package com.aucma.dms.service.impl;

import com.aucma.common.constant.DmsConstants;
import com.aucma.common.exception.ServiceException;
import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.SecurityUtils;
import com.aucma.common.utils.uuid.Seq;
import com.aucma.dms.domain.DmsBillsFaultInstance;
import com.aucma.dms.domain.DmsFaultCompentsParts;
import com.aucma.dms.domain.DmsFaultInstanceActivity;
import com.aucma.dms.domain.DmsInstanceFile;
import com.aucma.dms.domain.vo.DmsBillsFaultInstanceScanVo;
import com.aucma.dms.mapper.DmsBillsFaultInstanceMapper;
import com.aucma.dms.mapper.DmsFaultInstanceActivityMapper;
import com.aucma.dms.mapper.DmsInstanceFileMapper;
import com.aucma.dms.service.IDmsBillsFaultInstanceService;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * 报修工单Service业务层处理
 *
 * @author Open Platform
 * @date 2024-01-23
 */
@Service
public class DmsBillsFaultInstanceServiceImpl implements IDmsBillsFaultInstanceService {
    private static final Logger log = LoggerFactory.getLogger(DmsBillsFaultInstanceServiceImpl.class);

    @Autowired
    private DmsBillsFaultInstanceMapper dmsBillsFaultInstanceMapper;
    @Autowired
    private DmsFaultInstanceActivityMapper dmsFaultInstanceActivityMapper;
    @Autowired
    private DmsInstanceFileMapper dmsInstanceFileMapper;


    /**
     * 查询报修工单
     *
     * @param repairInstanceId 报修工单主键
     * @return 报修工单
     */
    @Override
    public DmsBillsFaultInstance selectDmsBillsFaultInstanceByRepairInstanceId(Long repairInstanceId) {
        // 使用包含完整操作记录列表的查询方法
        DmsBillsFaultInstance dmsBillsFaultInstance = dmsBillsFaultInstanceMapper.selectFaultInstanceJoinActivityByRepairInstanceId(repairInstanceId);
        
        // 获取首条操作记录附件（合并前后阶段）
        if (dmsBillsFaultInstance.getInstanceActivityId() != null) {
            List<DmsInstanceFile> instanceFiles = loadActivityFiles(dmsBillsFaultInstance.getInstanceActivityId());
            dmsBillsFaultInstance.setDmsInstanceFiles(instanceFiles);
        }
        
        // 为每个操作记录加载附件，并回填首步记录的操作人和时间
        List<DmsFaultInstanceActivity> activityList = dmsBillsFaultInstance.getDmsFaultInstanceActivityList();
        if (!CollectionUtils.isEmpty(activityList)) {
            for (DmsFaultInstanceActivity activity : activityList) {
                List<DmsInstanceFile> activityFiles = loadActivityFiles(activity.getInstanceActivityId());
                activity.setFileCount(activityFiles.size());
                activity.setDmsInstanceFiles(activityFiles);
                
                // 首步记录（processStepOrder=1）回填操作人和时间
                if (activity.getProcessStepOrder() != null && activity.getProcessStepOrder() == 1) {
                    if (activity.getHandleBy() == null || activity.getHandleBy().isEmpty()) {
                        activity.setHandleBy(dmsBillsFaultInstance.getApplyUser());
                    }
                    if (activity.getHandleTime() == null) {
                        activity.setHandleTime(dmsBillsFaultInstance.getApplyTime());
                    }
                }

                // 设置任务名称，避免前端“任务”列为空
                if (activity.getProcessStepOrder() != null) {
                    if (activity.getProcessStepOrder() == 1L) {
                        activity.setProcessActivityName("报修");
                    } else if (activity.getProcessStepOrder() == 2L) {
                        activity.setProcessActivityName("维修");
                    } else {
                        activity.setProcessActivityName("步骤" + activity.getProcessStepOrder());
                    }
                }
            }
        }

        return dmsBillsFaultInstance;
    }

    /**
     * 查询报修工单列表
     *
     * @param dmsBillsFaultInstance 报修工单
     * @return 报修工单
     */
    @Override
    public List<DmsBillsFaultInstance> selectDmsBillsFaultInstanceList(DmsBillsFaultInstance dmsBillsFaultInstance) {

        return dmsBillsFaultInstanceMapper.selectDmsBillsFaultInstanceList(dmsBillsFaultInstance);
    }

