package com.aucma.dms.service.impl;

import com.aucma.common.utils.DateUtils;
import com.aucma.common.utils.SecurityUtils;
import com.aucma.common.utils.uuid.Seq;
import com.aucma.dms.domain.*;
import com.aucma.dms.mapper.*;
import com.aucma.dms.service.IDmsDispatchPlanService;
import com.aucma.dms.service.IDmsRepairRecordService;
import com.aucma.dms.service.IDmsRepairWorkOrderService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
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.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 维修工单Service业务层处理
 * 
 * @author Cascade AI
 * @date 2025-01-10
 */
@Service
public class DmsRepairWorkOrderServiceImpl implements IDmsRepairWorkOrderService {
    
    private static final Logger log = LoggerFactory.getLogger(DmsRepairWorkOrderServiceImpl.class);
    
    @Autowired
    private DmsRepairWorkOrderMapper dmsRepairWorkOrderMapper;
    
    @Autowired
    private DmsRepairProjectMapper dmsRepairProjectMapper;
    
    @Autowired
    private DmsRepairMaterialMapper dmsRepairMaterialMapper;
    
    @Autowired
    private DmsBillsFaultInstanceMapper dmsBillsFaultInstanceMapper;
    
    @Autowired
    private IDmsDispatchPlanService dmsDispatchPlanService;
    
    @Autowired
    private IDmsRepairRecordService dmsRepairRecordService;

    /**
     * 查询维修工单
     * 
     * @param workOrderId 维修工单主键
     * @return 维修工单
     */
    @Override
    public DmsRepairWorkOrder selectDmsRepairWorkOrderByWorkOrderId(Long workOrderId) {
        DmsRepairWorkOrder workOrder = dmsRepairWorkOrderMapper.selectDmsRepairWorkOrderByWorkOrderId(workOrderId);
        if (workOrder != null) {
            // 查询维修工程明细
            DmsRepairProject projectQuery = new DmsRepairProject();
            projectQuery.setWorkOrderId(workOrderId);
            List<DmsRepairProject> projects = dmsRepairProjectMapper.selectDmsRepairProjectList(projectQuery);
            workOrder.setRepairProjects(projects);
            workOrder.setProjectCount(projects != null ? projects.size() : 0);
            
            // 查询维修材料明细
            DmsRepairMaterial materialQuery = new DmsRepairMaterial();
            materialQuery.setWorkOrderId(workOrderId);
            List<DmsRepairMaterial> materials = dmsRepairMaterialMapper.selectDmsRepairMaterialList(materialQuery);
            workOrder.setRepairMaterials(materials);
            workOrder.setMaterialCount(materials != null ? materials.size() : 0);
        }
        return workOrder;
    }

    /**
     * 查询维修工单列表
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 维修工单
     */
    @Override
    public List<DmsRepairWorkOrder> selectDmsRepairWorkOrderList(DmsRepairWorkOrder dmsRepairWorkOrder) {
        List<DmsRepairWorkOrder> list = dmsRepairWorkOrderMapper.selectDmsRepairWorkOrderList(dmsRepairWorkOrder);
        // 填充工程数和材料数
        if (!CollectionUtils.isEmpty(list)) {
            for (DmsRepairWorkOrder workOrder : list) {
                DmsRepairProject projectQuery = new DmsRepairProject();
                projectQuery.setWorkOrderId(workOrder.getWorkOrderId());
                int projectCount = dmsRepairProjectMapper.selectDmsRepairProjectList(projectQuery).size();
                workOrder.setProjectCount(projectCount);
                
                DmsRepairMaterial materialQuery = new DmsRepairMaterial();
                materialQuery.setWorkOrderId(workOrder.getWorkOrderId());
                int materialCount = dmsRepairMaterialMapper.selectDmsRepairMaterialList(materialQuery).size();
                workOrder.setMaterialCount(materialCount);
            }
        }
        return list;
    }

