package com.cf.imes.module.system.service.customplateno;

import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.cf.imes.framework.common.exception.ServiceException;
import com.cf.imes.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.cf.imes.framework.organ.core.context.OrganContextHolder;
import com.cf.imes.module.executor.api.customplateno.dto.CustomPlateNoRuleDTO;
import com.cf.imes.module.system.controller.admin.customplateno.vo.CustomPlateNoRuleResetModeReqVO;
import com.cf.imes.module.system.dal.dataobject.customplateno.CustomPlateNoSeqDO;
import com.cf.imes.module.system.dal.dataobject.systemconfig.SystemConfigDO;
import com.cf.imes.module.system.dal.mysql.customplateno.CustomPlateNoSeqMapper;
import com.cf.imes.module.system.dal.mysql.systemconfig.SystemConfigMapper;
import com.cf.imes.module.system.enums.config.SystemConfigTypeEnum;
import com.cf.imes.module.system.service.customplateno.factory.CustomPlateNoResetModeServiceFactory;
import com.cf.imes.module.system.service.customplateno.factory.service.AbstractCustomPlateNoResetServiceHandler;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import jakarta.annotation.Resource;

import java.util.List;
import java.util.Optional;

import static com.cf.imes.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.SYSTEM_CONFIG_CUSTOM_PLATE_NO_RULE_FIND;
import static com.cf.imes.module.system.enums.ErrorCodeConstants.SYSTEM_CONFIG_NOT_EXISTS;

/**
 * 自定义板编号序号服务实现类
 *
 * @author Gqr
 * @since 2024/11/15 13:54
 */
@Service
public class CustomPlateNoSeqServiceImpl implements CustomPlateNoSeqService {
    @Resource
    private CustomPlateNoSeqMapper customPlateNoSeqMapper;

    @Resource
    private SystemConfigMapper systemConfigMapper;

    @Resource
    private CustomPlateNoResetModeServiceFactory resetModeServiceFactory;

    @Override
    public CustomPlateNoSeqDO getOrgCustomPlateNoSeq() {
        return customPlateNoSeqMapper.selectOne(new LambdaQueryWrapperX<CustomPlateNoSeqDO>()
                .eq(CustomPlateNoSeqDO::getOrganId, OrganContextHolder.getOrganId()));
    }

    @Override
    public Boolean modifyOrgCustomPlateNoSeq(CustomPlateNoSeqDO seqDO) {
        return customPlateNoSeqMapper.insertOrUpdate(seqDO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateRuleResetMode(CustomPlateNoRuleResetModeReqVO reqVO) {
        // 校验配置是否存在
        Long configId = reqVO.getId();
        SystemConfigDO systemConfigDO = validateCustomPlateNoConfigExists(configId);
        // 解析规则列表，获取对应的规则项
        List<CustomPlateNoRuleDTO> customPlateNoRuleDTOS = JSON.parseArray(systemConfigDO.getSetting(), CustomPlateNoRuleDTO.class);
        Optional<CustomPlateNoRuleDTO> ruleVOOptional = customPlateNoRuleDTOS.stream().filter(r -> reqVO.getRuleCode().equals(r.getRuleCode())).findFirst();
        if (ruleVOOptional.isPresent()) {
            CustomPlateNoRuleDTO customPlateNoRuleDTO = ruleVOOptional.get();
            // 根据规则编码获取对应的复位处理器
            AbstractCustomPlateNoResetServiceHandler resetServiceHandler = resetModeServiceFactory.getResetServiceHandler(customPlateNoRuleDTO.getRuleCode());
            // 复位
            customPlateNoRuleDTO.setConfigId(systemConfigDO.getId());
            resetServiceHandler.reset(customPlateNoRuleDTO);
        } else {
            throw new ServiceException(SYSTEM_CONFIG_CUSTOM_PLATE_NO_RULE_FIND);
        }
    }

    /**
     * 校验基础配置是否存在
     *
     * @param id
     * @return
     */
    private SystemConfigDO validateCustomPlateNoConfigExists(Long id) {
        SystemConfigDO systemConfigDO = systemConfigMapper.selectOne(new LambdaQueryWrapperX<SystemConfigDO>()
                .eq(SystemConfigDO::getId, id)
                .eq(SystemConfigDO::getType, SystemConfigTypeEnum.CUSTOM_PLATE_NO.getType())
                .eq(SystemConfigDO::getOrganId, OrganContextHolder.getOrganId()));
        if (ObjectUtil.isNull(systemConfigDO)) {
            throw exception(SYSTEM_CONFIG_NOT_EXISTS);
        }
        return systemConfigDO;
    }
}