package com.bonus.system.dept.service;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.bonus.common.core.utils.BuildTreeUtil;
import com.bonus.common.core.utils.StringUtils;
import com.bonus.common.core.web.domain.AjaxResult;
import com.bonus.common.security.utils.SecurityUtils;
import com.bonus.system.api.domain.MapVo;
import com.bonus.system.api.domain.SysUser;
import com.bonus.system.basic.domain.SysNotice;
import com.bonus.system.basic.domain.SysOrg;
import com.bonus.system.basic.service.SysNoticeService;
import com.bonus.system.dept.controller.SubOrgController;
import com.bonus.system.dept.dao.ProDeptRoleDao;
import com.bonus.system.dept.entity.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.interceptor.TransactionAspectSupport;

import javax.annotation.Resource;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 项目部角色-业务层
 *
 * @author fly
 */
@Service("ProDeptRoleService")
@Slf4j
public class ProDeptRoleServiceImpl implements ProDeptRoleService {

    @Resource(name = "ProDeptRoleDao")
    private ProDeptRoleDao proDeptRoleDao;

    /**
     * 消息推送库表
     */
    @Resource
    private SysNoticeService noticeService;

    @Override
    public List<ProDeptRoleBean> getRoleUserList(ProDeptRoleBean bean) {
        return proDeptRoleDao.getRoleUserList(bean);
    }

    public List<ProDeptRoleBean> getRoleUserNoManagerList(ProDeptRoleBean bean) {
        return proDeptRoleDao.getRoleUserNoManagerList(bean);
    }

    /**
     * 更新项目部角色人员
     *
     * @param bean 参数
     *             departmentId 项目部角色表id
     *             deptRoleId 项目部角色id
     *             userId 选择人员
     *             orgId 项目部id
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updatePersonAssignment(ProDeptRoleDo bean, String personStatus) {
        int result = 0;
        Long loginId = SecurityUtils.getLoginUser().getSysUser().getUserId();
        bean.setCreateUserId(loginId);
        bean.setUpdateUserId(loginId);
        //新增项目部角色表
        String userId = bean.getUserId();
        List<String> checkList = new ArrayList<>();
        if (!StringUtils.isEmpty(userId)) {
            checkList = Arrays.asList(userId.split(","));
        }
        List<String> delList = new ArrayList<>();
        List<String> addList;
        //角色表操作结果
        if (bean.getDepartmentId() == null) {
            //1.departmentId为空，第一次分配
            //新增sys_department_role
            //无人分配直接通过(项目处分配的需要根据项目部是否通过同步)
            bean.setReviewerStatus(personStatus);
            result = proDeptRoleDao.insertDeptRole(bean);
            addList = checkList;
        } else {
            //2.departmentId不为空，非第一次分配
            //修改sys_department_role
            //有人分配审核
            bean.setReviewerStatus("0");
            result = proDeptRoleDao.updateDeptRole(bean);
            List<String> oldCheckList = proDeptRoleDao.getRoleUserById(bean.getDepartmentId());
            Map<String, List<String>> stringListMap = compareLists(oldCheckList, checkList);
            delList = stringListMap.get("onlyInList1");
            addList = stringListMap.get("onlyInList2");
            if (result > 0) {
                //获取部门负责人
                List<Long> userList = noticeService.getUserIdByOrgId(bean.getOrgId());
                // 将 List 转换为数组
                if (!userList.isEmpty()) {
                    Long[] userIds = userList.toArray(new Long[0]);
                    //发送审批消息
                    SysNotice notice = new SysNotice();
                    notice.setUserIds(userIds);
                    notice.setUserId(loginId);
                    notice.setTitle("项目部角色人员变更");
                    notice.setContent("项目部角色人员变更");
                    notice.setType("69");
                    notice.setValue("");
                    //推送消息
                    noticeService.insertNotice(notice);
                }
            }
        }
        if (result > 0) {
            if (!delList.isEmpty()) {
                bean.setUserIds(delList);
                proDeptRoleDao.deletePersonAssignment(bean);
            }
            if (!addList.isEmpty()) {
                Long departmentId = bean.getDepartmentId();
                List<ProDeptRoleDo> addDataList = new ArrayList<>();
                for (String s : addList) {
                    ProDeptRoleDo o = new ProDeptRoleDo();
                    o.setDepartmentId(departmentId);
                    o.setUserId(s);
                    addDataList.add(o);
                }
                proDeptRoleDao.insertPersonAssignment(addDataList);
            }
        }
        return result;
    }

    /**
     * 更新项目部角色人员
     *
     * @param bean 参数
     *             departmentId 项目部角色表id
     *             reviewerStatus 审核状态
     * @return
     */
    @Override
    public int checkPersonAssignment(ProDeptRoleDo bean) {
        Long loginId = SecurityUtils.getLoginUser().getSysUser().getUserId();
        bean.setReviewerUserId(loginId);
        bean.setReviewerTime(DateUtil.date());
        return proDeptRoleDao.checkPersonAssignment(bean);
    }

