package com.sundot.airport.equipment.service.impl;

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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sundot.airport.common.constant.Constants;
import com.sundot.airport.common.core.domain.entity.SysDept;
import com.sundot.airport.common.core.domain.entity.SysDictData;
import com.sundot.airport.common.core.domain.entity.SysUser;
import com.sundot.airport.common.core.redis.RedisSerialGenerator;
import com.sundot.airport.common.domain.BaseAttachment;
import com.sundot.airport.common.enums.BaseAttachmentSourceTypeEnum;
import com.sundot.airport.common.enums.EquipmentColorTypeEnum;
import com.sundot.airport.common.enums.EquipmentUsageStatusEnum;
import com.sundot.airport.common.exception.ServiceException;
import com.sundot.airport.common.service.IBaseAttachmentService;
import com.sundot.airport.common.utils.DateUtils;
import com.sundot.airport.common.utils.EquipmentDateUtils;
import com.sundot.airport.common.utils.SecurityUtils;
import com.sundot.airport.equipment.domain.EquipmentInspectionRecord;
import com.sundot.airport.equipment.service.IEquipmentInspectionRecordService;
import com.sundot.airport.system.domain.BasePosition;
import com.sundot.airport.system.service.IBasePositionService;
import com.sundot.airport.system.service.ISysDeptService;
import com.sundot.airport.system.service.ISysDictDataService;
import com.sundot.airport.system.service.ISysUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.sundot.airport.equipment.mapper.EquipmentLedgerMapper;
import com.sundot.airport.equipment.domain.EquipmentLedger;
import com.sundot.airport.equipment.service.IEquipmentLedgerService;
import org.springframework.transaction.annotation.Transactional;

/**
 * 设备台账Service业务层处理
 *
 * @author ruoyi
 * @date 2026-05-12
 */
@Service
public class EquipmentLedgerServiceImpl extends ServiceImpl<EquipmentLedgerMapper, EquipmentLedger> implements IEquipmentLedgerService {
    @Autowired
    private EquipmentLedgerMapper equipmentLedgerMapper;
    @Autowired
    private IEquipmentInspectionRecordService equipmentInspectionRecordService;
    @Autowired
    private IBaseAttachmentService baseAttachmentService;
    @Autowired
    private RedisSerialGenerator redisSerialGenerator;
    @Autowired
    private ISysDictDataService sysDictDataService;
    @Autowired
    private IBasePositionService basePositionService;
    @Autowired
    private ISysUserService sysUserService;
    @Autowired
    private ISysDeptService sysDeptService;

