package cn.iocoder.yudao.module.mes.service.criticalcomponent;

import cn.iocoder.yudao.module.iot.dal.dataobject.devicemodelattribute.DeviceModelAttributeDO;
import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.util.validation.ValidationUtils;
import cn.iocoder.yudao.module.mes.dal.dataobject.deviceledger.DeviceLedgerDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.repairtems.RepairTemsDO;
import cn.iocoder.yudao.module.mes.dal.mysql.deviceledger.DeviceLedgerMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.repairtems.RepairTemsMapper;
import cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants;
import com.alibaba.excel.util.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import javax.validation.ConstraintViolationException;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

import cn.iocoder.yudao.module.mes.controller.admin.criticalcomponent.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.criticalcomponent.CriticalComponentDO;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;

import cn.iocoder.yudao.module.mes.dal.mysql.criticalcomponent.CriticalComponentMapper;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.iot.enums.ErrorCodeConstants.DEVICE_MODEL_ATTRIBUTE_POTIN_CODE_EXISTS;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.*;

/**
 * 设备关键件 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class CriticalComponentServiceImpl implements CriticalComponentService {

    @Resource
    private CriticalComponentMapper criticalComponentMapper;

    @Resource
    private DeviceLedgerMapper deviceLedgerMapper;

    @Resource
    private RepairTemsMapper repairTemsMapper;


    @Override
    public Long createCriticalComponent(CriticalComponentSaveReqVO createReqVO) {

        //判断编码是否唯一
        boolean exists = criticalComponentMapper.exists(
                Wrappers.<CriticalComponentDO>lambdaQuery()
                        .eq(CriticalComponentDO::getCode, createReqVO.getCode()));

        if (exists) {
            throw exception(CRITICAL_COMPONENT_CODE_EXISTS);
        }



        // 插入
        CriticalComponentDO criticalComponent = BeanUtils.toBean(createReqVO, CriticalComponentDO.class);
        criticalComponentMapper.insert(criticalComponent);
        // 返回
        return criticalComponent.getId();
    }

    @Override
    public void updateCriticalComponent(CriticalComponentSaveReqVO updateReqVO) {
        // 校验存在
        validateCriticalComponentExists(updateReqVO.getId());
        // 更新
        CriticalComponentDO updateObj = BeanUtils.toBean(updateReqVO, CriticalComponentDO.class);
        criticalComponentMapper.updateById(updateObj);
    }

    @Override
    public void deleteCriticalComponent(List<Long> ids) {

        if (CollectionUtils.isEmpty(ids)) {
            return;
        }

        // 批量校验存在性
        List<CriticalComponentDO> existList = criticalComponentMapper.selectBatchIds(ids);
        if (existList.size() != ids.size()) {
            throw exception(CRITICAL_COMPONENT_NOT_EXISTS);
        }

        // 检验设备台账引用
        validateDeviceLedgerBatchReferences(ids);

        //检验项目维护引用
        validateDvjectBatchReferences(ids);

        // 删除
        criticalComponentMapper.deleteByIds(ids);

    }

    private void validateDvjectBatchReferences(List<Long> ids) {


        boolean isExists = repairTemsMapper.exists(
                Wrappers.<RepairTemsDO>lambdaQuery()
                        .in(RepairTemsDO::getComponentId, ids));

        if (isExists){
            throw exception(CRITICAL_COMPONENT_REFERENCES);
        }


    }

    private void validateDeviceLedgerBatchReferences(List<Long> ids) {
        // 查询所有包含这些ID的记录
        List<DeviceLedgerDO> ledgers = deviceLedgerMapper.selectList(
                Wrappers.<DeviceLedgerDO>lambdaQuery()
                        .isNotNull(DeviceLedgerDO::getComponentId)
                        .select(DeviceLedgerDO::getComponentId)
        );

        if (CollectionUtils.isEmpty(ledgers)) {
            return;
        }

        // 检查每个componentId字段是否包含目标ID
        for (DeviceLedgerDO ledger : ledgers) {
            if (StringUtils.isBlank(ledger.getComponentId())) {
                continue;
            }

            // 将逗号分隔的ID转换为Set
            Set<Long> componentIds = Arrays.stream(ledger.getComponentId().split(","))
                    .map(String::trim)
                    .filter(StringUtils::isNotBlank)
                    .map(Long::valueOf)
                    .collect(Collectors.toSet());

            // 检查是否有交集
            for (Long id : ids) {
                if (componentIds.contains(id)) {
                    throw exception(CRITICAL_COMPONENT_REFERENCES);
                }
            }
        }
    }

    private void validateCriticalComponentExists(Long id) {
        if (criticalComponentMapper.selectById(id) == null) {
            throw exception(CRITICAL_COMPONENT_NOT_EXISTS);
        }
    }

    @Override
    public CriticalComponentDO getCriticalComponent(Long id) {
        return criticalComponentMapper.selectById(id);
    }

    @Override
    public PageResult<CriticalComponentDO> getCriticalComponentPage(CriticalComponentPageReqVO pageReqVO) {
        return criticalComponentMapper.selectPage(pageReqVO);
    }

    @Override
    public List<CriticalComponentDO> getCriticalComponentList() {
        return criticalComponentMapper.selectList();
    }

    @Override
    public List<CriticalComponentExcelVO> exportDeviceComponent(Long id) {
        DeviceLedgerDO deviceLedgerDO = deviceLedgerMapper.selectById(id);
        if (deviceLedgerDO == null){
            throw exception(DEVICE_LEDGER_EXISTS);
        }
        if (StringUtils.isBlank(deviceLedgerDO.getComponentId())){
            return new ArrayList<>();
        }
        // 将逗号分隔的字符串转换为Long类型的List
        List<Long> idList = Arrays.stream(deviceLedgerDO.getComponentId().split(","))
                .map(String::trim) // 去除可能存在的空格
                .map(Long::valueOf)
                .collect(Collectors.toList());

        if (idList.isEmpty()) {
            return new ArrayList<>();
        }

        // 查询关键组件信息
        List<CriticalComponentDO> componentList = criticalComponentMapper.selectList(
                Wrappers.<CriticalComponentDO>lambdaQuery()
                        .in(CriticalComponentDO::getId, idList)
                        .orderByDesc(CriticalComponentDO::getCreateTime)
        );

        return BeanUtils.toBean(componentList,CriticalComponentExcelVO.class);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public CriticalComponentImportRespVO importCriticalComponentList(List<CriticalComponentImportExcelVO> importComponents, boolean isUpdateSupport) {
        // 1. 参数校验
        if (CollUtil.isEmpty(importComponents)) {
            throw exception(ErrorCodeConstants.CRITICAL_COMPONENT_NOT_EXISTS);
        }

        // 2. 初始化返回结果
        CriticalComponentImportRespVO respVO = CriticalComponentImportRespVO.builder()
                .createCodes(new ArrayList<>())
                .updateCodes(new ArrayList<>())
                .failureCodes(new LinkedHashMap<>())
                .build();

        // 3. 遍历导入数据
        importComponents.forEach(importComponent -> {
            try {
                // 3.1 字段校验
                ValidationUtils.validate(BeanUtils.toBean(importComponent, CriticalComponentSaveReqVO.class));
            } catch (ConstraintViolationException ex) {
                respVO.getFailureCodes().put(importComponent.getCode(), ex.getMessage());
                return;
            }

            // 3.2 检查是否已存在
            CriticalComponentDO existComponent = criticalComponentMapper.selectByCode(importComponent.getCode());
            if (existComponent == null) {
                // 3.3 创建新记录
                CriticalComponentDO newComponent = BeanUtils.toBean(importComponent, CriticalComponentDO.class);
                // 设置创建时间为当前时间
                newComponent.setCreateTime(LocalDateTime.now());
                criticalComponentMapper.insert(newComponent);
                respVO.getCreateCodes().add(importComponent.getCode());
            } else if (isUpdateSupport) {
                // 3.4 更新已有记录
                CriticalComponentDO updateComponent = BeanUtils.toBean(importComponent, CriticalComponentDO.class);
                updateComponent.setId(existComponent.getId());
                // 保持原有创建时间不变
                updateComponent.setCreateTime(existComponent.getCreateTime());
                criticalComponentMapper.updateById(updateComponent);
                respVO.getUpdateCodes().add(importComponent.getCode());
            } else {
                // 3.5 已存在且不支持更新
                respVO.getFailureCodes().put(importComponent.getCode(), "该关键件已存在");
            }
        });

        return respVO;
    }

}