package com.yeejoin.amos.boot.module.jg.biz.reminder.core.event.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.yeejoin.amos.boot.biz.common.entity.TzsBaseEntity;
import com.yeejoin.amos.boot.module.common.api.dao.ESEquipmentCategory;
import com.yeejoin.amos.boot.module.common.api.dto.ESEquipmentCategoryDto;
import com.yeejoin.amos.boot.module.common.biz.constats.Constants;
import com.yeejoin.amos.boot.module.common.biz.refresh.DataRefreshEvent;
import com.yeejoin.amos.boot.module.common.biz.service.impl.EquipmentCategoryService;
import com.yeejoin.amos.boot.module.jg.api.dto.ReminderItemDto;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.biz.event.publisher.EventPublisher;
import com.yeejoin.amos.boot.module.jg.biz.reminder.biz.factory.GradeStrategyFactory;
import com.yeejoin.amos.boot.module.jg.biz.reminder.core.event.EquipCreateOrEditEvent;
import com.yeejoin.amos.boot.module.jg.biz.reminder.core.event.service.DefaultQualityScoreUpdateService;
import com.yeejoin.amos.boot.module.jg.biz.reminder.dto.MatchItemDto;
import com.yeejoin.amos.boot.module.jg.biz.reminder.service.CommonReminderService;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgRegisterInfoServiceImpl;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgUseInfoServiceImpl;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgRegisterInfo;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgUseInfo;
import com.yeejoin.amos.boot.module.ymt.api.enums.EquipmentClassifityEnum;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.*;

@Component
@RequiredArgsConstructor
public class EquipQualityScoreUpdateService extends DefaultQualityScoreUpdateService {

    private final ESEquipmentCategory equipmentCategoryDao;

    private final IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;

    private final IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;

    private final CommonReminderService commonReminderService;

    @Value("${grade.calculation.strategy:MAX_GRADE}")
    private String activeStrategy;

    private final GradeStrategyFactory gradeStrategyFactory;

    private final EquipmentCategoryService equipmentCategoryService;

    private final EventPublisher eventPublisher;

    @Override
    public Boolean support(EquipCreateOrEditEvent.EquipType equipType) {
        return EquipCreateOrEditEvent.EquipType.equip.equals(equipType);
    }


    private Integer getReminderLevel(String bizType, String record) {
        MatchItemDto matchItemDto = MatchItemDto.builder().build();
        IdxBizJgUseInfo useInfo = getIdxBizJgUseInfo(record);
        IdxBizJgRegisterInfo registerInfo = getIdxBizJgRegisterInfo(record);
        if (ValidationUtil.isEmpty(useInfo) || ValidationUtil.isEmpty(registerInfo)) {
            return 0;
        }
        matchItemDto.setBizType(bizType);
        matchItemDto.setEquList(registerInfo.getEquList());
        matchItemDto.setEquCategory(registerInfo.getEquCategory());
        matchItemDto.setEquDefine(registerInfo.getEquDefine());
        matchItemDto.setRegType(CommonReminderService.getRegTypeByDataSource(useInfo.getDataSource()));
        matchItemDto.setIsRegister(useInfo.getIsIntoManagement() && StringUtils.isNotEmpty(registerInfo.getUseOrgCode()));
        matchItemDto.setWhetherVehicleCylinder(StringUtils.isNotEmpty(registerInfo.getWhetherVehicleCylinder()) ? registerInfo.getWhetherVehicleCylinder() : "0");
        ReminderItemDto reminderItemDto = new ReminderItemDto();
        reminderItemDto.setEquipId(record);
        reminderItemDto.setEquipNo(registerInfo.getEquCode());
        reminderItemDto.setEquipName(registerInfo.getProductName());
        reminderItemDto.setDetailData(commonReminderService.getEquipDetailByRecord(record));
        return gradeStrategyFactory.getStrategy(activeStrategy).calculateGrade(Collections.singletonList(reminderItemDto), matchItemDto);
    }

    private IdxBizJgUseInfo getIdxBizJgUseInfo(String record) {
        return idxBizJgUseInfoService.getOne(new LambdaQueryWrapper<IdxBizJgUseInfo>().eq(IdxBizJgUseInfo::getRecord, record)
                .select(IdxBizJgUseInfo::getRecord, IdxBizJgUseInfo::getIsIntoManagement, IdxBizJgUseInfo::getDataSource));
    }

    private IdxBizJgRegisterInfo getIdxBizJgRegisterInfo(String record) {
        return idxBizJgRegisterInfoService.getOne(new LambdaQueryWrapper<IdxBizJgRegisterInfo>()
                .eq(IdxBizJgRegisterInfo::getRecord, record)
                .select(TzsBaseEntity::getSequenceNbr,
                        IdxBizJgRegisterInfo::getRecord,
                        IdxBizJgRegisterInfo::getEquCategory,
                        IdxBizJgRegisterInfo::getEquDefine,
                        IdxBizJgRegisterInfo::getEquList,
                        IdxBizJgRegisterInfo::getWhetherVehicleCylinder,
                        IdxBizJgRegisterInfo::getProductName));
    }

    private void sendDataRefreshMsgEquip(List<String> records) {
        if (ValidationUtil.isEmpty(records)) {
            return;
        }
        eventPublisher.publish(new DataRefreshEvent(this, records, DataRefreshEvent.DataType.equipment.name(), DataRefreshEvent.Operation.UPDATE));
    }

    @Override
    protected Boolean shouldProcess(String bizType) {
        return BusinessTypeEnum.JG_USAGE_REGISTRATION.name().equals(bizType) ||
                BusinessTypeEnum.JG_INSTALLATION_NOTIFICATION.name().equals(bizType) ||
                BusinessTypeEnum.JG_NEW_EQUIP.name().equals(bizType) ||
                BusinessTypeEnum.JG_VEHICLE_GAS_APPLICATION.name().equals(bizType) ||
                Constants.JG_EDIT_EQUIP.equals(bizType);
    }

    @Override
    protected void doHandle(String bizType, Set<String> recordOrPIds) {
        recordOrPIds.forEach(record -> {
            Optional<ESEquipmentCategoryDto> op = equipmentCategoryDao.findById(record);
            // 压力管道不进行管道登记的计算
            if (op.isPresent() && op.get().getEQU_LIST_CODE().equals(EquipmentClassifityEnum.YLGD.getCode())) {
                return;
            }
            Integer level = this.getReminderLevel(bizType, record);
            op.ifPresent(equipmentCategory -> {
                equipmentCategory.setDataQualityScore(level);
                equipmentCategoryService.saveWithImmediateRefresh(equipmentCategory);
            });
            LambdaUpdateWrapper<IdxBizJgUseInfo> updateWrapper = new LambdaUpdateWrapper<>();
            updateWrapper.eq(IdxBizJgUseInfo::getRecord, record);
            updateWrapper.set(IdxBizJgUseInfo::getDataQualityScore, level);
            updateWrapper.set(TzsBaseEntity::getRecDate, new Date());
            idxBizJgUseInfoService.update(updateWrapper);
        });
    }

    @Override
    protected void afterHandle(Set<String> recordOrPIds) {
        // 事务提交后发送数据变更消息
        this.sendDataRefreshMsgEquip(new ArrayList<>(recordOrPIds));
    }
}
