package com.yeejoin.amos.boot.module.jg.biz.event.listener.service;

import com.google.common.collect.Sets;
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.refresh.DataRefreshEvent;
import com.yeejoin.amos.boot.module.jg.api.enums.BusinessTypeEnum;
import com.yeejoin.amos.boot.module.jg.api.mapper.CommonMapper;
import com.yeejoin.amos.boot.module.jg.biz.event.dto.CancelEquipItem;
import com.yeejoin.amos.boot.module.jg.biz.event.publisher.EventPublisher;
import com.yeejoin.amos.boot.module.jg.biz.reminder.core.event.EquipCreateOrEditEvent;
import com.yeejoin.amos.boot.module.jg.biz.service.ICommonService;
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 lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.Optional;
import java.util.Set;

@Service
@Slf4j
@RequiredArgsConstructor
public class ManageStatusDataUpdateService {

    private final EventPublisher publisher;

    private final ICommonService commonService;

    private final CommonMapper commonMapper;

    private final ESEquipmentCategory esEquipmentCategoryDao;

    private final IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;

    private final IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;

    @Transactional(rollbackFor = Exception.class)
    public void cancelAndGrade(CancelEquipItem cancelEquipItem) {
        // 1.设备、气瓶、管道纳管状态处理
        cancelEquipItem.getRecords().forEach(this::cancelAndGrade);
        // 2.评分级别更新
        castEvent2EquipEditEvent(cancelEquipItem);
    }

    /**
     * 处理单个设备纳管状态
     *
     * @param record 设备唯一标识
     */
    public void cancelAndGrade(String record) {
        // 查询使该设备变为已纳管的业务的数量 [> 0,则纳管状态不需要更新][< =0,则纳管状态需要更新]
        Integer inUsedNum = commonMapper.countEquipInUseTimesForDiscard(record);
        // [< =0,则纳管状态需要更新]
        if (inUsedNum == 0) {
            try {
                // 更新已纳管为未纳管 - 数据库
                updateEquipData(idxBizJgUseInfoService, record, idxBizJgRegisterInfoService, esEquipmentCategoryDao);
            } catch (Exception e) {
                log.error("设备cancelAndGrade异常:{}", e.getMessage());
            }
        }
    }

    /**
     * 处理单个设备纳管状态
     *
     * @param record 设备唯一标识
     */
    @Transactional(rollbackFor = Exception.class)
    public void dealDataAndAsyncEs(String record) {
        // 查询使该设备变为已纳管的业务的数量 [> 0,则纳管状态不需要更新][< =0,则纳管状态需要更新]
        Integer inUsedNum = commonMapper.countEquipInUseTimesForDiscard(record);
        // [< =0,则纳管状态需要更新]
        if (inUsedNum == 0) {
            try {
                updateEquipData(idxBizJgUseInfoService, record, idxBizJgRegisterInfoService, esEquipmentCategoryDao);
                // 发送数据刷新消息
            } catch (Exception e) {
                log.error("设备dealDataAndAsyncEs异常:{}", e.getMessage());
            }
        }
        publisher.publish(new DataRefreshEvent(this, Collections.singletonList(record), DataRefreshEvent.DataType.equipment.name(), DataRefreshEvent.Operation.UPDATE));
    }

    private void updateEquipData(IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService, String record, IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService, ESEquipmentCategory esEquipmentCategoryDao) {
        // 更新已纳管为未纳管 - 数据库
        idxBizJgUseInfoService.lambdaUpdate()
                .eq(IdxBizJgUseInfo::getRecord, record)
                .set(IdxBizJgUseInfo::getIsIntoManagement, false)
                .update();

        // 清除系统自动生成的设备代码`equCode`
        boolean isRegisterUpdated = idxBizJgRegisterInfoService.lambdaUpdate()
                .eq(IdxBizJgRegisterInfo::getRecord, record)
                .eq(IdxBizJgRegisterInfo::getEquCodeType, "2")
                .set(IdxBizJgRegisterInfo::getEquCode, null)
                .update();

        // 同步修改ES数据
        Optional<ESEquipmentCategoryDto> optional = esEquipmentCategoryDao.findById(record);
        optional.ifPresent(esEquipmentCategoryDto -> {
            esEquipmentCategoryDto.setIS_INTO_MANAGEMENT(false);
            if (isRegisterUpdated) {
                esEquipmentCategoryDto.setEQU_CODE(null);
            }
            esEquipmentCategoryDao.save(esEquipmentCategoryDto);
        });
    }


    private void castEvent2EquipEditEvent(CancelEquipItem cancelEquipItem) {
        Set<String> projectContraptionIds = cancelEquipItem.getProjectContraptionIds();
        if (projectContraptionIds != null && !projectContraptionIds.isEmpty()) {
            publisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_PROJECT.name(), projectContraptionIds, EquipCreateOrEditEvent.EquipType.project));
        } else {
            publisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), Sets.newHashSet(cancelEquipItem.getRecords()), EquipCreateOrEditEvent.EquipType.equip));
        }
    }
}