    @Override
    public AjaxResult batchRoleCheck(ProDeptRoleDo bean) {
        try {
            if(CollectionUtils.isEmpty(bean.getIds())){
                return AjaxResult.error("未选择审批数据");
            }
            if(StringUtils.isEmpty(bean.getReviewerStatus())){
                return AjaxResult.error("未选择审批状态");
            }
            long loginId = SecurityUtils.getLoginUser().getSysUser().getUserId();
            bean.setReviewerUserId(loginId);
            bean.setReviewerTime(DateUtil.date());
            proDeptRoleDao.batchRoleCheck(bean);
        } catch (Exception e) {
            log.error(e.toString(),e);
            TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
            return AjaxResult.error();
        }
        return AjaxResult.success();
    }

    @Override
    public JSONArray selectOrgUserList(ProDeptRoleBean bean) {
        JSONArray resultTree;
        try {
            //查出组织人员
            List<OrgUserVo> listOrg = proDeptRoleDao.selectOrgUserList(bean);
            // 人员只能在一个项目部任职，上四级岗位不能兼任
            //1.1当前分配的是否是上四级岗位 (上四级岗位id 分别为 1,2,3,4（固定）)
            //1.2查询在其他组织任职的所有人员，设置不可选中
            //1.3如果分配的是上四级岗位，查询同一项目部其他三个上级岗位,将这些人员设置为不可选中
            List<String> userIds = proDeptRoleDao.getUserByOtherRoleAndOrg(bean);
            // 比较并修改 listOrg 的值,置为不可选中
            List<OrgUserVo> toRemove = new ArrayList<>();
            for (OrgUserVo orgUser : listOrg) {
                if (orgUser == null) {
                    continue; // 防止空指针异常
                }
                String id = orgUser.getId();
                if (id == null) {
                    continue; // 防止空指针异常
                }
                if (userIds.contains(id)) {
                    toRemove.add(orgUser);
                }
            }
            // 统一删除
            listOrg.removeAll(toRemove);
            if (bean.getDeptRoleId() <= 4) {
                // 创建一个可变列表
                List<Long> roleIds = new ArrayList<>(Arrays.asList(1L, 2L, 3L, 4L));
                // 检查 null 值
                Long deptRoleId = bean.getDeptRoleId();
                if (deptRoleId != null) {
                    roleIds.remove(deptRoleId);
                }
                List<String> userIdTwos = proDeptRoleDao.getUserByRoleAndOrg(bean, roleIds);
//                userIds.addAll(userIdTwos);
                for (OrgUserVo orgUser : listOrg) {
                    if (orgUser == null) {
                        continue; // 防止空指针异常
                    }
                    String id = orgUser.getId();
                    if (id == null) {
                        continue; // 防止空指针异常
                    }
                    if (userIdTwos.contains(id)) {
                        orgUser.setDisabled(true);
                    }
                }
            }
            //构建treeTable
            resultTree = BuildTreeUtil.listInfoToTree(JSONArray.parseArray(JSON.toJSONString(listOrg)), "id", "parentId", "children");
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return resultTree;
    }

    /**
     * 查询项目部八大员情况
     *
     * @param bean
     * @return
     */
    @Override
    public List<EightRoleBean> getOrgEightRoleList(EightRoleBean bean) {
        return proDeptRoleDao.getOrgEightRoleList(bean);
    }

    @Override
    public List<EightRoleVo> getOrgEightRoleDetail(EightRoleBean bean) {
        String lackOrgId = bean.getLackOrgId();
        String moreOrgId = bean.getMoreOrgId();
        List<String> orgList = new ArrayList<>();
        if (StringUtils.isNotEmpty(lackOrgId)) {
            orgList = Arrays.asList(lackOrgId.split(","));
        } else if (StringUtils.isNotEmpty(moreOrgId)) {
            orgList = Arrays.asList(moreOrgId.split(","));
        }
        //这一块要组装数据，需要先处理分页，让框架自动分页
        List<String> list = proDeptRoleDao.getOrgEightRoleDetail(orgList, bean.getParentOrgName());
        //再去查真实数据处理
        List<ProDeptRoleBean> resultList = new ArrayList<>();
        if (!list.isEmpty()) {
            resultList = proDeptRoleDao.getDataDetail(list);
        }
        return rowSwitch(resultList);
    }

    @Override
    public List<ProDeptRoleBean> getMoreOrgData(ProDeptRoleBean bean) {
        List<ProDeptRoleBean> moreOrgData = proDeptRoleDao.getMoreOrgData(bean);
        if (!moreOrgData.isEmpty()) {
            moreOrgData = proDeptRoleDao.getMoreOrgDataByUserName(bean, moreOrgData);
        }
        return moreOrgData;
    }

    @Override
    public ProDeptRoleBean getInfoById(ProDeptRoleBean o) {
        return proDeptRoleDao.getInfoById(o);
    }

    /**
     * 列转行
     *
     * @param resultList
     * @return
     */
    private List<EightRoleVo> rowSwitch(List<ProDeptRoleBean> resultList) {
        //1.0先处理兼职和缺员
        // 按 orgId 分组
        Map<Long, List<ProDeptRoleBean>> groupedByOrgId = resultList.stream()
                .collect(Collectors.groupingBy(ProDeptRoleBean::getOrgId));
        // 处理每个分组
        for (Map.Entry<Long, List<ProDeptRoleBean>> entry : groupedByOrgId.entrySet()) {
            List<ProDeptRoleBean> group = entry.getValue();
            // 创建 List<String> 用于存储用户名称
            List<String> listUserName = new ArrayList<>();
            // 检查用户名字并进行相应处理
            for (ProDeptRoleBean bean : group) {
                String userName = bean.getUserName();
                // 处理数据
                if (StringUtils.isEmpty(userName)) {
                    // 如果存在 null 用户名，添加缺员角色
                    bean.setUserName("缺员");
                } else {
                    //将人名称添加到集合中
                    // 如果有非 null 的用户名，并且存在相同字段
                    String[] split = userName.split(",");
                    // 使用 Collections.addAll() 将数组添加到列表
                    Collections.addAll(listUserName, split);
                }
            }
            // 使用 Map 统计每个元素的出现次数
            Map<String, Integer> countMap = new HashMap<>();
            for (String user : listUserName) {
                countMap.put(user, countMap.getOrDefault(user, 0) + 1);
            }
            // 创建一个新的 List 存放重复的用户名称
            List<String> duplicates = new ArrayList<>();
            for (Map.Entry<String, Integer> entryMap : countMap.entrySet()) {
                if (entryMap.getValue() > 1) {
                    duplicates.add(entryMap.getKey());
                }
            }
            //将名字与重复集合比较，包含重复元素的将其改为"兼职"
            for (String duplicate : duplicates) {
                for (ProDeptRoleBean bean : group) {
                    if (bean.getUserName().contains(duplicate)) {
                        bean.setUserName("兼职");
                    }
                }
            }
        }

        //2.列转行   用于存储 EightRoleVo 对象的 List
        List<EightRoleVo> rolesList = new ArrayList<>();
        for (ProDeptRoleBean bean : resultList) {
            // 转换数据并分组
            Long orgId = bean.getOrgId();  // 部门 ID
            String orgName = bean.getOrgName();  // 部门名称
            String roleName = bean.getDeptRoleName();  // 角色名称
            String userName = bean.getUserName();
            // 创建或查找对应的 EightRoleVo 对象
            EightRoleVo roles = findOrCreateRole(rolesList, orgId, orgName);
            switch (roleName) {
                case "项目经理":
                    roles.setProjectManager(userName);
                    break;
                case "安全员":
                    roles.setSafetyOfficer(userName);
                    break;
                case "质检员":
                    roles.setQualityInspector(userName);
                    break;
                case "项目总工":
                    roles.setChiefEngineer(userName);
                    break;
                case "机械员":
                    roles.setMechanicalStaff(userName);
                    break;
                case "资料员":
                    roles.setDocumentStaff(userName);
                    break;
                case "施工员":
                    roles.setConstructionStaff(userName);
                    break;
                case "材料员":
                    roles.setMaterialStaff(userName);
                    break;
                case "其他":
                    roles.setOther(userName);
                    break;
            }
        }
        return rolesList;
    }

    // 辅助方法：查找或创建对应的 EightRoleVo 对象
    private static EightRoleVo findOrCreateRole(List<EightRoleVo> rolesList, Long orgId, String orgName) {
        for (EightRoleVo role : rolesList) {
            if (role.getOrgId().equals(orgId)) {
                return role;  // 找到已存在的角色
            }
        }
        // 如果未找到，则创建新的角色对象并添加到列表
        EightRoleVo newRole = new EightRoleVo();
        newRole.setOrgId(orgId);
        newRole.setOrgName(orgName);
        rolesList.add(newRole);
        return newRole;
    }

    public Map<String, List<String>> compareLists(List<String> list1, List<String> list2) {
        // 使用集合来找出相同和不同的值
        Set<String> set1 = new HashSet<>(list1);
        Set<String> set2 = new HashSet<>(list2);
        // 创建一个结果 map
        Map<String, List<String>> resultMap = new HashMap<>();
        // 找出相同的值（交集）
        Set<String> common = new HashSet<>(set1);
        common.retainAll(set2);
        // 找出不同的值（差集）
        Set<String> onlyInList1 = new HashSet<>(set1);
        onlyInList1.removeAll(set2);
        Set<String> onlyInList2 = new HashSet<>(set2);
        onlyInList2.removeAll(set1);
        // 将结果存入 map
        resultMap.put("common", new ArrayList<>(common));
        resultMap.put("onlyInList1", new ArrayList<>(onlyInList1));
        resultMap.put("onlyInList2", new ArrayList<>(onlyInList2));
        return resultMap;
    }
}
