package com.srs.routine.service.impl;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.srs.common.core.domain.AjaxResult;
import com.srs.common.doman.dto.ProcessResultDto;
import com.srs.common.doman.vo.TeacherVo;
import com.srs.common.exception.ServiceException;
import com.srs.common.utils.SecurityUtils;
import com.srs.flowable.service.IFlowDefinitionService;
import com.srs.routine.domain.SysDisMate;
import com.srs.routine.mapper.RtEnlistmentReserveMapper;
import com.srs.routine.mapper.RtStuLeaveApplicationMapper;
import com.srs.routine.mapper.SysDisMateMapper;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.IdentityService;
import org.flowable.engine.RuntimeService;
import org.flowable.engine.TaskService;
import org.flowable.engine.runtime.ProcessInstance;
import org.flowable.task.api.Task;
import org.springframework.beans.factory.annotation.Autowired;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import com.srs.routine.mapper.SysDisBasicMapper;
import com.srs.routine.domain.SysDisBasic;
import com.srs.routine.service.ISysDisBasicService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 退伍复学申请Service业务层处理
 *
 * @author srs
 * @date 2025-11-06
 */
@Service
@Slf4j
public class SysDisBasicServiceImpl extends ServiceImpl<SysDisBasicMapper,SysDisBasic> implements ISysDisBasicService {
    @Autowired
    private SysDisBasicMapper sysDisBasicMapper;

    @Autowired
    private SysDisMateMapper sysDisMateMapper;


    /**
     * 查询退伍复学申请
     *
     * @param id 退伍复学申请主键
     * @return 退伍复学申请
     */
    @Override
    public SysDisBasic selectSysDisBasicById(Long id) {
        return sysDisBasicMapper.selectSysDisBasicById(id);
    }

    @Override
    public SysDisBasic selectSysDisBasicByStName(String stName) {
        return sysDisBasicMapper.selectSysDisBasicByStName(stName);
    }

    @Override
    public SysDisBasic selectSysDisBasicByProcessInstanceId(String processId) {
        return sysDisBasicMapper.selectSysDisBasicByProcessInstanceId(processId);
    }

    /**
     * 查询退伍复学申请列表
     *
     * @param sysDisBasic 退伍复学申请
     * @return 退伍复学申请
     */
    @Override
    public List<SysDisBasic> selectSysDisBasicList(SysDisBasic sysDisBasic) {
        return sysDisBasicMapper.selectSysDisBasicList(sysDisBasic);
    }

    /**
     * 新增退伍复学申请
     *
     * @param sysDisBasic 退伍复学申请
     * @return 结果
     */
    @Override
    public int insertSysDisBasic(SysDisBasic sysDisBasic) {
        SysDisBasic inserData = sysDisBasicMapper.selectSysDisBasicByStId(sysDisBasic.getStId());
        if (inserData != null){
            throw new ServiceException("申请已提交，请勿重复提交", 500);
        }
        if (sysDisBasic.getFxId() == null || sysDisBasic.getFxId().trim().isEmpty()) {
            String genFxId = (sysDisBasic.getStId() == null ? SecurityUtils.getUserId().toString() : sysDisBasic.getStId()) + "-" + System.currentTimeMillis();
            sysDisBasic.setFxId(genFxId);
        }
        if ((sysDisBasic.getFxTime() == null || sysDisBasic.getFxTime().trim().isEmpty()) && sysDisBasic.getTimes() != null) {
            sysDisBasic.setFxTime(sysDisBasic.getTimes());
        }
        int insertData = sysDisBasicMapper.insertSysDisBasic(sysDisBasic);
        if (insertData <= 0) {
            throw new ServiceException("申请表插入失败", 500);
        }

        Long applyId = sysDisBasic.getId();
        if (applyId == null) {
            throw new ServiceException("申请表 ID 生成失败，无法继续操作", 500);
        }
        ProcessResultDto processResultDto = startBasicProcess(sysDisBasic);
        if (processResultDto != null){
            sysDisBasic.setProcessId(processResultDto.getProcessInstanceId());
            sysDisBasic.setDeployId(processResultDto.getDeploymentId());
        }
        return insertData;
    }

    private static final Logger logger = LoggerFactory.getLogger(SysDisBasicServiceImpl.class);