    /**
     * 查询设备台账
     *
     * @param id 设备台账主键
     * @return 设备台账
     */
    @Override
    public EquipmentLedger selectEquipmentLedgerById(Long id) {
        EquipmentLedger result = equipmentLedgerMapper.selectEquipmentLedgerById(id);
        if (ObjUtil.isNull(result)) {
            return result;
        }
        LambdaQueryWrapper<EquipmentInspectionRecord> recordQueryWrapper = new LambdaQueryWrapper<>();
        recordQueryWrapper.eq(EquipmentInspectionRecord::getSourceId, result.getId());
        List<EquipmentInspectionRecord> equipmentInspectionRecordList = equipmentInspectionRecordService.getBaseMapper().selectList(recordQueryWrapper);
        result.setEquipmentInspectionRecordList(equipmentInspectionRecordList);
        LambdaQueryWrapper<BaseAttachment> attachmentQueryWrapper = new LambdaQueryWrapper<>();
        attachmentQueryWrapper.eq(BaseAttachment::getSourceType, BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
        attachmentQueryWrapper.eq(BaseAttachment::getSourceId, result.getId());
        List<BaseAttachment> baseAttachmentList = baseAttachmentService.getBaseMapper().selectList(attachmentQueryWrapper);
        result.setBaseAttachmentList(baseAttachmentList);
        return result;
    }

    /**
     * 查询设备台账列表
     *
     * @param equipmentLedger 设备台账
     * @return 设备台账
     */
    @Override
    public List<EquipmentLedger> selectEquipmentLedgerList(EquipmentLedger equipmentLedger) {
        List<EquipmentLedger> result = equipmentLedgerMapper.selectEquipmentLedgerList(equipmentLedger);
        result.forEach(item -> {
            item.setColorType(EquipmentColorTypeEnum.COLORLESS.getCode());
            if (StrUtil.equals(EquipmentUsageStatusEnum.IN_USE.getCode(), item.getUsageStatus())) {
                if (EquipmentDateUtils.isBeforeToday(item.getNextInspectionDueDate())) {
                    item.setColorType(EquipmentColorTypeEnum.RED.getCode());
                } else if (EquipmentDateUtils.isWithinTwoWeeks(item.getNextInspectionDueDate())) {
                    item.setColorType(EquipmentColorTypeEnum.ORANGE.getCode());
                } else if (EquipmentDateUtils.isWithinOneMonth(item.getNextInspectionDueDate())) {
                    item.setColorType(EquipmentColorTypeEnum.YELLOW.getCode());
                } else {
                    item.setColorType(EquipmentColorTypeEnum.COLORLESS.getCode());
                }
            }
        });
        return result;
    }

    /**
     * 新增设备台账
     *
     * @param equipmentLedger 设备台账
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int insertEquipmentLedger(EquipmentLedger equipmentLedger) {
        EquipmentLedger temp = new EquipmentLedger();
        temp.setEquipmentSerialNumber(equipmentLedger.getEquipmentSerialNumber());
        List<EquipmentLedger> tempList = equipmentLedgerMapper.selectEquipmentLedgerList(temp);
        if (CollUtil.isNotEmpty(tempList)) {
            throw new ServiceException("该设备序列号已存在");
        }
        equipmentLedger.setCreateTime(DateUtils.getNowDate());
        equipmentLedger.setEquipmentCode(redisSerialGenerator.generate(Constants.EQUIPMENT_LEDGER));
        int result = equipmentLedgerMapper.insertEquipmentLedger(equipmentLedger);
        if (CollUtil.isNotEmpty(equipmentLedger.getEquipmentInspectionRecordList())) {
            equipmentLedger.getEquipmentInspectionRecordList().forEach(equipmentInspectionRecord -> {
                equipmentInspectionRecord.setSourceId(equipmentLedger.getId());
                equipmentInspectionRecord.setCreateBy(equipmentLedger.getCreateBy());
                equipmentInspectionRecord.setCreateTime(DateUtils.getNowDate());
                equipmentInspectionRecordService.insertEquipmentInspectionRecord(equipmentInspectionRecord);
            });
        }
        if (CollUtil.isNotEmpty(equipmentLedger.getBaseAttachmentList())) {
            equipmentLedger.getBaseAttachmentList().forEach(baseAttachment -> {
                baseAttachment.setSourceType(BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
                baseAttachment.setSourceTypeName(BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getInfo());
                baseAttachment.setSourceId(equipmentLedger.getId());
                baseAttachment.setCreateBy(equipmentLedger.getCreateBy());
                baseAttachment.setCreateTime(DateUtils.getNowDate());
                baseAttachmentService.insertBaseAttachment(baseAttachment);
            });
        }
        return result;
    }

    /**
     * 修改设备台账
     *
     * @param equipmentLedger 设备台账
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int updateEquipmentLedger(EquipmentLedger equipmentLedger) {
        equipmentLedger.setUpdateTime(DateUtils.getNowDate());
        int result = equipmentLedgerMapper.updateEquipmentLedger(equipmentLedger);
        // 删除旧数据
        LambdaQueryWrapper<EquipmentInspectionRecord> recordOldQueryWrapper = new LambdaQueryWrapper<>();
        recordOldQueryWrapper.eq(EquipmentInspectionRecord::getSourceId, equipmentLedger.getId());
        List<EquipmentInspectionRecord> equipmentInspectionRecordOldList = equipmentInspectionRecordService.getBaseMapper().selectList(recordOldQueryWrapper);
        if (CollUtil.isNotEmpty(equipmentInspectionRecordOldList)) {
            equipmentInspectionRecordService.removeBatchByIds(equipmentInspectionRecordOldList);
        }
        LambdaQueryWrapper<BaseAttachment> attachmentOldQueryWrapper = new LambdaQueryWrapper<>();
        attachmentOldQueryWrapper.eq(BaseAttachment::getSourceType, BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
        attachmentOldQueryWrapper.eq(BaseAttachment::getSourceId, equipmentLedger.getId());
        List<BaseAttachment> baseAttachmentOldList = baseAttachmentService.getBaseMapper().selectList(attachmentOldQueryWrapper);
        if (CollUtil.isNotEmpty(baseAttachmentOldList)) {
            baseAttachmentService.removeBatchByIds(baseAttachmentOldList);
        }
        // 新增新数据
        if (CollUtil.isNotEmpty(equipmentLedger.getEquipmentInspectionRecordList())) {
            equipmentLedger.getEquipmentInspectionRecordList().forEach(equipmentInspectionRecord -> {
                equipmentInspectionRecord.setId(null);
                equipmentInspectionRecord.setSourceId(equipmentLedger.getId());
                equipmentInspectionRecord.setCreateBy(equipmentLedger.getCreateBy());
                equipmentInspectionRecord.setCreateTime(DateUtils.getNowDate());
                equipmentInspectionRecord.setUpdateBy(equipmentLedger.getCreateBy());
                equipmentInspectionRecord.setUpdateTime(DateUtils.getNowDate());
                equipmentInspectionRecordService.insertEquipmentInspectionRecord(equipmentInspectionRecord);
            });
        }
        if (CollUtil.isNotEmpty(equipmentLedger.getBaseAttachmentList())) {
            equipmentLedger.getBaseAttachmentList().forEach(baseAttachment -> {
                baseAttachment.setId(null);
                baseAttachment.setSourceType(BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
                baseAttachment.setSourceTypeName(BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getInfo());
                baseAttachment.setSourceId(equipmentLedger.getId());
                baseAttachment.setCreateBy(equipmentLedger.getCreateBy());
                baseAttachment.setCreateTime(DateUtils.getNowDate());
                baseAttachment.setUpdateBy(equipmentLedger.getCreateBy());
                baseAttachment.setUpdateTime(DateUtils.getNowDate());
                baseAttachmentService.insertBaseAttachment(baseAttachment);
            });
        }
        return result;
    }

    /**
     * 批量删除设备台账
     *
     * @param ids 需要删除的设备台账主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteEquipmentLedgerByIds(Long[] ids) {
        int result = equipmentLedgerMapper.deleteEquipmentLedgerByIds(ids);
        for (Long id : ids) {
            LambdaQueryWrapper<EquipmentInspectionRecord> detailQueryWrapper = new LambdaQueryWrapper<>();
            detailQueryWrapper.eq(EquipmentInspectionRecord::getSourceId, id);
            List<EquipmentInspectionRecord> equipmentInspectionRecordList = equipmentInspectionRecordService.getBaseMapper().selectList(detailQueryWrapper);
            if (CollUtil.isNotEmpty(equipmentInspectionRecordList)) {
                equipmentInspectionRecordService.removeBatchByIds(equipmentInspectionRecordList);
            }
            LambdaQueryWrapper<BaseAttachment> attachmentQueryWrapper = new LambdaQueryWrapper<>();
            attachmentQueryWrapper.eq(BaseAttachment::getSourceType, BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
            attachmentQueryWrapper.eq(BaseAttachment::getSourceId, id);
            List<BaseAttachment> baseAttachmentList = baseAttachmentService.getBaseMapper().selectList(attachmentQueryWrapper);
            if (CollUtil.isNotEmpty(baseAttachmentList)) {
                baseAttachmentService.removeBatchByIds(baseAttachmentList);
            }
        }
        return result;
    }

    /**
     * 删除设备台账信息
     *
     * @param id 设备台账主键
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public int deleteEquipmentLedgerById(Long id) {
        int result = equipmentLedgerMapper.deleteEquipmentLedgerById(id);
        LambdaQueryWrapper<EquipmentInspectionRecord> detailQueryWrapper = new LambdaQueryWrapper<>();
        detailQueryWrapper.eq(EquipmentInspectionRecord::getSourceId, id);
        List<EquipmentInspectionRecord> equipmentInspectionRecordList = equipmentInspectionRecordService.getBaseMapper().selectList(detailQueryWrapper);
        if (CollUtil.isNotEmpty(equipmentInspectionRecordList)) {
            equipmentInspectionRecordService.removeBatchByIds(equipmentInspectionRecordList);
        }
        LambdaQueryWrapper<BaseAttachment> attachmentQueryWrapper = new LambdaQueryWrapper<>();
        attachmentQueryWrapper.eq(BaseAttachment::getSourceType, BaseAttachmentSourceTypeEnum.EQUIPMENT_LEDGER.getCode());
        attachmentQueryWrapper.eq(BaseAttachment::getSourceId, id);
        List<BaseAttachment> baseAttachmentList = baseAttachmentService.getBaseMapper().selectList(attachmentQueryWrapper);
        if (CollUtil.isNotEmpty(baseAttachmentList)) {
            baseAttachmentService.removeBatchByIds(baseAttachmentList);
        }
        return result;
    }

    /**
     * 查询定/自检到期日期已过期的设备列表
     *
     * @return 设备台账集合
     */
    @Override
    public List<EquipmentLedger> selectExpiredInspectionList() {
        return equipmentLedgerMapper.selectExpiredInspectionList();
    }

    /**
     * 查询一月内定/自检到期的设备列表
     *
     * @return 设备台账集合
     */
    @Override
    public List<EquipmentLedger> selectUpcomingInspectionList() {
        return equipmentLedgerMapper.selectUpcomingInspectionList();
    }

    /**
     * 查询两周内定/自检到期的设备列表
     *
     * @return 设备台账集合
     */
    @Override
    public List<EquipmentLedger> selectTwoWeeksUpcomingInspectionList() {
        return equipmentLedgerMapper.selectTwoWeeksUpcomingInspectionList();
    }

    /**
     * 导入设备台账数据
     *
     * @param list            数据列表
     * @param isUpdateSupport 是否更新支持，如果已存在，则进行更新数据
     * @return 结果
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public String importData(List<EquipmentLedger> list, boolean isUpdateSupport) {
        if (CollUtil.isEmpty(list)) {
            throw new ServiceException("导入设备台账数据不能为空！");
        }

        // 用户
        List<SysUser> sysUserListAll = sysUserService.selectUserAll();
        Map<String, Long> sysUserMap = sysUserListAll.stream().collect(Collectors.toMap(SysUser::getNickName, SysUser::getUserId, (oldValue, newValue) -> newValue));

        // 航站楼
        BasePosition terminlQuery = new BasePosition();
        terminlQuery.setLevel(1);
        List<BasePosition> terminlList = basePositionService.selectBasePositionList(terminlQuery);
        Map<String, String> terminlMap = terminlList.stream().collect(Collectors.toMap(BasePosition::getName, BasePosition::getCode, (oldValue, newValue) -> newValue));

        // 区域
        BasePosition regionalQuery = new BasePosition();
        regionalQuery.setLevel(2);
        List<BasePosition> regionalList = basePositionService.selectBasePositionList(regionalQuery);
        Map<String, String> regionalMap = regionalList.stream().collect(Collectors.toMap(BasePosition::getName, BasePosition::getCode, (oldValue, newValue) -> newValue));

        // 通道
        BasePosition channelQuery = new BasePosition();
        channelQuery.setLevel(3);
        List<BasePosition> channelList = basePositionService.selectBasePositionList(channelQuery);
        Map<String, String> channelMap = channelList.stream().collect(Collectors.toMap(BasePosition::getName, BasePosition::getCode, (oldValue, newValue) -> newValue));

        // 使用状态
        SysDictData equipmentUsageStatusQuery = new SysDictData();
        equipmentUsageStatusQuery.setDictType("equipment_usage_status");
        List<SysDictData> equipmentUsageStatusList = sysDictDataService.selectDictDataList(equipmentUsageStatusQuery);
        Map<String, String> equipmentUsageStatusMap = equipmentUsageStatusList.stream().collect(Collectors.toMap(SysDictData::getDictLabel, SysDictData::getDictValue));

        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();

        for (EquipmentLedger data : list) {
            // 根据名称填充ID字段
            fillIdsByName(data, sysUserMap, terminlMap, regionalMap, channelMap, equipmentUsageStatusMap);
            try {
                if (ObjUtil.isNull(data.getEquipmentSerialNumber())) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】设备序列号不能为空");
                    continue;
                }
                if (ObjUtil.isNull(data.getEquipmentName())) {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】设备名称不能为空");
                    continue;
                }

                // 查询是否已存在（根据【设备序列号】唯一）
                EquipmentLedger queryParam = new EquipmentLedger();
                queryParam.setEquipmentSerialNumber(data.getEquipmentSerialNumber());
                List<EquipmentLedger> existingList = equipmentLedgerMapper.selectEquipmentLedgerList(queryParam);

                if (CollUtil.isEmpty(existingList)) {
                    // 新增
                    data.setEquipmentCode(redisSerialGenerator.generate(Constants.EQUIPMENT_LEDGER));
                    data.setCreateTime(DateUtils.getNowDate());
                    equipmentLedgerMapper.insertEquipmentLedger(data);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】导入成功");
                } else if (isUpdateSupport) {
                    // 更新
                    EquipmentLedger old = existingList.get(0);
                    data.setId(old.getId());
                    data.setEquipmentCode(old.getEquipmentCode());
                    data.setUpdateTime(DateUtils.getNowDate());
                    equipmentLedgerMapper.updateEquipmentLedger(data);
                    successNum++;
                    successMsg.append("<br/>" + successNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】更新成功");
                } else {
                    failureNum++;
                    failureMsg.append("<br/>" + failureNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】已存在");
                }
            } catch (Exception e) {
                failureNum++;
                String msg = "<br/>" + failureNum + "、设备序列号【" + data.getEquipmentSerialNumber() + "】、设备名称【" + data.getEquipmentName() + "】导入失败：";
                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();
    }

    /**
     * 根据名称填充ID字段
     *
     * @param data 速率数据
     */
    private void fillIdsByName(EquipmentLedger data, Map<String, Long> sysUserMap, Map<String, String> terminlMap, Map<String, String> regionalMap, Map<String, String> channelMap, Map<String, String> equipmentUsageStatusMap) {
        // 定/自检小组组长
        if (ObjUtil.isNotNull(data.getInspectionTeamLeaderName())) {
            data.setInspectionTeamLeaderId(sysUserMap.get(data.getInspectionTeamLeaderName()));
        }
        // 定/自检小组组员1
        if (ObjUtil.isNotNull(data.getInspectionTeamMember1Name())) {
            data.setInspectionTeamMember1Id(sysUserMap.get(data.getInspectionTeamMember1Name()));
        }
        // 定/自检小组组员2
        if (ObjUtil.isNotNull(data.getInspectionTeamMember2Name())) {
            data.setInspectionTeamMember2Id(sysUserMap.get(data.getInspectionTeamMember2Name()));
        }
        // 航站楼
        if (ObjUtil.isNotNull(data.getTerminlName())) {
            data.setTerminlCode(terminlMap.get(data.getTerminlName()));
        }
        // 区域
        if (ObjUtil.isNotNull(data.getRegionalName())) {
            data.setRegionalCode(regionalMap.get(data.getRegionalName()));
        }
        // 通道
        if (ObjUtil.isNotNull(data.getChannelName())) {
            data.setChannelCode(channelMap.get(data.getChannelName()));
        }
    }

    /**
     * 设备台账通知
     *
     * @param equipmentLedger 设备台账
     * @return 设备台账
     */
    @Override
    public List<EquipmentLedger> notice(EquipmentLedger equipmentLedger) {
        if (ObjUtil.isNull(SecurityUtils.getDeptId())) {
            return Collections.emptyList();
        }
        SysDept sysDept = sysDeptService.selectDeptById(SecurityUtils.getDeptId());
        if (!StrUtil.equals("设备维修中心", sysDept.getDeptName())) {
            return Collections.emptyList();
        }
        return selectEquipmentLedgerList(equipmentLedger);
    }
}
