package com.srs.routine.service.impl;

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

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.core.domain.entity.SysUser;
import com.srs.common.doman.dto.ProcessResultDto;
import com.srs.common.exception.ServiceException;
import com.srs.common.utils.DateUtils;
import com.srs.common.utils.SecurityUtils;
import com.srs.common.utils.StringUtils;
import com.srs.common.utils.WeChatUtil;
import com.srs.flowable.service.IFlowDefinitionService;
import com.srs.routine.domain.RtStuDisciplinaryApplication;
import com.srs.routine.domain.RtStuDisciplinaryRelieve;
import com.srs.routine.mapper.RtStuDisciplinaryApplicationMapper;
import com.srs.routine.mapper.RtStuDisciplinaryRelieveMapper;
import com.srs.routine.service.IRtStuDisciplinaryRelieveService;
import com.srs.system.mapper.SysUserMapper;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.IdentityService;
import org.flowable.engine.TaskService;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

/**
 * 学生解除处分申请 Service 业务层处理
 *
 * @author LSD
 * @date 2024-04-29
 */
@Service
@Slf4j
public class RtStuDisciplinaryRelieveServiceImpl extends ServiceImpl<RtStuDisciplinaryRelieveMapper, RtStuDisciplinaryRelieve> implements IRtStuDisciplinaryRelieveService {
    @Autowired
    private RtStuDisciplinaryRelieveMapper rtStuDisciplinaryRelieveMapper;

    @Autowired
    RtStuDisciplinaryApplicationMapper rtStuDisciplinaryApplicationMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    public WeChatUtil weChatUtil;

    /**
     * 查询学生解除处分申请
     *
     * @param relieveId 学生解除处分申请主键
     * @return 学生解除处分申请
     */
    @Override
    public RtStuDisciplinaryRelieve selectRtStuDisciplinaryRelieveByRelieveId(Long relieveId) {
        return rtStuDisciplinaryRelieveMapper.selectRtStuDisciplinaryRelieveByRelieveId(relieveId);
    }

    /**
     * 查询学生解除处分申请列表
     *
     * @param rtStuDisciplinaryRelieve 学生解除处分申请
     * @return 学生解除处分申请
     */
    @Override
    public List<RtStuDisciplinaryRelieve> selectRtStuDisciplinaryRelieveList(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        rtStuDisciplinaryRelieve.setSubmissionStatus(1L);
        return rtStuDisciplinaryRelieveMapper.selectRtStuDisciplinaryRelieveList(rtStuDisciplinaryRelieve);
    }


    @Override
    public List<RtStuDisciplinaryRelieve> getRtStuDisciplinaryRelieveListByStuNo(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        rtStuDisciplinaryRelieve.setStuNo(SecurityUtils.getUsername());
        return rtStuDisciplinaryRelieveMapper.selectRtStuDisciplinaryRelieveList(rtStuDisciplinaryRelieve);
    }

    @Override
    public List<RtStuDisciplinaryRelieve> getRtStuDisciplinaryRelieveListByTeacherNo(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        HashMap<String, Object> hashMap = new HashMap<>();
        hashMap.put("employeeId", SecurityUtils.getUsername());
        rtStuDisciplinaryRelieve.setParams(hashMap);
        return rtStuDisciplinaryRelieveMapper.selectRtStuDisciplinaryRelieveListByTeacherNo(rtStuDisciplinaryRelieve);
    }

    @Override
    public List<RtStuDisciplinaryRelieve> selectRtStuDisciplinaryRelieveListByXW(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        return rtStuDisciplinaryRelieveMapper.selectRtStuDisciplinaryRelieveListXW(rtStuDisciplinaryRelieve);
    }