    /**
     * 新增报修工单
     *
     * @param dmsBillsFaultInstance 报修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertDmsBillsFaultInstance(DmsBillsFaultInstance dmsBillsFaultInstance) {
        Date currentDate = new Date();
        String userName = SecurityUtils.getLoginUser()==null ? SecurityUtils.getUsername() :SecurityUtils.getLoginUser().getUser().getNickName() ;
//        dmsBillsFaultInstance.setWfProcessId(WfConstants.WF_BILLS_FAULT_INSTANCE_PROCESS_ID);
        if (StringUtils.isBlank(dmsBillsFaultInstance.getApplyUser())) {
            dmsBillsFaultInstance.setApplyUser(userName);
        }
        dmsBillsFaultInstance.setApplyTime(currentDate);
        dmsBillsFaultInstance.setCreateTime(currentDate);
        dmsBillsFaultInstance.setCreateBy(SecurityUtils.getUserId());
        dmsBillsFaultInstance.setBillsFaultCode(Seq.getId(Seq.dmsBillsFaultInstanceSeqType, Seq.dmsBillsFaultInstanceSeqCode));
        dmsBillsFaultInstance.setBillsStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_TO_REPAIR);
        dmsBillsFaultInstance.setInstanceType(DmsConstants.DMS_BILLS_FAULT_INSTANCE_TYPE_MAUAL);
        dmsBillsFaultInstance.setIsFlag("1");
        // 设置默认报修来源类型为其他（9），避免 NULL 导致统计不准确
        if (dmsBillsFaultInstance.getFaultSourceType() == null || dmsBillsFaultInstance.getFaultSourceType().isEmpty()) {
            dmsBillsFaultInstance.setFaultSourceType("9");
        }
        // 设置默认审批状态为未审批（避免 NULL 导致查询时被过滤）
        if (dmsBillsFaultInstance.getApproveStatus() == null || dmsBillsFaultInstance.getApproveStatus().isEmpty()) {
            dmsBillsFaultInstance.setApproveStatus("0");
        }

        int rows = dmsBillsFaultInstanceMapper.insertDmsBillsFaultInstance(dmsBillsFaultInstance);

        DmsFaultInstanceActivity dmsFaultInstanceActivity = new DmsFaultInstanceActivity();
        dmsFaultInstanceActivity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
        // 已废弃审批流功能 - 设置固定值或注释
        // dmsFaultInstanceActivity.setProcessActivityId(WfConstants.WF_BILLS_FAULT_INSTANCE_PROCESS_ACTIVITY_FIRST_ID);
        //dmsFaultInstanceActivity.setProcessActivityId(1L);
        dmsFaultInstanceActivity.setFaultType(dmsBillsFaultInstance.getFaultType());
        dmsFaultInstanceActivity.setFaultDescription(dmsBillsFaultInstance.getFaultDescription());
        dmsFaultInstanceActivity.setDesignOperations(dmsBillsFaultInstance.getDesignOperations());
        dmsFaultInstanceActivity.setDeviceId(dmsBillsFaultInstance.getDeviceId());
        dmsFaultInstanceActivity.setRepairType(dmsBillsFaultInstance.getRepairType());
        if (dmsBillsFaultInstance.getOutsrcId() != null) {
            dmsFaultInstanceActivity.setOutsrcId(dmsBillsFaultInstance.getOutsrcId());
        }
        dmsFaultInstanceActivity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_TO_PICK);
        dmsFaultInstanceActivity.setProcessStepOrder(1l);
        dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(dmsFaultInstanceActivity);

        //存储图片
        List<String> fileUrls = dmsBillsFaultInstance.getFileUrls();
        if (fileUrls != null && !fileUrls.isEmpty()) {
            batchInsertInstanceFiles(fileUrls, dmsFaultInstanceActivity.getInstanceActivityId());
        }

        // 保存前端传来的操作记录列表（如果有）
        List<DmsFaultInstanceActivity> activityList = dmsBillsFaultInstance.getDmsFaultInstanceActivityList();
        if (!CollectionUtils.isEmpty(activityList)) {
            for (int i = 0; i < activityList.size(); i++) {
                DmsFaultInstanceActivity activity = activityList.get(i);
                activity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
                activity.setProcessStepOrder((long)(i + 2)); // 从第2步开始，第1步已经创建
                activity.setCreateTime(currentDate);
                activity.setCreateBy(SecurityUtils.getUserId());
                activity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_TO_PICK);
                
                // 插入操作记录
                dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(activity);
                
                // 处理操作记录的附件
                if (activity.getFileUrls() != null && !activity.getFileUrls().isEmpty()) {
                    batchInsertInstanceFiles(activity.getFileUrls(), activity.getInstanceActivityId());
                }
            }
        }

        return rows;
    }

    /**
     * 修改报修工单
     *
     * @param dmsBillsFaultInstance 报修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int updateDmsBillsFaultInstance(DmsBillsFaultInstance dmsBillsFaultInstance) {
        String username =SecurityUtils.getLoginUser()==null ? SecurityUtils.getUsername() :SecurityUtils.getLoginUser().getUser().getNickName() ;
        if (dmsBillsFaultInstance.getRepairConfirm()!=null){
            dmsBillsFaultInstance.setConfirmer(username);
        }
        Date currentDate = DateUtils.getNowDate();
        dmsBillsFaultInstance.setUpdateTime(currentDate);
        dmsBillsFaultInstance.setUpdateBy(SecurityUtils.getUserId());
        
        // 更新主工单
        int i = dmsBillsFaultInstanceMapper.updateDmsBillsFaultInstance(dmsBillsFaultInstance);
        
        // 处理主工单的附件（如果有）
        if (dmsBillsFaultInstance.getInstanceActivityId() != null) {
            dmsInstanceFileMapper.deleteDmsInstanceFileByUpdate(dmsBillsFaultInstance.getRepairInstanceId());
            List<String> fileUrls = dmsBillsFaultInstance.getFileUrls();
            if (fileUrls != null && !fileUrls.isEmpty()) {
                batchInsertInstanceFiles(fileUrls, dmsBillsFaultInstance.getInstanceActivityId());
            }
        }
        
        // 兼容顶层字段：将故障信息与处理意见同步到第1步操作记录（便于前端直接从主对象读取展示）
        DmsFaultInstanceActivity first = dmsFaultInstanceActivityMapper.selectDmsFaultInstanceActivityByRepairIdMin(dmsBillsFaultInstance.getRepairInstanceId());
        if (first != null) {
            DmsFaultInstanceActivity updateFirst = new DmsFaultInstanceActivity();
            updateFirst.setInstanceActivityId(first.getInstanceActivityId());
            if (dmsBillsFaultInstance.getFaultType() != null) {
                updateFirst.setFaultType(dmsBillsFaultInstance.getFaultType());
            }
            if (dmsBillsFaultInstance.getFaultDescription() != null) {
                updateFirst.setFaultDescription(dmsBillsFaultInstance.getFaultDescription());
            }
            if (dmsBillsFaultInstance.getDesignOperations() != null) {
                updateFirst.setDesignOperations(dmsBillsFaultInstance.getDesignOperations());
            }
            if (dmsBillsFaultInstance.getProcessHandleResolution() != null) {
                updateFirst.setProcessHandleResolution(dmsBillsFaultInstance.getProcessHandleResolution());
            }
            updateFirst.setUpdateTime(currentDate);
            updateFirst.setUpdateBy(SecurityUtils.getUserId());
            dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(updateFirst);
        }
        
        // 处理操作记录列表
        List<DmsFaultInstanceActivity> activityList = dmsBillsFaultInstance.getDmsFaultInstanceActivityList();
        if (!CollectionUtils.isEmpty(activityList)) {
            for (DmsFaultInstanceActivity activity : activityList) {
                if (activity.getInstanceActivityId() != null && activity.getInstanceActivityId() > 0) {
                    // 更新已有记录
                    activity.setUpdateTime(currentDate);
                    activity.setUpdateBy(SecurityUtils.getUserId());
                    dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(activity);
                    
                    // 更新附件：先删除旧的，再插入新的
                    if (activity.getFileUrls() != null && !activity.getFileUrls().isEmpty()) {
                        dmsInstanceFileMapper.deleteDmsInstanceFileByTargetId(activity.getInstanceActivityId());
                        batchInsertInstanceFiles(activity.getFileUrls(), activity.getInstanceActivityId());
                    }
                } else {
                    // 新增记录
                    activity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
                    activity.setCreateTime(currentDate);
                    activity.setCreateBy(SecurityUtils.getUserId());
                    activity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_TO_PICK);
                    
                    // 设置步骤顺序（查询当前最大步骤号+1）
                    DmsFaultInstanceActivity queryActivity = new DmsFaultInstanceActivity();
                    queryActivity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
                    List<DmsFaultInstanceActivity> existingList = dmsFaultInstanceActivityMapper.selectDmsFaultInstanceActivityList(queryActivity);
                    long maxOrder = existingList.stream()
                            .mapToLong(a -> a.getProcessStepOrder() != null ? a.getProcessStepOrder() : 0)
                            .max()
                            .orElse(0);
                    activity.setProcessStepOrder(maxOrder + 1);
                    
                    // 插入新记录
                    dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(activity);
                    
                    // 插入附件
                    if (activity.getFileUrls() != null && !activity.getFileUrls().isEmpty()) {
                        batchInsertInstanceFiles(activity.getFileUrls(), activity.getInstanceActivityId());
                    }
                }
            }
        }
        
        return i;
    }

    /**
     * 批量删除报修工单
     *
     * @param repairInstanceIds 需要删除的报修工单主键
     * @return 结果
     */
    @Override
    public int deleteDmsBillsFaultInstanceByRepairInstanceIds(Long[] repairInstanceIds) {
        return dmsBillsFaultInstanceMapper.deleteDmsBillsFaultInstanceByRepairInstanceIds(repairInstanceIds);
    }

