package cn.iocoder.yudao.module.pms.service.iotryimprovedailyreport;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.framework.datapermission.core.util.DataPermissionUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.module.pms.constant.PmsConstants;
import cn.iocoder.yudao.module.pms.controller.admin.iotryimprovedailyreport.vo.IotRyImproveDailyReportPageReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotryimprovedailyreport.vo.IotRyImproveDailyReportSaveReqVO;
import cn.iocoder.yudao.module.pms.controller.admin.iotryimprovedailyreportdetail.vo.IotRyImproveDailyReportDetailSaveReqVO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotryimprovedailyreport.IotRyImproveDailyReportDO;
import cn.iocoder.yudao.module.pms.dal.dataobject.iotryimprovedailyreportdetail.IotRyImproveDailyReportDetailDO;
import cn.iocoder.yudao.module.pms.dal.mysql.iotryimprovedailyreport.IotRyImproveDailyReportMapper;
import cn.iocoder.yudao.module.pms.dal.mysql.iotryimprovedailyreportdetail.IotRyImproveDailyReportDetailMapper;
import cn.iocoder.yudao.module.pms.message.PmsMessage;
import cn.iocoder.yudao.module.supplier.enums.common.SupplierAuditStatusEnum;
import cn.iocoder.yudao.module.system.api.user.AdminUserApi;
import cn.iocoder.yudao.module.system.api.user.dto.AdminUserRespDTO;
import cn.iocoder.yudao.module.system.dal.dataobject.dept.DeptDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.RoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.permission.UserRoleDO;
import cn.iocoder.yudao.module.system.dal.dataobject.user.AdminUserDO;
import cn.iocoder.yudao.module.system.dal.mysql.permission.UserRoleMapper;
import cn.iocoder.yudao.module.system.service.dept.DeptService;
import cn.iocoder.yudao.module.system.service.permission.RoleService;
import cn.iocoder.yudao.module.system.service.user.AdminUserService;
import com.google.common.collect.ImmutableMap;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

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

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.pms.enums.ErrorCodeConstant.IOT_RY_IMPROVE_DAILY_REPORT_NOT_EXISTS;
import static cn.iocoder.yudao.module.pms.framework.config.MultiThreadConfiguration.PMS_THREAD_POOL_TASK_EXECUTOR;
import static cn.iocoder.yudao.module.system.enums.ErrorCodeConstants.DEPT_NOT_FOUND;

/**
 * 瑞鹰项目启动设备整改 Service 实现类
 *
 * @author ruiqi
 */
@Service
@Validated
public class IotRyImproveDailyReportServiceImpl implements IotRyImproveDailyReportService {

    @Resource
    private IotRyImproveDailyReportMapper iotRyImproveDailyReportMapper;
    @Resource
    private DeptService deptService;
    @Resource
    private AdminUserService adminUserService;
    @Resource
    private RoleService roleService;
    @Resource
    private UserRoleMapper userRoleMapper;
    @Resource
    private AdminUserApi adminUserApi;
    @Resource(name = PMS_THREAD_POOL_TASK_EXECUTOR)
    private ThreadPoolTaskExecutor pmsThreadPoolTaskExecutor;
    @Resource
    private PmsMessage pmsMessage;
    @Resource
    private IotRyImproveDailyReportDetailMapper iotRyImproveDailyReportDetailMapper;

