package org.jeecg.modules.device.service.impl;

import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.jeecg.common.system.vo.DictModel;
import org.jeecg.common.system.vo.LoginUser;
import org.jeecg.common.util.DateUtils;
import org.jeecg.modules.device.entity.BuDevice;
import org.jeecg.modules.device.entity.DeviceBreakdownDossier;
import org.jeecg.modules.device.entity.DeviceBreakdownReport;
import org.jeecg.modules.device.entity.Part;
import org.jeecg.modules.device.mapper.BuDeviceMapper;
import org.jeecg.modules.device.mapper.DeviceBreakdownDossierMapper;
import org.jeecg.modules.device.mapper.DeviceBreakdownReportMapper;
import org.jeecg.modules.device.mapper.PartMapper;
import org.jeecg.modules.device.service.IDeviceBreakdownReportService;
import org.jeecg.modules.plan.entity.Plan;
import org.jeecg.modules.plan.mapper.PlanMapper;
import org.jeecg.modules.system.service.ISysDictService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.ZoneId;
import java.util.List;

/**
 * @Description: 设备故障报修
 * @Author: jeecg-boot
 * @Date:   2025-03-03
 * @Version: V1.0
 */
@Service
public class DeviceBreakdownReportServiceImpl extends ServiceImpl<DeviceBreakdownReportMapper, DeviceBreakdownReport> implements IDeviceBreakdownReportService {

    @Autowired
    private PlanMapper planMapper;
    @Autowired
    private BuDeviceMapper buDeviceMapper;
    @Autowired
    private PartMapper partMapper;
    @Autowired
    private DeviceBreakdownDossierMapper deviceBreakdownDossierMapper;
    @Autowired
    private BuDeviceMapper deviceMapper;

    @Autowired
    private ISysDictService sysDictService;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean aduit(DeviceBreakdownReport record) {
        // 审批通过自动创建维修的检修计划
        if(record.getStatus() == 1) {
            createTempPlan(record);
        }

        //获取登录用户信息
        LoginUser sysUser = (LoginUser) SecurityUtils.getSubject().getPrincipal();
        record.setAduitBy(sysUser.getId());
        record.setAduitTime(DateUtils.getDate());
        baseMapper.updateById(record);

        //查询
        DeviceBreakdownReport fullRecord = baseMapper.selectById(record.getId());
        //根据故障报修创建知识库
        createDossier(fullRecord);
        return true;
    }

    private void createTempPlan(DeviceBreakdownReport record) {
        LocalDate localDate = LocalDate.now(ZoneId.of("Asia/Shanghai"));
        Plan plan = new Plan(record.getDeviceId(), -1,// 检修规程默认未维修规程
                localDate,// 检修作业日期
                localDate.getDayOfWeek().getValue(),// 获取数字形式(1-7，周一是1，周日是7)
                1);
        planMapper.insert(plan);
        // 故障保修通过之后，自动创建维修计划，根据需要放开是否需要自动创建工单
//        WorkOrder workOrder = new WorkOrder();
//        workOrder.setDeviceId(plan.getDeviceId());
//        workOrder.setPlanId(plan.getId());
//        workOrder.setModelType(plan.getRapairRange());
//        workOrder.setStatus(0);
//        workOrderMapper.insert(workOrder);
    }

    /**
     * 根据故障报修创建知识库
     * @param report
     */
    private void createDossier(DeviceBreakdownReport report) {
        BuDevice device = buDeviceMapper.selectById(report.getDeviceId());

        DeviceBreakdownDossier dossier = new DeviceBreakdownDossier();
        dossier.setDeviceTypeId(device.getDeviceTypeId());

        if(StringUtils.isNotBlank(report.getDepartId())) {
            //如果存在部件ID，则添加部件类型信息
            Part part = partMapper.selectById(report.getDepartId());
            dossier.setDepartTypeId(part.getType());
        }

        dossier.setBreakdownType(report.getBreakdownType());
        dossier.setDescription(report.getDescription()+report.getBreakImpact());
        dossier.setReason(report.getReason());
        dossier.setSolve(report.getAduitRemark());
        deviceBreakdownDossierMapper.insert(dossier);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveBatchFromExcel(List<DeviceBreakdownReport> list) {
        if (list == null || list.isEmpty()) return;

        for (DeviceBreakdownReport report : list) {
            // 1. 设置系统字段
            report.setId(null); // 防止ID冲突
            report.setCreateBy(null);
            report.setSysOrgCode("大丰车辆段"); // 或从 token 获取

            // 2. 处理设备ID：根据设备名称或编号查询 bu_device
            String deviceId = resolveDeviceId(report.getDeviceId(), report.getDevice1Id());
            report.setDeviceId(deviceId); // 关联设备主键

            // 3. 故障来源字典转换
//            if (StringUtils.isNotBlank(report.getBreakOrigin())) {
//                String code = getDictCode("breakdown_origin", report.getBreakOrigin());
//                report.setBreakOrigin(code);
//            }

            // 4. 故障类型（归属系统）转换
//            if (ObjectUtil.isNotNull(report.getBreakdownType())) {
//                String code = getDictCode("breakdown_type", String.valueOf(report.getBreakdownType()));
//                report.setBreakdownType(StringUtils.isBlank(code) ? null : Integer.valueOf(code));
//            }

            // 5. 状态：默认已处理
            report.setStatus(1);

            // 6. 其他字段已由 @Excel 自动映射（如 description, reason, aduitRemark, aduitTime, breakImpact, breakdownId）
        }

        // 批量保存
        this.saveBatch(list, 1000);
    }

    /**
     * 根据设备名称或编号查询设备ID
     */
    private String resolveDeviceId(String deviceName, String deviceCode) {
        BuDevice device = null;
        device = deviceMapper.selectById(deviceName);
        if(device == null) {
            device = deviceMapper.selectById(deviceCode);
            if(device == null) {
                LambdaQueryWrapper<BuDevice> query = new LambdaQueryWrapper<BuDevice>();
                if (StringUtils.isNotBlank(deviceName)) {
                    query.eq(BuDevice::getDeviceName, deviceName);
                }
                if (StringUtils.isNotBlank(deviceCode)) {
                    query.or().eq(BuDevice::getDeviceCode, deviceCode);
                }
                device = deviceMapper.selectOne(query);
            }
        }
        return device != null ? device.getId() : null;
    }

    /**
     * 从字典中获取 code 值
     */
    private String getDictCode(String dictCode, String text) {
        List<DictModel> items = sysDictService.queryDictItemsByCode(dictCode);
        for (DictModel item : items) {
            if (text.equals(item.getText())) {
                return item.getValue();
            }
        }
        return null;
    }
}