    /**
     * 删除报修工单信息
     *
     * @param repairInstanceId 报修工单主键
     * @return 结果
     */
    @Override
    public int deleteDmsBillsFaultInstanceByRepairInstanceId(Long repairInstanceId) {
        return dmsBillsFaultInstanceMapper.deleteDmsBillsFaultInstanceByRepairInstanceId(repairInstanceId);
    }

    /**
     * pda-新增报修工单
     */
    public int insertDmsBillsFaultInstancePDA(DmsBillsFaultInstance dmsBillsFaultInstance) {
        //根据报修流程查询工单流程节点id
//        Long aLong = dmsBillsFaultInstanceMapper.selectProcessActivityId(102l);
        int i = dmsBillsFaultInstanceMapper.insertDmsBillsFaultInstance(dmsBillsFaultInstance);
        DmsFaultInstanceActivity dmsFaultInstanceActivity = new DmsFaultInstanceActivity();
        //生成故障报修工单实例节点第一步
        dmsFaultInstanceActivity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
        dmsFaultInstanceActivity.setFaultType(dmsBillsFaultInstance.getFaultType());
        dmsFaultInstanceActivity.setFaultDescription(dmsBillsFaultInstance.getFaultDescription());
        dmsFaultInstanceActivity.setDesignOperations(dmsBillsFaultInstance.getDesignOperations());
        dmsFaultInstanceActivity.setDeviceId(dmsBillsFaultInstance.getDeviceId());
        dmsFaultInstanceActivity.setRepairType(dmsBillsFaultInstance.getRepairType());
        dmsFaultInstanceActivity.setOutsrcId(dmsBillsFaultInstance.getOutsrcId());
//        dmsFaultInstanceActivity.setProcessActivityId(aLong);
        dmsFaultInstanceActivity.setProcessStepOrder(1l);
        dmsFaultInstanceActivity.setCreateTime(DateUtils.getNowDate());
        dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(dmsFaultInstanceActivity);
        return i;
    }