    /**
     * 修改退伍复学申请
     *
     * @param sysDisBasic 退伍复学申请
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class) // 事务保证原子性
    public int updateSysDisBasic(SysDisBasic sysDisBasic) {


//        ProcessResultDto processResultDto = startBasicProcess(sysDisBasic);
//        if (processResultDto != null){
//            sysDisBasic.setProcessId(processResultDto.getProcessInstanceId());
//            sysDisBasic.setDeployId(processResultDto.getDeploymentId());
//        }
        int mainTableUpdateCount = sysDisBasicMapper.updateSysDisBasic(sysDisBasic);
        logger.info("主表更新完成，影响行数: {}", mainTableUpdateCount);

        // ========== 2. 整合自定义子表更新逻辑（核心修复） ==========
        List<SysDisMate> maList = sysDisBasic.getMaList();
        logger.info("开始执行子表更新，maList大小: {}", maList != null ? maList.size() : 0);

        if (maList != null && !maList.isEmpty()) {
            for (SysDisMate mate : maList) {
                logger.info("正在更新子表记录，子表ID: {}, finaldata1: {}", mate.getId(), mate.getFinaldata1());

                int updateResult = 0;
                // 优先使用子表主键id更新（自定义SQL，避免update_time）
                if (mate.getId() != null) {
                    LambdaUpdateWrapper<SysDisMate> updateWrapper = Wrappers.lambdaUpdate(SysDisMate.class);
                    updateWrapper.eq(SysDisMate::getId, mate.getId())
                            .set(mate.getStId() != null, SysDisMate::getStId, mate.getStId())
                            .set(mate.getStName() != null, SysDisMate::getStName, mate.getStName())
                            .set(mate.getCollege() != null, SysDisMate::getCollege, mate.getCollege())
                            .set(mate.getOldgrade() != null, SysDisMate::getOldgrade, mate.getOldgrade())
                            .set(mate.getOldmajor() != null, SysDisMate::getOldmajor, mate.getOldmajor())
                            .set(mate.getNewgrade() != null, SysDisMate::getNewgrade, mate.getNewgrade())
                            .set(mate.getNewmajor() != null, SysDisMate::getNewmajor, mate.getNewmajor())
                            .set(mate.getFinaldata1() != null, SysDisMate::getFinaldata1, mate.getFinaldata1())
                            .set(mate.getFinaldata2() != null, SysDisMate::getFinaldata2, mate.getFinaldata2())
                            .set(mate.getFinalmajor() != null, SysDisMate::getFinalmajor, mate.getFinalmajor())
                            .set(mate.getFinallabel() != null, SysDisMate::getFinallabel, mate.getFinallabel())
//                    新增表字段位置
                            .set(mate.getCollegeInfo() != null, SysDisMate::getCollegeInfo, mate.getCollegeInfo())
                            .set(mate.getGradeInfo() != null, SysDisMate::getGradeInfo, mate.getGradeInfo())
                            .set(mate.getMajorInfo() != null, SysDisMate::getMajorInfo, mate.getMajorInfo())
                            .set(mate.getClassInfo() != null, SysDisMate::getClassInfo, mate.getClassInfo())
                            .set(mate.getTestData() != null, SysDisMate::getTestData, mate.getTestData())
                            .set(mate.getTestSave() != null, SysDisMate::getTestSave, mate.getTestSave());

                    updateResult = sysDisMateMapper.update(null, updateWrapper);
                    logger.info("通过子表ID自定义更新，影响行数: {}", updateResult);
                }
                // 兼容：无id时按st_id更新（同样自定义SQL）
                else if (mate.getStId() != null && !mate.getStId().isEmpty()) {
                    LambdaUpdateWrapper<SysDisMate> updateWrapper = Wrappers.lambdaUpdate(SysDisMate.class);
                    updateWrapper.eq(SysDisMate::getStId, mate.getStId())
                            .set(mate.getStName() != null, SysDisMate::getStName, mate.getStName())
                            .set(mate.getCollege() != null, SysDisMate::getCollege, mate.getCollege())
                            .set(mate.getOldgrade() != null, SysDisMate::getOldgrade, mate.getOldgrade())
                            .set(mate.getOldmajor() != null, SysDisMate::getOldmajor, mate.getOldmajor())
                            .set(mate.getNewgrade() != null, SysDisMate::getNewgrade, mate.getNewgrade())
                            .set(mate.getNewmajor() != null, SysDisMate::getNewmajor, mate.getNewmajor())
                            .set(mate.getFinaldata1() != null, SysDisMate::getFinaldata1, mate.getFinaldata1())
                            .set(mate.getFinaldata2() != null, SysDisMate::getFinaldata2, mate.getFinaldata2())
                            .set(mate.getFinalmajor() != null, SysDisMate::getFinalmajor, mate.getFinalmajor())
                            .set(mate.getFinallabel() != null, SysDisMate::getFinallabel, mate.getFinallabel())
//                            新增子表字段
                            .set(mate.getCollegeInfo() != null, SysDisMate::getCollegeInfo, mate.getCollegeInfo())
                            .set(mate.getGradeInfo() != null, SysDisMate::getGradeInfo, mate.getGradeInfo())
                            .set(mate.getMajorInfo() != null, SysDisMate::getMajorInfo, mate.getMajorInfo())
                            .set(mate.getClassInfo() != null, SysDisMate::getClassInfo, mate.getClassInfo())
                            .set(mate.getTestData() != null, SysDisMate::getTestData, mate.getTestData())
                            .set(mate.getTestSave() != null, SysDisMate::getTestSave, mate.getTestSave());

                    updateResult = sysDisMateMapper.update(null, updateWrapper);
                    logger.info("通过st_id自定义更新，影响行数: {}", updateResult);
                }
                // 无更新条件时提示
                else {
                    logger.warn("子表记录缺少id和stId，无法更新");
                    continue;
                }

                // 校验更新结果，失败时打印错误日志
                if (updateResult <= 0) {
                    logger.error("子表更新失败，子表ID: {}, stId: {}", mate.getId(), mate.getStId());
                    // 可选：抛出异常让事务回滚（根据业务需求决定是否开启）
                    // throw new RuntimeException("子表更新失败，影响行数为0");
                }
            }
        } else {
            logger.warn("子表数据为空，跳过子表更新");
        }

        // ========== 3. 原有返回值不变 ==========
        return mainTableUpdateCount;
    }

    /**
     * 批量删除退伍复学申请
     *
     * @param ids 需要删除的退伍复学申请主键
     * @return 结果
     */
    @Override
    public int deleteSysDisBasicByIds(Long[] ids) {
        return sysDisBasicMapper.deleteSysDisBasicByIds(ids);
    }