    @Override
    public Long createIotRyImproveDailyReport(IotRyImproveDailyReportSaveReqVO createReqVO) {
        // 创建人为当前登录人
        Long loginUserDeptId = SecurityFrameworkUtils.getLoginUserDeptId();
        DeptDO dept = deptService.getDept(loginUserDeptId);
        if (ObjUtil.isEmpty(dept)) {
            throw exception(DEPT_NOT_FOUND);
        }
        // 插入
        IotRyImproveDailyReportDO iotRyImproveDailyReport = BeanUtils.toBean(createReqVO, IotRyImproveDailyReportDO.class);
        // 新增时 status = 1 填报完成 audit_status = 10审批中
        iotRyImproveDailyReport.setDeptId(dept.getId());
        iotRyImproveDailyReport.setStatus(1);
        iotRyImproveDailyReport.setAuditStatus(10);
        iotRyImproveDailyReport.setCreator(loginUserDeptId.toString());
        iotRyImproveDailyReportMapper.insert(iotRyImproveDailyReport);

        // 创建生产动态明细
        List<IotRyImproveDailyReportDetailSaveReqVO> details = createReqVO.getImproveReportDetails();
        if (CollUtil.isNotEmpty(details)) {
            List<IotRyImproveDailyReportDetailDO> tobeAddedReports = new ArrayList<>();
            details.forEach(detail -> {
                IotRyImproveDailyReportDetailDO tempDetail = BeanUtils.toBean(detail, IotRyImproveDailyReportDetailDO.class);
                tempDetail.setReportId(iotRyImproveDailyReport.getId());
                tobeAddedReports.add(tempDetail);
            });
            iotRyImproveDailyReportDetailMapper.insertBatch(tobeAddedReports);
        }

        // 查找当前登录人的上级项目部审批人 发送审批通知
        DataPermissionUtils.executeIgnore(() -> {
            // 伊拉克项目部公共账号 填报 在当前部门内部查找 具有 审批权限 ‘项目部日报审批RY’ ‘项目部日报审批RYXJ’ 的人员
            Set<Long> projectIds = new HashSet<>();
            projectIds.add(dept.getId());
            List<AdminUserDO> receivedMsgUsers = adminUserService.getUserListByDeptIds(projectIds);
            if (CollUtil.isNotEmpty(receivedMsgUsers)) {
                Set<Long> userIds = new HashSet<>();
                receivedMsgUsers.forEach(user -> {
                    userIds.add(user.getId());
                });
                RoleDO role = roleService.getRoleByCode("项目部日报审批RY");
                RoleDO xjRole = roleService.getRoleByCode("项目部日报审批RYXJ");
                if (ObjUtil.isNotEmpty(role) || ObjUtil.isNotEmpty(xjRole)) {
                    Set<Long> roleIds = new HashSet<>();
                    if (ObjUtil.isNotEmpty(role)) {
                        roleIds.add(role.getId());
                    }
                    if (ObjUtil.isNotEmpty(xjRole)) {
                        roleIds.add(xjRole.getId());
                    }
                    List<UserRoleDO> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
                    if (CollUtil.isNotEmpty(userRoles)) {
                        // 提取有审批角色的所有用户ID（去重+空值过滤）
                        Set<Long> roleUserIds = userRoles.stream()
                                .map(UserRoleDO::getUserId)
                                .filter(Objects::nonNull) // 过滤空userId
                                .collect(Collectors.toSet());
                        // 计算两个集合的交集，得到最终目标用户ID
                        Set<Long> targetUserIds = userIds.stream()
                                .filter(roleUserIds::contains)
                                .collect(Collectors.toSet());
                        if (CollUtil.isNotEmpty(targetUserIds)) {
                            Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(targetUserIds);
                            if (CollUtil.isNotEmpty(users)) {
                                String msgTitle = iotRyImproveDailyReport.getTitle();
                                CountDownLatch latch = new CountDownLatch(users.size());
                                String finalMsgTitle = msgTitle;
                                String constant = PmsConstants.RY_IMPROVE_DAILY_REPORT_APPROVAL;
                                users.forEach((userId, user) -> {
                                    pmsThreadPoolTaskExecutor.execute(() -> {
                                        try {
                                            String mobile = user.getMobile();
                                            // 没有手机号也可以发送站内信消息
                                            if (StrUtil.isNotBlank(finalMsgTitle)) {
                                                pmsMessage.sendMessage(iotRyImproveDailyReport.getId(), finalMsgTitle, constant,
                                                        userId, mobile);
                                            }
                                        } finally {
                                            latch.countDown();
                                        }
                                    });
                                });
                            }
                        }
                    }
                }
            }
        });
        // 返回
        return iotRyImproveDailyReport.getId();
    }

