package com.lesingle.edu.controller.school;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.lesingle.edu.common.annotation.Log;
import com.lesingle.edu.common.enums.LogModule;
import com.lesingle.edu.common.enums.LogOperationType;
import com.lesingle.edu.common.mapper.ParentMapper;
import com.lesingle.edu.mapper.ParentStudentMapper;
import com.lesingle.edu.common.response.PageResult;
import com.lesingle.edu.common.response.Result;
import com.lesingle.edu.common.security.SecurityUtils;
import com.lesingle.edu.dto.request.ParentCreateRequest;
import com.lesingle.edu.dto.request.ParentUpdateRequest;
import com.lesingle.edu.dto.response.ChildInfoResponse;
import com.lesingle.edu.dto.response.ParentResponse;
import com.lesingle.edu.dto.response.ParentStudentResponse;
import com.lesingle.edu.entity.Parent;
import com.lesingle.edu.entity.ParentStudent;
import com.lesingle.edu.service.ParentChildService;
import com.lesingle.edu.service.ParentService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@Tag(name = "School - Parent", description = "Parent Management APIs for School")
@RestController
@RequestMapping("/api/v1/school/parents")
@RequiredArgsConstructor
public class SchoolParentController {

    private final ParentService parentService;
    private final ParentChildService parentChildService;
    private final ParentMapper parentMapper;
    private final ParentStudentMapper parentStudentMapper;

    @Operation(summary = "Create parent")
    @Log(module = LogModule.PARENT, type = LogOperationType.CREATE, description = "创建新家长")
    @PostMapping
    public Result<ParentResponse> createParent(@Valid @RequestBody ParentCreateRequest request) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Parent parent = parentService.createParent(tenantId, request);
        return Result.success(parentMapper.toVO(parent));
    }

    @Operation(summary = "Update parent")
    @Log(module = LogModule.PARENT, type = LogOperationType.UPDATE, description = "修改家长信息")
    @PutMapping("/{id}")
    public Result<ParentResponse> updateParent(@PathVariable Long id, @RequestBody ParentUpdateRequest request) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Parent parent = parentService.updateParentWithTenantCheck(id, tenantId, request);
        return Result.success(parentMapper.toVO(parent));
    }

    @Operation(summary = "Get parent by ID")
    @GetMapping("/{id}")
    public Result<ParentResponse> getParent(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Parent parent = parentService.getParentByIdWithTenantCheck(id, tenantId);
        return Result.success(parentMapper.toVO(parent));
    }

    @Operation(summary = "Get parent page")
    @GetMapping
    public Result<PageResult<ParentResponse>> getParentPage(
            @RequestParam(required = false, defaultValue = "1") Integer pageNum,
            @RequestParam(required = false, defaultValue = "10") Integer pageSize,
            @RequestParam(required = false) String keyword,
            @RequestParam(required = false) String status) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        Page<Parent> page = parentService.getParentPage(tenantId, pageNum, pageSize, keyword, status);
        List<ParentResponse> voList = parentMapper.toVO(page.getRecords());
        for (ParentResponse vo : voList) {
            long count = parentStudentMapper.selectCount(
                    new LambdaQueryWrapper<ParentStudent>()
                            .eq(ParentStudent::getParentId, vo.getId()));
            vo.setChildrenCount((int) count);
        }
        return Result.success(PageResult.of(voList, page.getTotal(), page.getCurrent(), page.getSize()));
    }

    @Operation(summary = "Delete parent")
    @Log(module = LogModule.PARENT, type = LogOperationType.DELETE, description = "删除家长")
    @DeleteMapping("/{id}")
    public Result<Void> deleteParent(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        parentService.deleteParentWithTenantCheck(id, tenantId);
        return Result.success();
    }

    @Operation(summary = "Reset parent password")
    @Log(module = LogModule.PARENT, type = LogOperationType.UPDATE, description = "重置家长密码")
    @PostMapping("/{id}/reset-password")
    public Result<java.util.Map<String, String>> resetPassword(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        String tempPassword = parentService.resetPasswordAndReturnTemp(id, tenantId);
        return Result.success(java.util.Map.of("tempPassword", tempPassword));
    }

    @Operation(summary = "Bind student to parent")
    @Log(module = LogModule.PARENT, type = LogOperationType.CREATE, description = "绑定学生到家长")
    @PostMapping("/{parentId}/students/{studentId}")
    public Result<Void> bindStudent(
            @PathVariable Long parentId,
            @PathVariable Long studentId,
            @RequestParam(required = false) String relationship,
            @RequestParam(required = false) Boolean isPrimary) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        parentService.bindStudentWithTenantCheck(parentId, studentId, tenantId, relationship, isPrimary);
        return Result.success();
    }

    @Operation(summary = "Add child to parent (alias for bind student)")
    @Log(module = LogModule.PARENT, type = LogOperationType.CREATE, description = "添加孩子到家长")
    @PostMapping("/{parentId}/children/{studentId}")
    public Result<Void> addChild(
            @PathVariable Long parentId,
            @PathVariable Long studentId,
            @RequestBody(required = false) java.util.Map<String, Object> body) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        String relationship = null;
        Boolean isPrimary = null;
        if (body != null) {
            if (body.containsKey("relationship")) {
                Object v = body.get("relationship");
                relationship = v != null ? v.toString() : null;
            }
            if (body.containsKey("isPrimary")) {
                Object v = body.get("isPrimary");
                isPrimary = v instanceof Boolean ? (Boolean) v : (v != null && Boolean.parseBoolean(v.toString()));
            }
        }
        parentService.bindStudentWithTenantCheck(parentId, studentId, tenantId, relationship, isPrimary);
        return Result.success();
    }

    @Operation(summary = "Unbind student from parent")
    @Log(module = LogModule.PARENT, type = LogOperationType.DELETE, description = "从家长解绑学生")
    @DeleteMapping("/{parentId}/students/{studentId}")
    public Result<Void> unbindStudent(@PathVariable Long parentId, @PathVariable Long studentId) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        parentService.unbindStudentWithTenantCheck(parentId, studentId, tenantId);
        return Result.success();
    }

    @Operation(summary = "Remove child from parent (alias for unbind student)")
    @Log(module = LogModule.PARENT, type = LogOperationType.DELETE, description = "从家长移除孩子")
    @DeleteMapping("/{parentId}/children/{studentId}")
    public Result<Void> removeChild(@PathVariable Long parentId, @PathVariable Long studentId) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        parentService.unbindStudentWithTenantCheck(parentId, studentId, tenantId);
        return Result.success();
    }

    @Operation(summary = "Get children of parent")
    @GetMapping("/{id}/children")
    public Result<List<ChildInfoResponse>> getParentChildren(@PathVariable Long id) {
        Long tenantId = SecurityUtils.getCurrentTenantId();
        parentService.getParentByIdWithTenantCheck(id, tenantId);
        List<ChildInfoResponse> children = parentChildService.getChildrenForParent(id);
        return Result.success(children);
    }

}
