package com.yeejoin.amos.boot.module.jyjc.biz.action;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.yeejoin.amos.boot.module.jyjc.api.enums.LicenceTypeEnum;
import com.yeejoin.amos.boot.module.jyjc.api.enums.OpenBizTypeEnum;
import com.yeejoin.amos.boot.module.jyjc.api.enums.TopicEnum;
import com.yeejoin.amos.boot.module.jyjc.biz.rule.InspectionEquipInfo;
import com.yeejoin.amos.boot.module.ymt.api.dto.TzBaseEnterpriseInfoDto;
import com.yeejoin.amos.boot.module.ymt.api.entity.TzBaseUnitLicence;
import com.yeejoin.amos.boot.module.ymt.api.entity.UseInfo;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseEnterpriseInfoMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.TzBaseUnitLicenceMapper;
import com.yeejoin.amos.boot.module.ymt.api.mapper.UseInfoMapper;
import com.yeejoin.amos.component.rule.config.RuleConfig;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.emq.EmqKeeper;

import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author LiuLin
 * @date 2024年01月02日 15:45
 */
@Component
@Slf4j
public class RuleActionHandler {

    private final EmqKeeper emqKeeper;
    private final TzBaseUnitLicenceMapper baseUnitLicenceMapper;
    private final TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper;
    private final UseInfoMapper useInfoMapper;
    /**
     * 特殊独立的区县
     */
    private static final String[] EXCLUSION_CITY_REGIONS = {"610403", "610581"};


    public RuleActionHandler(EmqKeeper emqKeeper, TzBaseUnitLicenceMapper baseUnitLicenceMapper,
                             TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper,
                             UseInfoMapper useInfoMapper) {
        this.emqKeeper = emqKeeper;
        this.baseUnitLicenceMapper = baseUnitLicenceMapper;
        this.tzBaseEnterpriseInfoMapper = tzBaseEnterpriseInfoMapper;
        this.useInfoMapper = useInfoMapper;
    }

    /**
     * 规则回调方法
     *
     * @param bizObj      请求变量参数
     * @param itemCode    核对项目编码，多个用逗号分割
     * @param isMatchArea 是否进行属地过滤（检验检测机构的开通区域包含设备归属地市），true-过滤，false-不过滤
     */
    public void filterInspectionOrgAction(Object bizObj, String itemCode, Boolean isMatchArea) {
        InspectionEquipInfo inspectionEquipInfo = (InspectionEquipInfo) bizObj;
        try {
            // 1.获取所有的符合资质条件的单位许可信息
            List<TzBaseUnitLicence> unitLicenceList = getBaseUnitLicenceList(itemCode);
            // 2.匹配过滤机构信息,默认检验机构（目前检测没配置规则，后续检测也需要配置规则时，需要规则那回调方法新增参数，区分检验还是检测）
            List<TzBaseEnterpriseInfoDto> tzBaseEnterpriseInfoList = getInspectionUnitList(unitLicenceList, isMatchArea, inspectionEquipInfo.getRecord(), OpenBizTypeEnum.JY.getCode());

            publishMqttMessage(inspectionEquipInfo.getComponentKey(), tzBaseEnterpriseInfoList);
        } catch (MqttException e) {
            log.error("Error publishing MQTT message: {}", e.getMessage());
        }
    }

    private List<TzBaseUnitLicence> getBaseUnitLicenceList(String itemCode) {
        return baseUnitLicenceMapper.selectList(new LambdaQueryWrapper<TzBaseUnitLicence>()
                .select(TzBaseUnitLicence::getUnitCode)
                .eq(TzBaseUnitLicence::getLicenceType, LicenceTypeEnum.JY_JC.getCode())
                .in(TzBaseUnitLicence::getItemCode, Arrays.asList(itemCode.split(","))));
//                .ge(TzBaseUnitLicence::getExpiryDate, LocalDate.now()));
    }

    public List<TzBaseEnterpriseInfoDto> getInspectionUnitList(List<TzBaseUnitLicence> unitLicenceList, Boolean isMatchArea, String record, String openBizType) {
        // 是否进行属地过滤
        String areaCode = isMatchArea ? this.getArea(record) : "";
        // 所有符合单位的code
        List<String> unitCodes = unitLicenceList.stream()
                .map(TzBaseUnitLicence::getUnitCode)
                .collect(Collectors.toList());
        // 按照资质 + areaCode，进行设备单位的筛选
        List<TzBaseEnterpriseInfoDto> matchEnterpriseInfos = tzBaseEnterpriseInfoMapper.getInspectionUnitListByCode(unitCodes, areaCode, openBizType);
        if (matchEnterpriseInfos.isEmpty()) {
            log.info("按照资质、区域未匹配到对应的单位、按照地市未匹配到单位，将返回全部单位");
            return tzBaseEnterpriseInfoMapper.getInspectionUnitListByCode(null, null, openBizType);
        }
        return matchEnterpriseInfos;
    }

    private String getArea(String record) {
        UseInfo equipUseInfo = useInfoMapper.selectOne(Wrappers.<UseInfo>lambdaQuery().select(UseInfo::getCity).eq(UseInfo::getRecord, record));
        if (equipUseInfo == null) {
            return "";
        }
        // 特殊地区特殊处理，目前有韩城、杨凌,原因行政区划上是有层级的，但是业务办理时，他们与所在地市是同级别的
        if (StringUtils.isEmpty(equipUseInfo.getCity()) || StringUtils.isEmpty(equipUseInfo.getCounty())) {
            return "";
        }
        if (Arrays.asList(EXCLUSION_CITY_REGIONS).contains(equipUseInfo.getCounty())) {
            return equipUseInfo.getCounty();
        }
        return equipUseInfo.getCity();
    }

    private void publishMqttMessage(String componentKey, Object message) throws MqttException {
        log.info("报检规则推送到web主题：{}:,消息内容为：{}", String.format(TopicEnum.INSPECTION_LIST_PUSH.getTopic(), componentKey), JSON.toJSONString(message));
        try {
            emqKeeper.getMqttClient().publish(String.format(TopicEnum.INSPECTION_LIST_PUSH.getTopic(), componentKey),
                    JSON.toJSONString(message).getBytes(), RuleConfig.DEFAULT_QOS, false);
        } catch (MqttException e) {
            log.error("Error publishing MQTT message: {}", e.getMessage());
            throw e;
        }
    }
}

