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.TopicEnum;
import com.yeejoin.amos.boot.module.jyjc.biz.rule.InspectionEquipInfo;
import com.yeejoin.amos.boot.module.jyjc.biz.service.impl.CommonserviceImpl;
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.entity.TzBaseEnterpriseInfo;
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.eclipse.paho.client.mqttv3.MqttException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.component.emq.EmqKeeper;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
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 CommonserviceImpl commonserviceImpl;
    private final UseInfoMapper useInfoMapper;

    @Autowired
    public RuleActionHandler(EmqKeeper emqKeeper, TzBaseUnitLicenceMapper baseUnitLicenceMapper,
                             TzBaseEnterpriseInfoMapper tzBaseEnterpriseInfoMapper, CommonserviceImpl commonserviceImpl,
                             UseInfoMapper useInfoMapper) {
        this.emqKeeper = emqKeeper;
        this.baseUnitLicenceMapper = baseUnitLicenceMapper;
        this.tzBaseEnterpriseInfoMapper = tzBaseEnterpriseInfoMapper;
        this.commonserviceImpl = commonserviceImpl;
        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 {
            //获取单位许可信息
            List<TzBaseUnitLicence> unitLicenceList = getBaseUnitLicenceList(itemCode);
            List<TzBaseEnterpriseInfo> tzBaseEnterpriseInfoList = getInspectionUnitList(unitLicenceList, isMatchArea, inspectionEquipInfo.getRecord());

            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()));
    }

    private List<TzBaseEnterpriseInfo> getInspectionUnitList(List<TzBaseUnitLicence> unitLicenceList, Boolean isMatchArea, String record) {
        if (ValidationUtil.isEmpty(unitLicenceList)) {
            return commonserviceImpl.getInspectionUnitList();
        }

        //是否进行属地过滤
        String city = isMatchArea ? Optional.ofNullable(useInfoMapper.selectOne(
                Wrappers.<UseInfo>lambdaQuery().select(UseInfo::getCity)
                        .eq(UseInfo::getRecord, record))).map(UseInfo::getCity).orElse(null) : "";

        List<String> unitCodes = unitLicenceList.stream()
                .map(TzBaseUnitLicence::getUnitCode)
                .collect(Collectors.toList());

        return tzBaseEnterpriseInfoMapper.getInspectionUnitListByCode(unitCodes, city);
    }

    private void publishMqttMessage(String componentKey, Object message) throws MqttException {
        log.info("{}: {}", TopicEnum.INSPECTION_LIST_PUSH.getName(), String.format(TopicEnum.INSPECTION_LIST_PUSH.getTopic(), componentKey));
        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;
        }
    }
}