    /**
     * 新增学生解除处分申请
     *
     * @param rtStuDisciplinaryRelieve 学生解除处分申请
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int insertRtStuDisciplinaryRelieve(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {

        // todo 暂时注释 判断，该 处分文号，是否已存在解除处分表
//        RtStuDisciplinaryApplication application = new RtStuDisciplinaryApplication();
//
//        application.setPenaltyNumber(rtStuDisciplinaryRelieve.getPenaltyNumber());
//
//        List<RtStuDisciplinaryApplication> rtStuDisciplinaryApplications = rtStuDisciplinaryApplicationMapper.selectRtStuDisciplinaryApplicationList(application);
//
//        if (rtStuDisciplinaryApplications.size() > 0) {
//            throw new ServiceException("请忽重复提交该处分文号的解除处分申请", 500);
//        }

        rtStuDisciplinaryRelieve.setCreateTime(DateUtils.getNowDate());

        rtStuDisciplinaryRelieve.setCreateBy(SecurityUtils.getUsername());

        rtStuDisciplinaryRelieve.setStuId(SecurityUtils.getUserId());

        int i = rtStuDisciplinaryRelieveMapper.insertRtStuDisciplinaryRelieve(rtStuDisciplinaryRelieve);

        if (rtStuDisciplinaryRelieve.getSubmissionStatus() != null && rtStuDisciplinaryRelieve.getSubmissionStatus() == 1) {

            ProcessResultDto processResultDto = startRelieveProcess(rtStuDisciplinaryRelieve);

            if (processResultDto != null) {

                rtStuDisciplinaryRelieve.setProcessInstanceId(processResultDto.getProcessInstanceId());

                rtStuDisciplinaryRelieve.setDeployId(processResultDto.getDeploymentId());
            }
        }

        // 修改处分表
        RtStuDisciplinaryApplication rtStuDisciplinaryApplication = rtStuDisciplinaryApplicationMapper.selectRtStuDisciplinaryApplicationByApplicationId(Long.parseLong(rtStuDisciplinaryRelieve.getPenaltyNumber()));

        if (rtStuDisciplinaryApplication != null) {

            rtStuDisciplinaryApplication.setPenaltyStatus(2L);

            rtStuDisciplinaryApplicationMapper.updateRtStuDisciplinaryApplication(rtStuDisciplinaryApplication);
        }

        return rtStuDisciplinaryRelieveMapper.updateRtStuDisciplinaryRelieve(rtStuDisciplinaryRelieve);
    }

    @Override
    public int editRtStuDisciplinaryRelieve(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        rtStuDisciplinaryRelieve.setUpdateTime(DateUtils.getNowDate());
        rtStuDisciplinaryRelieve.setUpdateBy(SecurityUtils.getUsername());
        if (rtStuDisciplinaryRelieve.getSubmissionStatus() != null && rtStuDisciplinaryRelieve.getSubmissionStatus() == 1) {
            ProcessResultDto processResultDto = startRelieveProcess(rtStuDisciplinaryRelieve);
            if (processResultDto != null) {
                rtStuDisciplinaryRelieve.setProcessInstanceId(processResultDto.getProcessInstanceId());
                rtStuDisciplinaryRelieve.setDeployId(processResultDto.getDeploymentId());
            }
        }
        return rtStuDisciplinaryRelieveMapper.updateRtStuDisciplinaryRelieve(rtStuDisciplinaryRelieve);
    }

    /**
     * 修改学生解除处分申请
     *
     * @param rtStuDisciplinaryRelieve 学生解除处分申请
     * @return 结果
     */
    @Override
    public int updateRtStuDisciplinaryRelieve(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {
        rtStuDisciplinaryRelieve.setUpdateTime(DateUtils.getNowDate());
        return rtStuDisciplinaryRelieveMapper.updateRtStuDisciplinaryRelieve(rtStuDisciplinaryRelieve);
    }

    @Autowired
    IFlowDefinitionService flowDefinitionService;

    @Autowired
    TaskService taskService;

    @Autowired
    IdentityService identityService;

    /**
     * 开启处分工作流
     *
     * @param rtStuDisciplinaryRelieve
     */
    private ProcessResultDto startRelieveProcess(RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve) {

        Map<String, Object> variables = new HashMap<>();
        variables.put("relieveId", rtStuDisciplinaryRelieve.getRelieveId().toString());
        variables.put("penaltyType", rtStuDisciplinaryRelieve.getPenaltyType());
        variables.put("stuUserId", SecurityUtils.getUserId());


        AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_d46199lc:18:832592", variables);
        String code = ajaxResult.get("code").toString();
        if (code.equals("200")) {

            log.info("流程启动成功");

            Object obj = ajaxResult.get("data");

            ProcessResultDto dto = (ProcessResultDto) obj;

            // 操作工作流
            // 设置当前用户
            identityService.setAuthenticatedUserId(SecurityUtils.getUserId().toString());

            // 查询待办任务列表
            List<Task> tasks = taskService.createTaskQuery()
                    .processInstanceId(dto.getProcessInstanceId())
                    .taskAssignee(SecurityUtils.getUserId().toString())
                    .active()
                    .list();

            // 保存审核结果到任务变量中
            variables.put("approved", true);

            // 标记是否有任务被完成
            boolean taskCompleted = false;

            // 完成待办任务列表
            for (Task task : tasks) {
                String taskId = task.getId();
                String applicationId = taskService.getVariable(taskId, "relieveId").toString();
                if (applicationId.equals(rtStuDisciplinaryRelieve.getRelieveId().toString())) {
                    taskService.complete(task.getId(), variables);
                    taskCompleted = true;
                }
            }
            // 所有相关任务完成后，发送企业微信消息
            if (taskCompleted) {
                try {
                    // 获取申请人信息
                    String applicantName = rtStuDisciplinaryRelieve.getStuName();
                    String politicalStatus = rtStuDisciplinaryRelieve.getPoliticalStatus();

                    SysUser sysUser = new SysUser();
                    sysUser.setRoleId(118L);
                    List<SysUser> sysUsers = sysUserMapper.selectAllocatedList(sysUser);

                    // 提取二级学院的书记的账号
                    List<String> userNames = sysUsers.stream()
                            .map(SysUser::getUserName)
                            .collect(Collectors.toList());

                    // 只有政治面貌是团员时才发送企业微信消息
                    if ("团员".equals(politicalStatus)) {
                        // 消息内容
                        String messageContent = "【解除处分】" + applicantName + "的解除处分申请已通过审核。";
                        int batchSize = 10;
                        for (int i = 0; i < userNames.size(); i += batchSize) {
                            List<String> batch = userNames.subList(i, Math.min(i + batchSize, userNames.size()));
                            // 拼接成"user1|user2|user3"格式
                            String toUser = String.join("|", batch);
                            // 调用企业微信发送消息方法
                            weChatUtil.sendTextMessage(toUser, messageContent);
                        }
                    }
                } catch (Exception e) {
                    log.error("发送企业微信消息失败：", e);
                }
            }
            return dto;
        } else {
            return null;
        }
    }

    /**
     * 批量删除学生解除处分申请
     *
     * @param relieveIds 需要删除的学生解除处分申请主键
     * @return 结果
     */
    @Override
    public int deleteRtStuDisciplinaryRelieveByRelieveIds(Long[] relieveIds) {
        return rtStuDisciplinaryRelieveMapper.deleteRtStuDisciplinaryRelieveByRelieveIds(relieveIds);
    }

    /**
     * 删除学生解除处分申请信息
     *
     * @param relieveId 学生解除处分申请主键
     * @return 结果
     */
    @Override
    public int deleteRtStuDisciplinaryRelieveByRelieveId(Long relieveId) {
        return rtStuDisciplinaryRelieveMapper.deleteRtStuDisciplinaryRelieveByRelieveId(relieveId);
    }

    @Override
    public RtStuDisciplinaryRelieve getDisciplinaryRelieveByProcInsId(String procInsId) {
        QueryWrapper queryWrapper = new QueryWrapper();
        queryWrapper.eq("process_instance_id", procInsId);
        RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve = rtStuDisciplinaryRelieveMapper.selectOne(queryWrapper);
        return rtStuDisciplinaryRelieve;
    }

    @Override
    public String importDisciplinaryRelieve(List<RtStuDisciplinaryRelieve> list, boolean updateSupport) {
        if (com.srs.common.utils.StringUtils.isNull(list) || list.size() == 0) {
            throw new ServiceException("导入数据不能为空！");
        }
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (int i = 0; i < list.size(); i++) {
            RtStuDisciplinaryRelieve rtStuDisciplinaryRelieve = list.get(i);
            // 跳过 null 元素
            if (rtStuDisciplinaryRelieve == null) {
                continue;
            }
            
            // 跳过必填字段为空的行（学号为空则跳过）
            if (StringUtils.isEmpty(rtStuDisciplinaryRelieve.getStuNo())) {
                continue;
            }
            
            try {
                if (com.srs.common.utils.StringUtils.isNotNull(rtStuDisciplinaryRelieve.getStuNo())) {
                    SysUser sysUser = sysUserMapper.selectUserByUserName(rtStuDisciplinaryRelieve.getStuNo());
                    if (sysUser != null) {
                        rtStuDisciplinaryRelieve.setStuId(sysUser.getUserId());
                        rtStuDisciplinaryRelieve.setStuName(sysUser.getNickName());
                    }
                }

                rtStuDisciplinaryRelieve.setCreateBy(SecurityUtils.getUsername());
                rtStuDisciplinaryRelieve.setCreateTime(DateUtils.getNowDate());
                rtStuDisciplinaryRelieve.setApplicantName(SecurityUtils.getLoginUser().getUser().getNickName());

                if (rtStuDisciplinaryRelieve.getSubmissionStatus() == null) {
                    rtStuDisciplinaryRelieve.setSubmissionStatus(0L);
                }

                if (rtStuDisciplinaryRelieve.getPenaltyStatus() == null) {
                    rtStuDisciplinaryRelieve.setPenaltyStatus(1L);
                }

                rtStuDisciplinaryRelieveMapper.insertRtStuDisciplinaryRelieve(rtStuDisciplinaryRelieve);
                successNum++;
                successMsg.append("<br/>" + successNum + "、学号 " + rtStuDisciplinaryRelieve.getStuNo() + " 导入成功");
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、学号 " + rtStuDisciplinaryRelieve.getStuNo() + " 导入失败：";
                failureMsg.append(msg + e.getMessage());
            }
        }

        if (failureNum > 0) {
            failureMsg.insert(0, "很抱歉，导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        } else {
            successMsg.insert(0, "恭喜您，数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }
        return successMsg.toString();
    }

}
