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.jg.api.enums.BusinessTypeEnum;
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.Optional;
import java.util.Set;

@Service
@Slf4j
@RequiredArgsConstructor
public class ManageStatusDataUpdateService {

    private final EventPublisher publisher;

    private final ICommonService commonService;

    private final ESEquipmentCategory esEquipmentCategoryDao;

    private final IdxBizJgUseInfoServiceImpl idxBizJgUseInfoService;

    private final IdxBizJgRegisterInfoServiceImpl idxBizJgRegisterInfoService;

    @Transactional(rollbackFor = Exception.class)
    public void dealData(CancelEquipItem cancelEquipItem) {
        // 设备、气瓶、管道纳管状态处理
        cancelEquipItem.getRecords().forEach(record -> {
            dealData(record, true);
        });
        // 装置评分处理
        castEvent2EquipEditEvent(cancelEquipItem.getProjectContraptionIds());
    }

    /**
     * 处理单个设备纳管状态
     *
     * @param record    设备唯一标识
     * @param isForward 是否进行转发
     */
    @Transactional(rollbackFor = Exception.class)
    public void dealData(String record, Boolean isForward) {
        log.info("开始检查设备的引用:{}", record);
        // 所有业务单据（除去作废、删除状态单据），有在引用设备的则不修改设备纳管状态
        Boolean inUsed = commonService.checkEquipIsUsed(record);
        // 无引用则进行修改纳管状态为未纳管
        if (!inUsed) {
            log.info("进行设备作废处理:{}", record);
            try {
                // 更新已纳管为未纳管 - 数据库
                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);
                });
            } catch (Exception e) {
                log.error("设备作废异常:{}", e.getMessage());
            }
        }
        if (isForward) {
            castEvent2EquipEditEvent(record);
        }
    }

    private void castEvent2EquipEditEvent(String record) {
        publisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_EQUIP.name(), Sets.newHashSet(record), EquipCreateOrEditEvent.EquipType.equip));
    }


    private void castEvent2EquipEditEvent(Set<String> projectContraptionIds) {
        if (projectContraptionIds != null && !projectContraptionIds.isEmpty()) {
            publisher.publish(new EquipCreateOrEditEvent(this, BusinessTypeEnum.JG_NEW_PROJECT.name(), projectContraptionIds, EquipCreateOrEditEvent.EquipType.project));
        }
    }
}