    @Override
    public void updateIotRyImproveDailyReport(IotRyImproveDailyReportSaveReqVO updateReqVO) {
        // 校验存在
        IotRyImproveDailyReportDO existReport = validateIotRyImproveDailyReportExists(updateReqVO.getId());
        DeptDO dept = deptService.getDept(existReport.getDeptId());
        if (ObjUtil.isEmpty(dept)) {
            throw exception(DEPT_NOT_FOUND);
        }
        // 更新
        IotRyImproveDailyReportDO updateObj = BeanUtils.toBean(updateReqVO, IotRyImproveDailyReportDO.class);
        if (!"Y".equals(updateReqVO.getModifyFlag())) {
            // 日报管理员修改日报 不修改状态 不审批
            // 提交 待审批
            updateObj.setStatus(1);
            updateObj.setAuditStatus(10);
        }
        iotRyImproveDailyReportMapper.updateById(updateObj);

        // 更新生成动态明细 先删除 再新增
        int count = iotRyImproveDailyReportDetailMapper.deleteByMap(ImmutableMap.of(
                "report_id", existReport.getId()
        ));
        List<IotRyImproveDailyReportDetailSaveReqVO> details = updateReqVO.getImproveReportDetails();
        if (CollUtil.isNotEmpty(details)) {
            List<IotRyImproveDailyReportDetailDO> tobeAddedReports = new ArrayList<>();
            details.forEach(detail -> {
                IotRyImproveDailyReportDetailDO tempDetail = BeanUtils.toBean(detail, IotRyImproveDailyReportDetailDO.class);
                tempDetail.setReportId(existReport.getId());
                tobeAddedReports.add(tempDetail);
            });
            iotRyImproveDailyReportDetailMapper.insertBatch(tobeAddedReports);
        }

        // 钉钉 站内信 提醒项目部人员审批
        // 查找当前登录人的上级项目部审批人 发送审批通知
        // 日报管理员修改日报 不修改状态 不审批
        if (!"Y".equals(updateReqVO.getModifyFlag())) {
            DataPermissionUtils.executeIgnore(() -> {
                // 伊拉克项目部公共账号 填报 在当前部门内部查找 具有 审批权限 ‘项目部日报审批RY’ ‘项目部日报审批RYXJ’ 的人员
                Set<Long> projectIds = new HashSet<>();
                projectIds.add(dept.getId());
                List<AdminUserDO> receivedMsgUsers = adminUserService.getUserListByDeptIds(projectIds);
                if (CollUtil.isNotEmpty(receivedMsgUsers)) {
                    Set<Long> userIds = new HashSet<>();
                    receivedMsgUsers.forEach(user -> {
                        userIds.add(user.getId());
                    });
                    RoleDO role = roleService.getRoleByCode("项目部日报审批RY");
                    RoleDO xjRole = roleService.getRoleByCode("项目部日报审批RYXJ");
                    if (ObjUtil.isNotEmpty(role) || ObjUtil.isNotEmpty(xjRole)) {
                        Set<Long> roleIds = new HashSet<>();
                        if (ObjUtil.isNotEmpty(role)) {
                            roleIds.add(role.getId());
                        }
                        if (ObjUtil.isNotEmpty(xjRole)) {
                            roleIds.add(xjRole.getId());
                        }
                        List<UserRoleDO> userRoles = userRoleMapper.selectListByRoleIds(roleIds);
                        if (CollUtil.isNotEmpty(userRoles)) {
                            // 提取有审批角色的所有用户ID（去重+空值过滤）
                            Set<Long> roleUserIds = userRoles.stream()
                                    .map(UserRoleDO::getUserId)
                                    .filter(Objects::nonNull) // 过滤空userId
                                    .collect(Collectors.toSet());
                            // 计算两个集合的交集，得到最终目标用户ID
                            Set<Long> targetUserIds = userIds.stream()
                                    .filter(roleUserIds::contains)
                                    .collect(Collectors.toSet());
                            if (CollUtil.isNotEmpty(targetUserIds)) {
                                Map<Long, AdminUserRespDTO> users = adminUserApi.getUserMap(targetUserIds);
                                if (CollUtil.isNotEmpty(users)) {
                                    String msgTitle = updateObj.getTitle();
                                    CountDownLatch latch = new CountDownLatch(users.size());
                                    String finalMsgTitle = msgTitle;
                                    String constant = PmsConstants.RY_IMPROVE_DAILY_REPORT_APPROVAL;
                                    users.forEach((userId, user) -> {
                                        pmsThreadPoolTaskExecutor.execute(() -> {
                                            try {
                                                String mobile = user.getMobile();
                                                // 没有手机号也可以发送站内信消息
                                                if (StrUtil.isNotBlank(finalMsgTitle)) {
                                                    pmsMessage.sendMessage(updateObj.getId(), finalMsgTitle, constant,
                                                            userId, mobile);
                                                }
                                            } finally {
                                                latch.countDown();
                                            }
                                        });
                                    });
                                }
                            }
                        }
                    }
                }
            });
        }
    }