    /**
     * 新增维修工单
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int insertDmsRepairWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder) {
        // 生成工单编号
        if (dmsRepairWorkOrder.getWorkOrderCode() == null || dmsRepairWorkOrder.getWorkOrderCode().isEmpty()) {
            dmsRepairWorkOrder.setWorkOrderCode(Seq.getId(Seq.dmsBillsFaultInstanceSeqType, "WO"));
        }
        
        // 设置默认值
        if (dmsRepairWorkOrder.getOrderStatus() == null) {
            dmsRepairWorkOrder.setOrderStatus("0"); // 待派工
        }
        if (dmsRepairWorkOrder.getApproveStatus() == null) {
            dmsRepairWorkOrder.setApproveStatus("0"); // 待审批
        }
        if (dmsRepairWorkOrder.getIsFlag() == null) {
            dmsRepairWorkOrder.setIsFlag("1");
        }
        
        dmsRepairWorkOrder.setCreateTime(DateUtils.getNowDate());
        dmsRepairWorkOrder.setCreateBy(SecurityUtils.getUserId());
        
        // 插入主表
        int rows = dmsRepairWorkOrderMapper.insertDmsRepairWorkOrder(dmsRepairWorkOrder);
        
        // 插入维修工程明细
        insertRepairProjects(dmsRepairWorkOrder);
        
        // 插入维修材料明细
        insertRepairMaterials(dmsRepairWorkOrder);
        
        // 【断点1修复】如果关联了故障报修，更新故障报修状态为“已创建工单”
        if (dmsRepairWorkOrder.getFaultInstanceId() != null) {
            updateFaultInstanceStatus(dmsRepairWorkOrder.getFaultInstanceId(), "1"); // 1-维修中
            log.info("维修工单[{}]关联故障报修[{}]，已更新故障报修状态", 
                dmsRepairWorkOrder.getWorkOrderCode(), dmsRepairWorkOrder.getFaultInstanceId());
        }
        
        return rows;
    }

    /**
     * 修改维修工单
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int updateDmsRepairWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder) {
        dmsRepairWorkOrder.setUpdateTime(DateUtils.getNowDate());
        dmsRepairWorkOrder.setUpdateBy(SecurityUtils.getUserId());
        
        // 删除原有子表数据
        dmsRepairProjectMapper.deleteDmsRepairProjectByWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        dmsRepairMaterialMapper.deleteDmsRepairMaterialByWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        
        // 重新插入子表数据
        insertRepairProjects(dmsRepairWorkOrder);
        insertRepairMaterials(dmsRepairWorkOrder);
        
        // 更新主表
        return dmsRepairWorkOrderMapper.updateDmsRepairWorkOrder(dmsRepairWorkOrder);
    }

    /**
     * 批量删除维修工单
     * 
     * @param workOrderIds 需要删除的维修工单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDmsRepairWorkOrderByWorkOrderIds(Long[] workOrderIds) {
        // 删除子表数据
        for (Long workOrderId : workOrderIds) {
            dmsRepairProjectMapper.deleteDmsRepairProjectByWorkOrderId(workOrderId);
            dmsRepairMaterialMapper.deleteDmsRepairMaterialByWorkOrderId(workOrderId);
        }
        return dmsRepairWorkOrderMapper.deleteDmsRepairWorkOrderByWorkOrderIds(workOrderIds);
    }

    /**
     * 删除维修工单信息
     * 
     * @param workOrderId 维修工单主键
     * @return 结果
     */
    @Transactional
    @Override
    public int deleteDmsRepairWorkOrderByWorkOrderId(Long workOrderId) {
        // 删除子表数据
        dmsRepairProjectMapper.deleteDmsRepairProjectByWorkOrderId(workOrderId);
        dmsRepairMaterialMapper.deleteDmsRepairMaterialByWorkOrderId(workOrderId);
        return dmsRepairWorkOrderMapper.deleteDmsRepairWorkOrderByWorkOrderId(workOrderId);
    }

    /**
     * 派工
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int dispatchWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder) {
        DmsRepairWorkOrder updateEntity = new DmsRepairWorkOrder();
        updateEntity.setWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        updateEntity.setExecutorId(dmsRepairWorkOrder.getExecutorId());
        updateEntity.setExecutorName(dmsRepairWorkOrder.getExecutorName());
        updateEntity.setOrderStatus("1"); // 已派工
        updateEntity.setUpdateTime(DateUtils.getNowDate());
        updateEntity.setUpdateBy(SecurityUtils.getUserId());
        
        int rows = dmsRepairWorkOrderMapper.updateDmsRepairWorkOrder(updateEntity);
        
        // 【断点2修复】自动创建派工计划
        DmsRepairWorkOrder workOrder = dmsRepairWorkOrderMapper.selectDmsRepairWorkOrderByWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        if (workOrder != null) {
            createDispatchPlanFromWorkOrder(workOrder, dmsRepairWorkOrder.getExecutorId(), dmsRepairWorkOrder.getExecutorName());
            log.info("维修工单[{}]派工成功，已自动创建派工计划", workOrder.getWorkOrderCode());
        }
        
        return rows;
    }

    /**
     * 开始维修
     * 
     * @param workOrderId 维修工单ID
     * @return 结果
     */
    @Override
    public int startWorkOrder(Long workOrderId) {
        DmsRepairWorkOrder updateEntity = new DmsRepairWorkOrder();
        updateEntity.setWorkOrderId(workOrderId);
        updateEntity.setOrderStatus("2"); // 维修中
        updateEntity.setActualStartTime(new Date());
        updateEntity.setUpdateTime(DateUtils.getNowDate());
        updateEntity.setUpdateBy(SecurityUtils.getUserId());
        
        return dmsRepairWorkOrderMapper.updateDmsRepairWorkOrder(updateEntity);
    }