    /**
     * 删除退伍复学申请信息
     *
     * @param id 退伍复学申请主键
     * @return 结果
     */
    @Override
    public int deleteSysDisBasicById(Long id) {
        return sysDisBasicMapper.deleteSysDisBasicById(id);
    }

    @Autowired
    IFlowDefinitionService flowDefinitionService;

    @Autowired
    TaskService taskService;

    @Autowired
    IdentityService identityService;

    @Autowired
    private RtStuLeaveApplicationMapper rtStuLeaveApplicationMapper;

    @Autowired
    private RtEnlistmentReserveMapper rtEnlistmentReserveMapper;
    /**
     * 开启请假工作流
     *
     * @param
     */
//    private ProcessResultDto startBasicProcess(SysDisBasic sysDisBasic) {
//
//        Map<String, Object> variables = new HashMap<>();
//        variables.put("basicId", sysDisBasic.getId());
//        variables.put("conversion", sysDisBasic.getConversion());
//        variables.put("stuId", sysDisBasic.getStId());
//
//        if ("N".equals(sysDisBasic.getConversion())) { // 修复字符串比较方式
//            TeacherVo counselorInfo = rtEnlistmentReserveMapper.getCounselorInfo(sysDisBasic.getStId());
//            if (counselorInfo == null) {
//                log.error("未查询到辅导员信息，stuId: {}", sysDisBasic.getStId());
//                return null; // 避免空指针
//            }
//            variables.put("approval", counselorInfo.getUserId());
//            variables.put("deptId", counselorInfo.getDeptId());
//            // 无需重复设置 conversion = "N"，因为已经通过上面的代码设置过了
//        }else {
//            List<TeacherVo> zjcData = sysDisBasicMapper.getShenDataInfo("招就处");
//            if (zjcData == null) {
//                log.error("未查询到辅导员信息，stuId: {}", sysDisBasic.getStId());
//                return null; // 避免空指针
//            }
//            variables.put("approval", zjcData.get(0).getUserId());
//            variables.put("deptId", zjcData.get(0).getDeptId());
//        }
////
//
//        //flow_m4npextk:28:257686 flow_m4npextk:31:755004
//        AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_nrblbjev:15:1330041", 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);
//            // 完成待办任务列表
//            for (Task task : tasks) {
//                String taskId = task.getId();
//                String leaveId = taskService.getVariable(taskId, "basicId").toString();
//                if (leaveId.equals(sysDisBasic.getId().toString())) {
//                    taskService.complete(task.getId(), variables);
//                }
//            }
//
//            // todo 企业微信推送消息
//
//
//            return dto;
//        } else {
//            return null;
//        }
//    }

