package com.njcn.rdms.module.system.controller.admin.user;

import com.njcn.rdms.framework.apilog.core.annotation.ApiAccessLog;
import com.njcn.rdms.framework.common.pojo.CommonResult;
import com.njcn.rdms.framework.common.util.object.BeanUtils;
import com.njcn.rdms.framework.excel.core.util.ExcelUtils;
import com.njcn.rdms.module.system.controller.admin.user.vo.user.UserSimpleRespVO;
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.MySubordinateTreeRespVO;
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationQueryReqVO;
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationRespVO;
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationSaveReqVO;
import com.njcn.rdms.module.system.controller.admin.user.vo.userManagementRelation.UserManagementRelationTreeRespVO;
import com.njcn.rdms.module.system.convert.user.UserConvert;
import com.njcn.rdms.module.system.dal.dataobject.dept.DeptDO;
import com.njcn.rdms.module.system.dal.dataobject.user.AdminUserDO;
import com.njcn.rdms.module.system.dal.dataobject.user.UserManagementRelationDO;
import com.njcn.rdms.module.system.service.dept.DeptService;
import com.njcn.rdms.module.system.service.user.AdminUserService;
import com.njcn.rdms.module.system.service.user.UserManagementRelationService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.Valid;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.Comparator;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static com.njcn.rdms.framework.apilog.core.enums.OperateTypeEnum.EXPORT;
import static com.njcn.rdms.framework.common.pojo.CommonResult.success;
import static com.njcn.rdms.framework.common.util.collection.CollectionUtils.convertList;

/**
 * 用户管理链路 Controller
 * 
 * 提供用户管理链路的管理接口，包括：
 * - 创建、更新、删除用户管理链路
 * - 查询用户管理链路列表和详情
 * - 获取用户管理链路树形结构
 * - 导出用户管理链路数据
 *
 * @author dklive
 */
@Tag(name = "管理后台 - 用户管理链路")
@RestController
@RequestMapping("/system/user-management-relation")
@Validated
public class UserManagementRelationController {

    @Resource
    private DeptService deptService;

    @Resource
    private UserManagementRelationService userManagementRelationService;

    @Resource
    private AdminUserService adminUserService;

    /**
     * 创建用户管理链路
     * 
     * 权限要求：system:user-management-relation:create
     *
     * @param createReqVO 创建请求VO
     * @return 关系记录主键ID
     */
    @PostMapping("/create")
    @Operation(summary = "创建用户管理链路")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:create')")
    public CommonResult<Long> createUserManagementRelation(@Valid @RequestBody UserManagementRelationSaveReqVO createReqVO) {
        Long id = userManagementRelationService.createRelation(createReqVO);
        return success(id);
    }

    /**
     * 修改用户管理链路
     * 
     * 权限要求：system:user-management-relation:update
     *
     * @param updateReqVO 更新请求VO
     * @return 操作结果
     */
    @PutMapping("/update")
    @Operation(summary = "修改用户管理链路")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:update')")
    public CommonResult<Boolean> updateUserManagementRelation(@Valid @RequestBody UserManagementRelationSaveReqVO updateReqVO) {
        userManagementRelationService.updateRelation(updateReqVO);
        return success(true);
    }

    /**
     * 删除用户管理链路
     * 
     * 根据主键ID删除单条用户管理链路记录
     * 权限要求：system:user-management-relation:delete
     *
     * @param id 关系记录主键ID
     * @return 操作结果
     */
    @DeleteMapping("/delete")
    @Operation(summary = "删除用户管理链路")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:delete')")
    public CommonResult<Boolean> deleteUserManagementRelation(@RequestParam("id") Long id) {
        userManagementRelationService.deleteRelation(id);
        return success(true);
    }

    /**
     * 批量删除用户管理链路
     * 
     * 根据主键ID列表批量删除用户管理链路记录
     * 权限要求：system:user-management-relation:delete
     *
     * @param ids 关系记录主键ID列表
     * @return 操作结果
     */
    @DeleteMapping("/delete-list")
    @Operation(summary = "批量删除用户管理链路")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:delete')")
    public CommonResult<Boolean> deleteUserManagementRelationList(@RequestParam("ids") List<Long> ids) {
        userManagementRelationService.deleteRelationList(ids);
        return success(true);
    }

    /**
     * 获得用户管理链路信息
     * 
     * 根据主键ID查询单条用户管理链路记录
     * 权限要求：system:user-management-relation:query
     *
     * @param id 关系记录主键ID
     * @return 用户管理链路详情
     */
    @GetMapping(value = "/get")
    @Operation(summary = "获得用户管理链路信息")
    @Parameter(name = "id", description = "关系编号", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<UserManagementRelationRespVO> getUserManagementRelation(@RequestParam("id") Long id) {
        UserManagementRelationDO relation = userManagementRelationService.getRelation(id);
        return success(BeanUtils.toBean(relation, UserManagementRelationRespVO.class));
    }

    /**
     * 获取用户管理链路列表
     * 
     * 根据查询条件查询用户管理链路记录列表
     * 权限要求：system:user-management-relation:query
     *
     * @param reqVO 查询条件VO
     * @return 用户管理链路列表
     */
    @GetMapping("/query")
    @Operation(summary = "获取用户管理链路列表")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<List<UserManagementRelationTreeRespVO>> getUserManagementRelationQuery(@Validated UserManagementRelationQueryReqVO reqVO) {
        List<UserManagementRelationTreeRespVO> list = userManagementRelationService.getRelationQuery(reqVO);
        return success(list);
    }

    /**
     * 获得某用户当前生效的直属上级
     *
     * @param userId 用户ID
     * @return 直属上级用户，不存在则返回 null
     */
    @GetMapping("/direct-manager")
    @Operation(summary = "获得某用户当前生效的直属上级")
    @Parameter(name = "userId", description = "用户ID", required = true, example = "1024")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<UserSimpleRespVO> getDirectManager(@RequestParam("userId") Long userId) {
        AdminUserDO manager = userManagementRelationService.getDirectManager(userId);
        if (manager == null) {
            return success(null);
        }
        List<Long> deptIds = manager.getDeptId() == null ? Collections.emptyList() : List.of(manager.getDeptId());
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(deptIds);
        return success(UserConvert.INSTANCE.convertSimpleList(List.of(manager), deptMap).get(0));
    }

    /**
     * 获取未绑定直属上级的候选下级用户列表
     * @return 候选下级用户列表
     */
    @GetMapping("/candidate-users")
    @Operation(summary = "获取未绑定直属上级的候选下级用户列表")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<List<UserSimpleRespVO>> getCandidateSubordinateUsers() {
        List<AdminUserDO> users = userManagementRelationService.getCandidateSubordinateUsers();
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(users, AdminUserDO::getDeptId));
        return success(UserConvert.INSTANCE.convertSimpleList(users, deptMap));
    }