    @Override
    public void deleteIotRyImproveDailyReport(Long id) {
        // 校验存在
        validateIotRyImproveDailyReportExists(id);
        // 删除
        iotRyImproveDailyReportMapper.deleteById(id);
    }

    private IotRyImproveDailyReportDO validateIotRyImproveDailyReportExists(Long id) {
        IotRyImproveDailyReportDO improveDailyReport = iotRyImproveDailyReportMapper.selectById(id);
        if (ObjUtil.isEmpty(improveDailyReport)) {
            throw exception(IOT_RY_IMPROVE_DAILY_REPORT_NOT_EXISTS);
        }
        return improveDailyReport;
    }

    @Override
    public IotRyImproveDailyReportDO getIotRyImproveDailyReport(Long id) {
        return iotRyImproveDailyReportMapper.selectById(id);
    }

    @Override
    public PageResult<IotRyImproveDailyReportDO> getIotRyImproveDailyReportPage(IotRyImproveDailyReportPageReqVO pageReqVO) {
        // 查询选择部门下面所有子部门
        Set<Long> ids = new HashSet<>();
        if (Objects.nonNull(pageReqVO.getDeptId())) {
            ids = deptService.getChildDeptIdListFromCache(pageReqVO.getDeptId());
            ids.add(pageReqVO.getDeptId());
            pageReqVO.setDeptIds(ids);
        }
        return iotRyImproveDailyReportMapper.selectPage(pageReqVO);
    }

    @Override
    public void approvalImproveDailyReport(IotRyImproveDailyReportSaveReqVO updateReqVO) {
        // 审核瑞恒日报
        // 如果审批拒绝 修改日报 填报状态 status = 0 填写中  审批状态 auditStatus = 30
        // 审批通过 设置 日报审批状态 auditStatus = 20
        IotRyImproveDailyReportDO dailyReport = validateIotRyImproveDailyReportExists(updateReqVO.getId());
        dailyReport.setAuditStatus(updateReqVO.getAuditStatus());
        dailyReport.setOpinion(updateReqVO.getOpinion());
        dailyReport.setConstructionBrief(updateReqVO.getConstructionBrief());
        if (SupplierAuditStatusEnum.REJECT.getStatus().equals(updateReqVO.getAuditStatus())) {
            dailyReport.setStatus(0);
            // 审批拒绝后需要向 日报填报人 发送消息提醒 驳回到日报创建人
            Long deptId = dailyReport.getDeptId();
            // 当前日报创建人
            String creator = dailyReport.getCreator();
            // 消息标题
            String msgTitle = dailyReport.getTitle();
            // 查询当前部门 deptId 部门下的人员
            Set<Long> deptIds = new HashSet<>();
            deptIds.add(deptId);
            List<AdminUserDO> users = adminUserService.getUserListByDeptIds(deptIds);
            AdminUserDO user = adminUserService.getUser(Long.valueOf(creator));
            if (ObjUtil.isNotEmpty(user)) {
                // AdminUserDO user = users.get(0);
                String mobile = user.getMobile();
                String finalMsgTitle = msgTitle;
                String constant = PmsConstants.RY_IMPROVE_DAILY_REPORT;

                // 没有手机号 可以发送站内信消息
                if (StrUtil.isNotBlank(finalMsgTitle) && StrUtil.isNotBlank(creator)) {
                    pmsThreadPoolTaskExecutor.execute(() -> {
                        pmsMessage.sendMessage(dailyReport.getId(), finalMsgTitle, constant, Long.valueOf(creator), mobile);
                    });
                }
            }
        }
        // 更新瑞鹰项目启动设备整改 日报 状态
        iotRyImproveDailyReportMapper.updateById(dailyReport);
    }

}