    @Autowired
    private RuntimeService runtimeService;

    private ProcessResultDto startBasicProcess(SysDisBasic sysDisBasic) {
        // 新增：核心唯一标识获取+空指针防护
        Long applyId = sysDisBasic.getId();
        String stId = sysDisBasic.getStId();
        if (applyId == null || stId == null) {
            log.error("申请ID/学生ID为空，无法启动工作流 - applyId: {}, stId: {}", applyId, stId);
            return null;
        }
        String basicId = applyId.toString();

        // --------------- 新增：启动前暴力清理该学生所有流程实例（核心拦截）---------------
        List<ProcessInstance> duplicateInstances = runtimeService.createProcessInstanceQuery()
                .variableValueEquals("stuId", stId) // 按学生ID精准匹配
                .list();
        for (ProcessInstance instance : duplicateInstances) {
            log.warn("清理学生重复流程实例 - stId: {}, 实例ID: {}", stId, instance.getId());
            runtimeService.deleteProcessInstance(instance.getId(), "同一学生重复提交清理");
        }

        // --------------- 原有变量构建（仅添加禁用回调标记）---------------
        Map<String, Object> variables = new HashMap<>();
        variables.put("basicId", sysDisBasic.getId());
        variables.put("conversion", sysDisBasic.getConversion());
        variables.put("stuId", sysDisBasic.getStId());
        // 新增：禁用所有自动回调（切断框架触发重复的链路）
        variables.put("skipFormCallback", true);
        variables.put("noAutoCallback", true);

        // --------------- 原有审核人查询（优化空指针）---------------
        if ("N".equals(sysDisBasic.getConversion())) {
            TeacherVo counselorInfo = rtEnlistmentReserveMapper.getCounselorInfo(sysDisBasic.getStId());
            if (counselorInfo == null) {
                log.error("未查询到辅导员信息，stuId: {}", sysDisBasic.getStId());
                return null;
            }
            variables.put("approval", counselorInfo.getUserId());
            variables.put("deptId", counselorInfo.getDeptId());
        } else {
            List<TeacherVo> zjcData = sysDisBasicMapper.getShenDataInfo("招就处");
            // 修复：添加集合非空判断，避免IndexOutOfBoundsException
            if (zjcData == null || zjcData.isEmpty()) {
                log.error("未查询到招就处审核人信息，stuId: {}", sysDisBasic.getStId());
                return null;
            }
            variables.put("approval", zjcData.get(0).getUserId());
            variables.put("deptId", zjcData.get(0).getDeptId());
        }

        // --------------- 原有流程启动逻辑（不变）---------------
        AjaxResult ajaxResult = flowDefinitionService.startProcessInstanceById("flow_nrblbjev:21:1517504", variables);
        String code = ajaxResult.get("code").toString();
        if (code.equals("200")) {
            log.info("流程启动成功 - stId: {}, applyId: {}", stId, basicId);

            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();

            // --------------- 核心修改：删除approved变量，任务完成不传递任何参数 ---------------
            // 注释掉：variables.put("approved", true); // 移除该变量，避免触发回调

            // 完成待办任务列表
            for (Task task : tasks) {
                String taskId = task.getId();
                // 新增：变量非空校验，避免空指针
                Object taskBasicIdObj = taskService.getVariable(taskId, "basicId");
                if (taskBasicIdObj == null) {
                    log.warn("任务变量basicId为空，跳过任务 - 任务ID: {}", taskId);
                    continue;
                }
                String leaveId = taskBasicIdObj.toString();
                if (leaveId.equals(basicId)) {
                    // 核心修改：仅完成任务，不传递variables（切断回调触发重复）
                    taskService.complete(task.getId());
                    log.info("自动完成任务 - 任务ID: {}, 实例ID: {}", taskId, dto.getProcessInstanceId());
                }
            }

            // todo 企业微信推送消息
            return dto;
        } else {
            log.error("流程启动失败，响应码: {}", code);
            return null;
        }
    }

}