    /**
     * 获取某用户当前生效的直属下级列表。
     *
     * 口径：只返回直接下级，不递归孙级；仅返回当前生效的管理链路。
     */
    @GetMapping("/direct-subordinates")
    @Operation(summary = "获取某用户当前生效的直属下级列表")
    @Parameter(name = "userId", description = "用户ID", required = true, example = "1024")
    //@PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<List<UserSimpleRespVO>> getDirectSubordinates(@RequestParam("userId") Long userId) {
        List<UserManagementRelationDO> relations = userManagementRelationService.getRelationListByManagerUserId(userId);
        if (relations.isEmpty()) {
            return success(Collections.emptyList());
        }
        LocalDateTime now = LocalDateTime.now();
        Set<Long> subordinateIds = new LinkedHashSet<>();
        relations.stream()
                .filter(relation -> relation.getSubordinateUserId() != null)
                .filter(relation -> relation.getEffectiveFrom() == null || !relation.getEffectiveFrom().isAfter(now))
                .filter(relation -> relation.getEffectiveUntil() == null || relation.getEffectiveUntil().isAfter(now))
                .map(UserManagementRelationDO::getSubordinateUserId)
                .forEach(subordinateIds::add);
        if (subordinateIds.isEmpty()) {
            return success(Collections.emptyList());
        }
        List<AdminUserDO> users = adminUserService.getUserList(subordinateIds).stream()
                .filter(adminUserService::isUserAvailable)
                .sorted(Comparator.comparing(AdminUserDO::getSort, Comparator.nullsLast(Integer::compareTo))
                        .thenComparing(AdminUserDO::getId, Comparator.nullsLast(Long::compareTo)))
                .toList();
        if (users.isEmpty()) {
            return success(Collections.emptyList());
        }
        Map<Long, DeptDO> deptMap = deptService.getDeptMap(convertList(users, AdminUserDO::getDeptId));
        List<UserSimpleRespVO> result = UserConvert.INSTANCE.convertSimpleList(users, deptMap).stream()
                .sorted(Comparator.comparing(UserSimpleRespVO::getSort, Comparator.nullsLast(Integer::compareTo))
                        .thenComparing(UserSimpleRespVO::getId, Comparator.nullsLast(Long::compareTo)))
                .toList();
        return success(result);
    }

    /**
     * 获取用户管理链路树形结构
     * 
     * 构建用户上下级关系的树形结构，用于前端树形控件展示
     * 树形结构特点：
     * - 根节点：最高领导，没有上级
     * - 中间节点：有上级也有下级
     * - 叶子节点：基层员工，没有下级
     * 
     * 权限要求：system:user-management-relation:query
     *
     * @return 用户管理链路树形列表
     */
    @GetMapping("/tree")
    @Operation(summary = "获取用户管理链路树形结构", description = "用于前端树形控件展示，包含用户的上下级层级关系")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:query')")
    public CommonResult<List<UserManagementRelationTreeRespVO>> getUserManagementRelationTree(@Validated UserManagementRelationQueryReqVO reqVO) {
        return success(userManagementRelationService.getRelationTree(reqVO));
    }

    @GetMapping("/my-subordinate-tree")
    @Operation(summary = "获取当前用户下属树")
    @PreAuthorize("@ss.hasPermission('project:work-report:team-dashboard')")
    public CommonResult<MySubordinateTreeRespVO> getMySubordinateTree() {
        return success(userManagementRelationService.getMySubordinateTree(null));
    }


    /**
     * 导出用户管理链路 Excel
     * 
     * 根据查询条件导出用户管理链路数据到Excel文件
     * 权限要求：system:user-management-relation:export
     *
     * @param response HTTP响应对象
     * @param reqVO 查询条件VO
     * @throws IOException IO异常
     */
    @GetMapping("/export-excel")
    @Operation(summary = "导出用户管理链路 Excel")
    @PreAuthorize("@ss.hasPermission('system:user-management-relation:export')")
    @ApiAccessLog(operateType = EXPORT)
    public void export(HttpServletResponse response, @Validated UserManagementRelationQueryReqVO reqVO) throws IOException {
        List<UserManagementRelationTreeRespVO> list = userManagementRelationService.getRelationQuery(reqVO);
        ExcelUtils.write(response, "用户管理链路数据.xls", "用户管理链路列表", UserManagementRelationRespVO.class,
                BeanUtils.toBean(list, UserManagementRelationRespVO.class));
    }

}