    /**
     * 查询报修工单列表，Join 设备
     *
     * @param dmsBillsFaultInstance 报修工单
     * @return 报修工单
     */
    @Override
    public List<DmsBillsFaultInstance> selectDmsBillsFaultInstanceJoinList(DmsBillsFaultInstance dmsBillsFaultInstance) {

        return dmsBillsFaultInstanceMapper.selectDmsBillsFaultInstanceJoinList(dmsBillsFaultInstance);
    }


    /**
     * 获取故障报修工单明细，提供给维修使用
     *
     * @param repairInstanceId
     * @return
     */
    @Override
    public DmsBillsFaultInstance getDmsBillsFaultInstance4Repair(Long repairInstanceId) {
        DmsBillsFaultInstance dmsBillsFaultInstance = dmsBillsFaultInstanceMapper.selectFaultInstanceJoinActivityByRepairInstanceId(repairInstanceId);
        if (dmsBillsFaultInstance == null) {
            return null;
        }
        
        Long repairInstanceId1 = dmsBillsFaultInstance.getRepairInstanceId();
        List<DmsFaultCompentsParts> parts = dmsFaultInstanceActivityMapper.selectPartsById(repairInstanceId1);
        dmsBillsFaultInstance.setParts(parts);
        
        List<DmsFaultInstanceActivity> dmsBillsFaultInstanceActivityList = dmsBillsFaultInstance.getDmsFaultInstanceActivityList();
        if (CollectionUtils.isEmpty(dmsBillsFaultInstanceActivityList)) {
            return dmsBillsFaultInstance;
        }
        
        DmsFaultInstanceActivity firstStepActivity = dmsBillsFaultInstanceActivityList.get(0);
        DmsFaultInstanceActivity dmsFaultInstanceActivity;
        if (dmsBillsFaultInstanceActivityList.size() == 1) {
            dmsFaultInstanceActivity = firstStepActivity;
            dmsBillsFaultInstance.setInstanceActivityId(firstStepActivity.getInstanceActivityId());
        } else {
            dmsFaultInstanceActivity = dmsBillsFaultInstanceActivityList.get(1);
            dmsBillsFaultInstance.setInstanceActivityId(dmsFaultInstanceActivity.getInstanceActivityId());
        }
        
        for (DmsFaultInstanceActivity activity : dmsBillsFaultInstanceActivityList) {
            DmsFaultInstanceActivity instanceActivity = dmsFaultInstanceActivityMapper.selectDmsFaultInstanceActivityByInstanceActivityId(activity.getInstanceActivityId());
            // 添加空指针检查
            if (instanceActivity == null) {
                continue;
            }
            
            // 检查 processActivityId 是否为 1021
            if (instanceActivity.getProcessActivityId() != null && instanceActivity.getProcessActivityId() == 1021l) {
                dmsBillsFaultInstance.setCheckedFault(instanceActivity.getCheckedFault());
                List<DmsInstanceFile> instanceFiles = loadActivityFiles(activity.getInstanceActivityId());
                dmsBillsFaultInstance.setDmsInstanceFiles(instanceFiles);
                dmsBillsFaultInstance.setConfirmTime(instanceActivity.getConfirmTime());
                dmsBillsFaultInstance.setRepairContent(instanceActivity.getRepairContent());
                dmsBillsFaultInstance.setProtectedMethod(instanceActivity.getProtectedMethod());
                dmsBillsFaultInstance.setRepairer(instanceActivity.getRepairer());
                dmsBillsFaultInstance.setRepairConfirm(instanceActivity.getRepairConfirm());
                dmsBillsFaultInstance.setProcessHandleResolution(instanceActivity.getProcessHandleResolution());
                dmsBillsFaultInstance.setDmsInstanceFiles1(null);
            }
        }
        dmsBillsFaultInstance.setFaultType(dmsFaultInstanceActivity.getFaultType());
        dmsBillsFaultInstance.setFaultDescription(firstStepActivity.getFaultDescription());
        dmsBillsFaultInstance.setDesignOperations(dmsFaultInstanceActivity.getDesignOperations());
        dmsBillsFaultInstance.setDeviceId(dmsFaultInstanceActivity.getDeviceId());
        dmsBillsFaultInstance.setRepairType(dmsFaultInstanceActivity.getRepairType());
        dmsBillsFaultInstance.setOutsrcId(dmsFaultInstanceActivity.getOutsrcId());


        dmsBillsFaultInstance.setDmsFaultInstanceActivityList(null);

//        DmsInstanceFile queryInstanceFile = new DmsInstanceFile();
////        queryInstanceFile.setTargetType(DmsConstants.DMS_INSTANCE_FILE_TARGET_TYPE_FAULT_INSTANCE_ACTIVITY);
//        queryInstanceFile.setTargetId(dmsBillsFaultInstanceActivityList.get(0).getInstanceActivityId());
//        queryInstanceFile.setTargetType("1");
//        List<DmsInstanceFile> dmsInstanceFiles = dmsInstanceFileMapper.selectDmsInstanceFileList(queryInstanceFile);
//        queryInstanceFile.setTargetId(dmsBillsFaultInstanceActivityList.get(1).getInstanceActivityId());
//        queryInstanceFile.setTargetType("2");
//        List<DmsInstanceFile> dmsInstanceFiles1 = dmsInstanceFileMapper.selectDmsInstanceFileList(queryInstanceFile);
//        dmsBillsFaultInstance.setDmsInstanceFiles(dmsInstanceFiles);
//        dmsBillsFaultInstance.setDmsInstanceFiles1(dmsInstanceFiles1);
        return dmsBillsFaultInstance;
    }