    /**
     * 完成维修
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 结果
     */
    @Transactional
    @Override
    public int completeWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder) {
        // 查询完整工单信息
        DmsRepairWorkOrder workOrder = dmsRepairWorkOrderMapper.selectDmsRepairWorkOrderByWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        
        DmsRepairWorkOrder updateEntity = new DmsRepairWorkOrder();
        updateEntity.setWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        updateEntity.setOrderStatus("3"); // 已完成
        updateEntity.setActualEndTime(new Date());
        updateEntity.setRepairResult(dmsRepairWorkOrder.getRepairResult());
        updateEntity.setActualCost(dmsRepairWorkOrder.getActualCost());
        updateEntity.setRepairHours(dmsRepairWorkOrder.getRepairHours());
        updateEntity.setUpdateTime(DateUtils.getNowDate());
        updateEntity.setUpdateBy(SecurityUtils.getUserId());
        
        int rows = dmsRepairWorkOrderMapper.updateDmsRepairWorkOrder(updateEntity);
        
        // 【断点3修复】自动创建维修记录
        if (workOrder != null) {
            createRepairRecordFromWorkOrder(workOrder, dmsRepairWorkOrder);
            log.info("维修工单[{}]完成，已自动创建维修记录", workOrder.getWorkOrderCode());
            
            // 如果关联了故障报修，更新故障报修状态为“已完成”
            if (workOrder.getFaultInstanceId() != null) {
                updateFaultInstanceStatus(workOrder.getFaultInstanceId(), "2"); // 2-维修完成
                log.info("维修工单[{}]完成，已更新关联故障报修[{}]状态", 
                    workOrder.getWorkOrderCode(), workOrder.getFaultInstanceId());
            }
        }
        
        return rows;
    }

    /**
     * 审批
     * 
     * @param dmsRepairWorkOrder 维修工单
     * @return 结果
     */
    @Override
    public int approveWorkOrder(DmsRepairWorkOrder dmsRepairWorkOrder) {
        DmsRepairWorkOrder updateEntity = new DmsRepairWorkOrder();
        updateEntity.setWorkOrderId(dmsRepairWorkOrder.getWorkOrderId());
        updateEntity.setApproveStatus(dmsRepairWorkOrder.getApproveStatus());
        updateEntity.setApprover(SecurityUtils.getUsername());
        updateEntity.setApproveTime(new Date());
        updateEntity.setApproveRemark(dmsRepairWorkOrder.getApproveRemark());
        updateEntity.setUpdateTime(DateUtils.getNowDate());
        updateEntity.setUpdateBy(SecurityUtils.getUserId());
        
        return dmsRepairWorkOrderMapper.updateDmsRepairWorkOrder(updateEntity);
    }

    /**
     * 插入维修工程明细
     */
    private void insertRepairProjects(DmsRepairWorkOrder workOrder) {
        List<DmsRepairProject> projects = workOrder.getRepairProjects();
        if (!CollectionUtils.isEmpty(projects)) {
            for (DmsRepairProject project : projects) {
                project.setWorkOrderId(workOrder.getWorkOrderId());
                project.setCreateTime(DateUtils.getNowDate());
                project.setCreateBy(SecurityUtils.getUserId());
                dmsRepairProjectMapper.insertDmsRepairProject(project);
            }
        }
    }

    /**
     * 插入维修材料明细
     */
    private void insertRepairMaterials(DmsRepairWorkOrder workOrder) {
        List<DmsRepairMaterial> materials = workOrder.getRepairMaterials();
        if (!CollectionUtils.isEmpty(materials)) {
            for (DmsRepairMaterial material : materials) {
                material.setWorkOrderId(workOrder.getWorkOrderId());
                material.setCreateTime(DateUtils.getNowDate());
                material.setCreateBy(SecurityUtils.getUserId());
                dmsRepairMaterialMapper.insertDmsRepairMaterial(material);
            }
        }
    }
    
    // ==================== 业务流程闭环辅助方法 ====================
    
    /**
     * 【断点1】更新故障报修状态
     * 
     * @param faultInstanceId 故障报修ID
     * @param billsStatus 状态：0-待维修 1-维修中 2-维修完成
     */
    private void updateFaultInstanceStatus(Long faultInstanceId, String billsStatus) {
        try {
            DmsBillsFaultInstance updateEntity = new DmsBillsFaultInstance();
            updateEntity.setRepairInstanceId(faultInstanceId);
            updateEntity.setBillsStatus(billsStatus);
            updateEntity.setUpdateTime(DateUtils.getNowDate());
            updateEntity.setUpdateBy(SecurityUtils.getUserId());
            dmsBillsFaultInstanceMapper.updateDmsBillsFaultInstance(updateEntity);
        } catch (Exception e) {
            log.error("更新故障报修[{}]状态失败: {}", faultInstanceId, e.getMessage());
        }
    }
    
    /**
     * 【断点2】根据维修工单自动创建派工计划
     * 
     * @param workOrder 维修工单
     * @param executorId 执行人ID
     * @param executorName 执行人姓名
     */
    private void createDispatchPlanFromWorkOrder(DmsRepairWorkOrder workOrder, Long executorId, String executorName) {
        try {
            DmsDispatchPlan dispatchPlan = new DmsDispatchPlan();
            // 关联工单信息
            dispatchPlan.setWorkOrderId(workOrder.getWorkOrderId());
            dispatchPlan.setWorkOrderCode(workOrder.getWorkOrderCode());
            // 设备信息
            dispatchPlan.setDeviceId(workOrder.getDeviceId());
            dispatchPlan.setDeviceCode(workOrder.getDeviceCode());
            dispatchPlan.setDeviceName(workOrder.getDeviceName());
            // 派工类型：单人派工
            dispatchPlan.setDispatchType("1");
            // 执行人信息
            dispatchPlan.setExecutorId(executorId);
            dispatchPlan.setExecutorName(executorName);
            // 时间要求
            dispatchPlan.setRequireStartTime(workOrder.getPlanStartTime());
            dispatchPlan.setRequireEndTime(workOrder.getPlanEndTime());
            // 优先级
            dispatchPlan.setPriority(workOrder.getPriority());
            // 派工说明
            dispatchPlan.setDispatchNotes("由维修工单[" + workOrder.getWorkOrderCode() + "]自动生成");
            
            dmsDispatchPlanService.insertDmsDispatchPlan(dispatchPlan);
        } catch (Exception e) {
            log.error("为维修工单[{}]创建派工计划失败: {}", workOrder.getWorkOrderCode(), e.getMessage());
        }
    }
    
    /**
     * 【断点3】根据维修工单自动创建维修记录
     * 
     * @param workOrder 原始工单信息
     * @param completeInfo 完成时的信息
     */
    private void createRepairRecordFromWorkOrder(DmsRepairWorkOrder workOrder, DmsRepairWorkOrder completeInfo) {
        try {
            DmsRepairRecord repairRecord = new DmsRepairRecord();
            // 关联工单信息
            repairRecord.setWorkOrderId(workOrder.getWorkOrderId());
            repairRecord.setWorkOrderCode(workOrder.getWorkOrderCode());
            // 设备信息
            repairRecord.setDeviceId(workOrder.getDeviceId());
            repairRecord.setDeviceCode(workOrder.getDeviceCode());
            repairRecord.setDeviceName(workOrder.getDeviceName());
            // 故障信息
            repairRecord.setFaultPhenomenon(workOrder.getFaultDescription());
            // 维修人员
            repairRecord.setRepairerId(workOrder.getExecutorId());
            repairRecord.setRepairerName(workOrder.getExecutorName());
            // 维修时间
            repairRecord.setStartTime(workOrder.getActualStartTime());
            repairRecord.setEndTime(new Date());
            // 维修结果
            repairRecord.setRepairResult(completeInfo.getRepairResult());
            // 维修工时
            if (completeInfo.getRepairHours() != null) {
                repairRecord.setRepairHours(completeInfo.getRepairHours());
            }
            // 维修费用
            if (completeInfo.getActualCost() != null) {
                repairRecord.setRepairCost(completeInfo.getActualCost());
            }
            // 停机时长（如果有）
            if (workOrder.getShutdownDuration() != null) {
                repairRecord.setShutdownDuration(workOrder.getShutdownDuration().intValue());
            }
            
            dmsRepairRecordService.insertDmsRepairRecord(repairRecord);
        } catch (Exception e) {
            log.error("为维修工单[{}]创建维修记录失败: {}", workOrder.getWorkOrderCode(), e.getMessage());
        }
    }

    /**
     * 根据故障报修ID查询维修工单
     * 
     * @param faultInstanceId 故障报修ID
     * @return 维修工单
     */
    @Override
    public DmsRepairWorkOrder selectByFaultInstanceId(Long faultInstanceId) {
        return dmsRepairWorkOrderMapper.selectByFaultInstanceId(faultInstanceId);
    }
}
