package com.usky.system.controller.web;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.usky.common.core.exception.BusinessException;
import com.usky.common.core.bean.ApiResult;
import com.usky.system.controller.web.page.TableDataInfo;
import com.usky.common.security.utils.SecurityUtils;
import com.usky.system.domain.SysPerson;
import com.usky.system.domain.SysUser;
import com.usky.system.domain.SysUserPerson;
import com.usky.system.service.ISysUserService;
import com.usky.system.service.SysPersonService;
import com.usky.system.service.SysUserPersonService;
import com.usky.common.core.util.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.BeanUtils;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 人员信息 前端控制器
 * </p>
 *
 * @author JCB
 * @since 2022-08-22
 */
@RestController
@RequestMapping("/sysPerson")
public class SysPersonController extends BaseController {

    @Autowired
    private SysPersonService sysPersonService;
    @Autowired
    private SysUserPersonService sysUserPersonService;
    @Autowired
    private ISysUserService sysUserService;

    /**
     * 人员列表（分页）
     */
    @GetMapping("/list")
    public ApiResult<TableDataInfo> list(SysPerson person) {
        startPage();
        // 支持 fullName 模糊查询；其他字段保持按传入条件精确匹配
        Long filterDeptId = person != null ? person.getDeptId() : null;
        Long filterUserId = person != null ? person.getUserId() : null;

        SysPerson queryEntity = new SysPerson();
        if (person != null) {
            BeanUtils.copyProperties(person, queryEntity);
            // fullName 用 like 查询，避免 Wrappers.query(entity) 产生 fullName=xxx 的精确条件
            queryEntity.setFullName(null);
            // 部门、岗位、用户以关联表为准，不作为人员表列条件
            queryEntity.setDeptId(null);
            queryEntity.setPostId(null);
            queryEntity.setUserId(null);
        }
        QueryWrapper<SysPerson> queryWrapper = Wrappers.query(queryEntity);
        queryWrapper.lambda()
                .like(person != null && StringUtils.isNotBlank(person.getFullName()),
                        SysPerson::getFullName, person.getFullName());

        // 按 userId 筛选：通过用户-人员关联表
        if (filterUserId != null) {
            List<SysUserPerson> userRelations = sysUserPersonService.list(
                    Wrappers.<SysUserPerson>lambdaQuery()
                            .eq(SysUserPerson::getUserId, filterUserId)
            );
            List<Integer> userPersonIds = userRelations == null ? null : userRelations.stream()
                    .map(SysUserPerson::getPersonId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (userPersonIds == null || userPersonIds.isEmpty()) {
                // 避免 MyBatis-Plus 生成 id IN () 语法错误
                queryWrapper.apply("1 = 0");
            } else {
                queryWrapper.lambda().in(SysPerson::getId, userPersonIds);
            }
        }

        // 按部门筛选：关联用户的 dept_id = filterDeptId
        if (filterDeptId != null) {
            LambdaQueryWrapper<SysUser> userQuery = Wrappers.<SysUser>lambdaQuery()
                    .eq(SysUser::getDeptId, filterDeptId)
                    .eq(SysUser::getDelFlag, "0");
            Integer tenantId = SecurityUtils.getTenantId();
            if (tenantId != null) {
                userQuery.eq(SysUser::getTenantId, tenantId);
            }
            List<SysUser> deptUsers = sysUserService.list(userQuery);
            List<Long> userIds = deptUsers == null ? null : deptUsers.stream()
                    .map(SysUser::getUserId)
                    .filter(Objects::nonNull)
                    .distinct()
                    .collect(Collectors.toList());
            if (userIds == null || userIds.isEmpty()) {
                queryWrapper.apply("1 = 0");
            } else {
                List<SysUserPerson> deptRelations = sysUserPersonService.list(
                        Wrappers.<SysUserPerson>lambdaQuery()
                                .in(SysUserPerson::getUserId, userIds)
                );
                List<Integer> deptPersonIds = deptRelations == null ? null : deptRelations.stream()
                        .map(SysUserPerson::getPersonId)
                        .filter(Objects::nonNull)
                        .distinct()
                        .collect(Collectors.toList());
                if (deptPersonIds == null || deptPersonIds.isEmpty()) {
                    queryWrapper.apply("1 = 0");
                } else {
                    queryWrapper.lambda().in(SysPerson::getId, deptPersonIds);
                }
            }
        }

        List<SysPerson> list = sysPersonService.list(queryWrapper);

        // 回显 userId，以及通过 userId 回显部门、岗位
        if (list != null && !list.isEmpty()) {
            List<Integer> personIds = list.stream()
                    .map(SysPerson::getId)
                    .filter(Objects::nonNull)
                    .collect(Collectors.toList());
            if (!personIds.isEmpty()) {
                List<SysUserPerson> relations = sysUserPersonService.list(
                        Wrappers.<SysUserPerson>lambdaQuery()
                                .in(SysUserPerson::getPersonId, personIds)
                );
                final Map<Integer, Long> personUserMap;
                if (relations != null && !relations.isEmpty()) {
                    personUserMap = relations.stream()
                            .collect(Collectors.toMap(
                                    SysUserPerson::getPersonId,
                                    SysUserPerson::getUserId,
                                    (u1, u2) -> u1
                            ));
                    list.forEach(p -> {
                        Long userId = personUserMap.get(p.getId());
                        if (userId != null) {
                            p.setUserId(userId);
                        }
                    });
                } else {
                    personUserMap = new HashMap<>();
                }
                sysPersonService.fillDeptAndPostForList(list, personUserMap);
            }
        }
        return ApiResult.success(getDataTable(list));
    }

    /**
     * 根据主键获取人员详情
     */
    @GetMapping("/{id}")
    public ApiResult<SysPerson> getInfo(@PathVariable("id") Integer id) {
        SysPerson person = sysPersonService.getById(id);
        if (person != null) {
            Long userId = null;
            SysUserPerson userPerson = sysUserPersonService.getOne(
                    Wrappers.<SysUserPerson>lambdaQuery()
                            .eq(SysUserPerson::getPersonId, id)
                            .last("limit 1")
            );
            if (userPerson != null) {
                userId = userPerson.getUserId();
                person.setUserId(userId);
            }
            sysPersonService.fillDeptAndPostFromUser(person, userId);
        }
        return ApiResult.success(person);
    }

    /**
     * 新增人员并绑定用户
     */
    @PostMapping
    @Transactional
    public ApiResult<Void> add(@RequestBody SysPerson person) {
        Long userId = person.getUserId();
        if (Objects.isNull(userId)) {
            throw new BusinessException("lack necessary param:userId is required!");
        }
        // 校验账户是否已被其他人员绑定
        SysUserPerson existBind = sysUserPersonService.getOne(
                Wrappers.<SysUserPerson>lambdaQuery()
                        .eq(SysUserPerson::getUserId, userId)
                        .last("limit 1")
        );
        if (existBind != null) {
            throw new BusinessException("此账户已被其它人员绑定，请解绑后重试！");
        }
        // 先保存人员信息
        sysPersonService.save(person);
        // 新增用户-人员关联
        SysUserPerson userPerson = new SysUserPerson();
        userPerson.setUserId(userId);
        userPerson.setPersonId(person.getId());
        userPerson.setIsLoginNotify(0);
        sysUserPersonService.save(userPerson);
        return ApiResult.success();
    }

    /**
     * 修改人员并更新绑定用户
     */
    @PutMapping
    @Transactional
    public ApiResult<Void> edit(@RequestBody SysPerson person) {
        Long userId = person.getUserId();
        if (Objects.isNull(userId)) {
            throw new BusinessException("lack necessary param:userId is required!");
        }
        // 校验账户是否已被其他人员绑定（排除当前人员本身）
        SysUserPerson existBind = sysUserPersonService.getOne(
                Wrappers.<SysUserPerson>lambdaQuery()
                        .eq(SysUserPerson::getUserId, userId)
                        .last("limit 1")
        );
        if (existBind != null && !Objects.equals(existBind.getPersonId(), person.getId())) {
            throw new BusinessException("此账户已被其它人员绑定，请解绑后重试！");
        }
        // 更新人员信息
        sysPersonService.updateById(person);
        // 先删除原有关联，再按当前传入的 userId 重新绑定
        QueryWrapper<SysUserPerson> wrapper = Wrappers.query();
        wrapper.eq("person_id", person.getId());
        sysUserPersonService.remove(wrapper);

        SysUserPerson userPerson = new SysUserPerson();
        userPerson.setUserId(userId);
        userPerson.setPersonId(person.getId());
        userPerson.setIsLoginNotify(0);
        sysUserPersonService.save(userPerson);
        return ApiResult.success();
    }

    /**
     * 删除人员（支持批量，逗号分隔），并解绑与用户的关联
     */
    @DeleteMapping("/{ids}")
    public ApiResult<Void> remove(@PathVariable("ids") Integer[] ids) {
        // 先删除关联关系
        QueryWrapper<SysUserPerson> wrapper = Wrappers.query();
        wrapper.in("person_id", Arrays.asList(ids));
        sysUserPersonService.remove(wrapper);
        // 再删除人员
        sysPersonService.removeByIds(Arrays.asList(ids));
        return ApiResult.success();
    }
}