    /**
     * 修改报修工单实例节点
     *
     * @param dmsFaultInstanceActivity 报修工单实例节点
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int updateDmsFaultInstanceActivity(DmsFaultInstanceActivity dmsFaultInstanceActivity) {
        List<String> fileUrls = dmsFaultInstanceActivity.getFileUrls();
        Long activityId = dmsFaultInstanceActivity.getInstanceActivityId();
        Long repairInstanceId = dmsFaultInstanceActivityMapper.selectRepairInstanceId(activityId);
        DmsBillsFaultInstance dmsBillsFaultInstance = new DmsBillsFaultInstance();
        dmsBillsFaultInstance.setOutsrcId(dmsFaultInstanceActivity.getOutsrcId());
        dmsBillsFaultInstance.setFaultSourceType(dmsFaultInstanceActivity.getFaultSourceType());
        dmsBillsFaultInstance.setFaultType(dmsFaultInstanceActivity.getFaultType());
        dmsBillsFaultInstance.setRepairInstanceId(repairInstanceId);
        int i = dmsBillsFaultInstanceMapper.updateDmsBillsFaultInstance(dmsBillsFaultInstance);
        int rows = dmsFaultInstanceActivityMapper.deleteByTargetId(activityId);
        batchInsertInstanceFiles(fileUrls,activityId);
        return dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(dmsFaultInstanceActivity);
    }

    /**
     * 扫描设备编码验证，验证通过后进行维修
     *
     * @param dmsBillsFaultInstanceScanVo
     */
    @Override
    public void scanDevice4Repair(DmsBillsFaultInstanceScanVo dmsBillsFaultInstanceScanVo) {
        Long count = dmsBillsFaultInstanceMapper.selectCountByRepairInstanceIdAndDeviceCode(
                dmsBillsFaultInstanceScanVo.getRepairInstanceId(), dmsBillsFaultInstanceScanVo.getDeviceCode());
        if (count <= 0) {
            throw new ServiceException("扫描验证失败");
        }
    }


    /**
     * 开始维修
     *
     * @param dmsFaultInstanceActivity 报修工单实例节点
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int startRepair(DmsFaultInstanceActivity dmsFaultInstanceActivity) {
        DmsBillsFaultInstance dmsBillsFaultInstance = dmsBillsFaultInstanceMapper
                .selectFaultInstanceJoinFirstById(dmsFaultInstanceActivity.getRepairInstanceId());//join 第一步activity
        String dmsBillsStatus = dmsBillsFaultInstance.getBillsStatus();
        if (dmsBillsStatus.equals(DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_FINISH)) {//维修完成
            throw new ServiceException("已经维修完成");
        }

        Date currentDate = new Date();
        String userName = SecurityUtils.getLoginUser()==null ? SecurityUtils.getUsername() :SecurityUtils.getLoginUser().getUser().getNickName();

        if (dmsBillsStatus.equals(DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_TO_REPAIR)) {//待维修
            dmsBillsFaultInstance.setBillsStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_REPAIRING);
            dmsBillsFaultInstance.setRealBeginTime(currentDate);
            dmsBillsFaultInstance.setUpdateTime(currentDate);
            dmsBillsFaultInstance.setUpdateBy(SecurityUtils.getUserId());
            dmsBillsFaultInstanceMapper.updateDmsBillsFaultInstance(dmsBillsFaultInstance);
            // 若已存在第2步（派工后），则改为执行中；否则新增第2步
            DmsFaultInstanceActivity query = new DmsFaultInstanceActivity();
            query.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
            query.setProcessStepOrder(2L);
            List<DmsFaultInstanceActivity> step2List = dmsFaultInstanceActivityMapper.selectDmsFaultInstanceActivityList(query);
            if (!CollectionUtils.isEmpty(step2List)) {
                DmsFaultInstanceActivity updateStep2 = new DmsFaultInstanceActivity();
                updateStep2.setInstanceActivityId(step2List.get(0).getInstanceActivityId());
                updateStep2.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_EXECUTING);
                updateStep2.setStartTime(currentDate);
                // 若未指定执行人，默认当前人
                if (step2List.get(0).getHandleUserId() == null) {
                    updateStep2.setHandleUserId(SecurityUtils.getUserId());
                    updateStep2.setHandleBy(userName);
                }
                updateStep2.setHandleTime(currentDate);
                updateStep2.setUpdateBy(SecurityUtils.getUserId());
                updateStep2.setUpdateTime(currentDate);
                dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(updateStep2);
            } else {
                dmsFaultInstanceActivity.setRepairInstanceId(dmsBillsFaultInstance.getRepairInstanceId());
                // 已废弃审批流功能 - 设置固定值或注释
                // dmsFaultInstanceActivity.setProcessActivityId(WfConstants.WF_BILLS_FAULT_INSTANCE_PROCESS_ACTIVITY_SECOND_ID);
                dmsFaultInstanceActivity.setProcessActivityId(2L); // 临时设置固定值
                dmsFaultInstanceActivity.setDeviceId(dmsBillsFaultInstance.getDeviceId());
                dmsFaultInstanceActivity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_EXECUTING);
                dmsFaultInstanceActivity.setProcessStepOrder(2L);
                dmsFaultInstanceActivity.setStartTime(currentDate);
                dmsFaultInstanceActivity.setHandleUserId(SecurityUtils.getUserId());
                dmsFaultInstanceActivity.setHandleBy(userName);
                dmsFaultInstanceActivity.setHandleTime(currentDate);
                dmsFaultInstanceActivity.setCreateBy(SecurityUtils.getUserId());
                dmsFaultInstanceActivity.setCreateTime(currentDate);
                dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(dmsFaultInstanceActivity);
            }

            DmsFaultInstanceActivity firstInstanceActivity = new DmsFaultInstanceActivity();
            firstInstanceActivity.setInstanceActivityId(dmsBillsFaultInstance.getInstanceActivityId());
            firstInstanceActivity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_FINISH);
            firstInstanceActivity.setEndTime(currentDate);

            dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(firstInstanceActivity);

        } else {//维修中

            dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(dmsFaultInstanceActivity);
        }

        return 1;
    }

    /**
     * 指定派工：为某工单的第2步设置执行人，状态置为待接取；若不存在第2步则创建
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int dispatchRepair(DmsFaultInstanceActivity dmsFaultInstanceActivity) {
        if (dmsFaultInstanceActivity == null || dmsFaultInstanceActivity.getRepairInstanceId() == null) {
            throw new ServiceException("参数错误");
        }
        DmsBillsFaultInstance bills = dmsBillsFaultInstanceMapper
                .selectDmsBillsFaultInstanceByRepairInstanceId(dmsFaultInstanceActivity.getRepairInstanceId());
        if (bills == null) {
            throw new ServiceException("工单不存在");
        }
        if (DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_FINISH.equals(bills.getBillsStatus())) {
            throw new ServiceException("工单已完成，无法派工");
        }

        Date now = new Date();
        String userName = SecurityUtils.getLoginUser()==null ? SecurityUtils.getUsername() :SecurityUtils.getLoginUser().getUser().getNickName();
        Long handleUserId = dmsFaultInstanceActivity.getHandleUserId();
        String handleBy = dmsFaultInstanceActivity.getHandleBy();
        if (handleUserId == null) {
            handleUserId = SecurityUtils.getUserId();
        }
        if (StringUtils.isBlank(handleBy)) {
            handleBy = userName;
        }

        // 查找第2步
        DmsFaultInstanceActivity query = new DmsFaultInstanceActivity();
        query.setRepairInstanceId(bills.getRepairInstanceId());
        query.setProcessStepOrder(2L);
        List<DmsFaultInstanceActivity> step2List = dmsFaultInstanceActivityMapper.selectDmsFaultInstanceActivityList(query);
        if (!CollectionUtils.isEmpty(step2List)) {
            DmsFaultInstanceActivity exist = step2List.get(0);
            // 已在执行或已结束则不允许派工
            if (DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_EXECUTING.equals(exist.getProcessHandleStatus())
                || DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_FINISH.equals(exist.getProcessHandleStatus())) {
                throw new ServiceException("当前状态不可派工");
            }
            DmsFaultInstanceActivity update = new DmsFaultInstanceActivity();
            update.setInstanceActivityId(exist.getInstanceActivityId());
            update.setHandleUserId(handleUserId);
            update.setHandleBy(handleBy);
            update.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_TO_PICK);
            update.setUpdateBy(SecurityUtils.getUserId());
            update.setUpdateTime(now);
            dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(update);
        } else {
            // 创建第2步，待接取
            DmsFaultInstanceActivity create = new DmsFaultInstanceActivity();
            create.setRepairInstanceId(bills.getRepairInstanceId());
            create.setProcessActivityId(2L);
            create.setDeviceId(bills.getDeviceId());
            create.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_TO_PICK);
            create.setProcessStepOrder(2L);
            create.setHandleUserId(handleUserId);
            create.setHandleBy(handleBy);
            create.setCreateBy(SecurityUtils.getUserId());
            create.setCreateTime(now);
            dmsFaultInstanceActivityMapper.insertDmsFaultInstanceActivity(create);
        }
        return 1;
    }


    @Override
    public List<DmsFaultCompentsParts> getDmsPartsList(Long repairInstanceId) {
        return dmsBillsFaultInstanceMapper.getDmsPartsList(repairInstanceId);
    }

    @Override
    public List<DmsBillsFaultInstance> selectDmsBillsFaultInstanceCompletedList(DmsBillsFaultInstance dmsBillsFaultInstance) {
        return dmsBillsFaultInstanceMapper.selectDmsBillsFaultInstanceCompletedList(dmsBillsFaultInstance);
    }

    @Override
    public DmsFaultInstanceActivity selectFaults(Long repairInstanceId) {
        List<DmsFaultInstanceActivity> list = dmsBillsFaultInstanceMapper.selectFaults(repairInstanceId);
        List<DmsFaultCompentsParts> parts = dmsBillsFaultInstanceMapper.selectParts(repairInstanceId);
        DmsFaultInstanceActivity activity = new DmsFaultInstanceActivity();
        BeanUtils.copyProperties(list.get(0),activity);
//        activity.setCheckedFault(list.get(0).getCheckedFault());
        activity.setParts(parts);
        return activity;
    }

    /**
     * 完成维修
     *
     * @param dmsFaultInstanceActivity 报修工单实例节点
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int completeRepair(DmsFaultInstanceActivity dmsFaultInstanceActivity) {
        batchInsertInstanceAfterFiles(dmsFaultInstanceActivity.getFileUrls(), dmsFaultInstanceActivity.getInstanceActivityId());
        List<DmsFaultCompentsParts> parts = dmsFaultInstanceActivity.getParts();
        if (!CollectionUtils.isEmpty(parts)) {
            for (DmsFaultCompentsParts part : parts) {
                part.setFaultId(dmsFaultInstanceActivity.getRepairInstanceId());
            }
            dmsFaultInstanceActivityMapper.insertParts(parts);
        }

        DmsBillsFaultInstance dmsBillsFaultInstance = dmsBillsFaultInstanceMapper
                .selectDmsBillsFaultInstanceByRepairInstanceId(dmsFaultInstanceActivity.getRepairInstanceId());
        String dmsBillsStatus = dmsBillsFaultInstance.getBillsStatus();
        if (DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_FINISH.equals(dmsBillsStatus)) {
            throw new ServiceException("已经维修完成");
        }
        if (DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_TO_REPAIR.equals(dmsBillsStatus)) {
            throw new ServiceException("请先开始维修");
        }

        Date currentDate = new Date();
        String userName = SecurityUtils.getLoginUser() == null ? SecurityUtils.getUsername() : SecurityUtils.getLoginUser().getUser().getNickName();

        dmsBillsFaultInstance.setBillsStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_STATUS_FINISH);
        dmsBillsFaultInstance.setRealEndTime(currentDate);
        dmsBillsFaultInstance.setUpdateBy(SecurityUtils.getUserId());
        dmsBillsFaultInstance.setUpdateTime(currentDate);
        dmsBillsFaultInstanceMapper.updateDmsBillsFaultInstance(dmsBillsFaultInstance);

        dmsFaultInstanceActivity.setProcessHandleStatus(DmsConstants.DMS_BILLS_FAULT_INSTANCE_ACTIVITY_HANDLE_STATUS_FINISH);
        dmsFaultInstanceActivity.setEndTime(currentDate);
        if (StringUtils.isBlank(dmsFaultInstanceActivity.getRepairer())) {
            dmsFaultInstanceActivity.setRepairer(userName);
        }
        if (dmsFaultInstanceActivity.getHandleUserId() == null) {
            dmsFaultInstanceActivity.setHandleUserId(SecurityUtils.getUserId());
            dmsFaultInstanceActivity.setHandleBy(userName);
        }
        dmsFaultInstanceActivity.setHandleTime(currentDate);
        dmsFaultInstanceActivityMapper.updateDmsFaultInstanceActivity(dmsFaultInstanceActivity);

        return 1;
    }

    private void batchInsertInstanceFiles(List<String> fileUrls, Long instanceActivityId) {
        if (CollectionUtils.isEmpty(fileUrls) || instanceActivityId == null) {
            return;
        }
        List<DmsInstanceFile> dmsInstanceFiles = new ArrayList<>(fileUrls.size());
        for (String fileUrl : fileUrls) {
            if (StringUtils.isBlank(fileUrl)) {
                continue;
            }
            DmsInstanceFile dmsInstanceFile = new DmsInstanceFile();
            dmsInstanceFile.setTargetId(instanceActivityId);
            dmsInstanceFile.setTargetType(DmsConstants.DMS_INSTANCE_FILE_TARGET_TYPE_FAULT_INSTANCE_ACTIVITY);
            dmsInstanceFile.setFilePath(fileUrl);
            dmsInstanceFiles.add(dmsInstanceFile);
        }
        if (!dmsInstanceFiles.isEmpty()) {
            dmsInstanceFileMapper.batchDmsInstanceFile(dmsInstanceFiles);
        }
    }

    private void batchInsertInstanceAfterFiles(List<String> fileUrls, Long instanceActivityId) {
        if (CollectionUtils.isEmpty(fileUrls) || instanceActivityId == null) {
            return;
        }
        List<DmsInstanceFile> dmsInstanceFiles = new ArrayList<>(fileUrls.size());
        for (String fileUrl : fileUrls) {
            if (StringUtils.isBlank(fileUrl)) {
                continue;
            }
            DmsInstanceFile dmsInstanceFile = new DmsInstanceFile();
            dmsInstanceFile.setTargetId(instanceActivityId);
            dmsInstanceFile.setTargetType(DmsConstants.DMS_INSTANCE_FILE_TARGET_TYPE_FAULT_INSTANCE_ACTIVITY_AFTER);
            dmsInstanceFile.setFilePath(fileUrl);
            dmsInstanceFiles.add(dmsInstanceFile);
        }
        if (!dmsInstanceFiles.isEmpty()) {
            dmsInstanceFileMapper.batchDmsInstanceFile(dmsInstanceFiles);
        }
    }

    /**
     * 加载指定操作记录的所有附件（含开始/完成阶段）
     */
    private List<DmsInstanceFile> loadActivityFiles(Long instanceActivityId) {
        List<DmsInstanceFile> result = new ArrayList<>();
        if (instanceActivityId == null) {
            return result;
        }
        result.addAll(loadFilesByType(instanceActivityId, DmsConstants.DMS_INSTANCE_FILE_TARGET_TYPE_FAULT_INSTANCE_ACTIVITY));
        result.addAll(loadFilesByType(instanceActivityId, DmsConstants.DMS_INSTANCE_FILE_TARGET_TYPE_FAULT_INSTANCE_ACTIVITY_AFTER));
        return result;
    }

    private List<DmsInstanceFile> loadFilesByType(Long instanceActivityId, String targetType) {
        DmsInstanceFile query = new DmsInstanceFile();
        query.setTargetId(instanceActivityId);
        query.setTargetType(targetType);
        List<DmsInstanceFile> files = dmsInstanceFileMapper.selectDmsInstanceFileList(query);
        for (DmsInstanceFile file : files) {
            normalizeFilePath(file);
        }
        return files;
    }

    private void normalizeFilePath(DmsInstanceFile file) {
        String filePath = file.getFilePath();
        if (StringUtils.isBlank(filePath)) {
            return;
        }
        log.info("filePath1:" + filePath);
        if (!filePath.contains("7309")) {
            if (filePath.contains("https")) {
                filePath = filePath.replaceFirst("https", "http");
            }
            int index = filePath.indexOf("/statics");
            if (index > -1) {
                filePath = "http://172.16.12.100:7309" + filePath.substring(index);
            }
            log.info("filePath2:" + filePath);
            file.setUrl(filePath);
            file.setFilePath(filePath);
        } else {
            file.setUrl(filePath);
        }
    }
}
