package com.yeejoin.amos.boot.module.jg.biz.handler.strategy;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
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.entity.SafetyProblemTracing;
import com.yeejoin.amos.boot.module.jg.api.enums.SafetyProblemStatusEnum;
import com.yeejoin.amos.boot.module.jg.api.enums.SafetyProblemTypeEnum;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.IdxBizJgOtherInfoServiceImpl;
import com.yeejoin.amos.boot.module.jg.biz.service.impl.SafetyProblemTracingServiceImpl;
import com.yeejoin.amos.boot.module.ymt.api.entity.IdxBizJgOtherInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.typroject.tyboot.core.foundation.utils.ValidationUtil;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;

@Component("equipmentProblemStrategy")
@RequiredArgsConstructor
@Slf4j
public class EquipmentProblemStrategy implements ProblemHandleStrategy {

    private final SafetyProblemTracingServiceImpl safetyProblemTracingService;
    private final IdxBizJgOtherInfoServiceImpl idxBizJgOtherInfoService;
    private final ESEquipmentCategory esEquipmentCategory;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void handleProblem(JSONArray jsonArray, SafetyProblemTypeEnum problemTypeEnum) {
        if (ValidationUtil.isEmpty(jsonArray)) {
            return;
        }
        log.info("安全追溯-设备问题处理接收数据：---> {}", jsonArray);
        List<String> equipRecords = jsonArray.stream()
                .map(obj -> JSONObject.parseObject(obj.toString()).getString("record"))
                .collect(Collectors.toList());
        if (ValidationUtil.isEmpty(equipRecords)) {
            return;
        }
        log.info("安全追溯-设备问题处理设备record：---> {}", equipRecords);

        // 更新问题状态为已处理
        safetyProblemTracingService.lambdaUpdate()
                .set(SafetyProblemTracing::getProblemStatusCode, SafetyProblemStatusEnum.HANDLED.getCode())
                .set(SafetyProblemTracing::getProblemStatus, SafetyProblemStatusEnum.HANDLED.getName())
                .in(SafetyProblemTracing::getSourceId, equipRecords)
                .eq(SafetyProblemTracing::getProblemTypeCode, problemTypeEnum.getProblemTypeCode())
                .eq(SafetyProblemTracing::getProblemStatusCode, SafetyProblemStatusEnum.UNHANDLED.getCode())
                .update();

        // 查询仍存在未处理问题的设备
        Set<String> problemEquipIds = safetyProblemTracingService.lambdaQuery()
                .select(SafetyProblemTracing::getSourceId)
                .in(SafetyProblemTracing::getSourceId, equipRecords)
                .eq(SafetyProblemTracing::getProblemStatusCode, SafetyProblemStatusEnum.UNHANDLED.getCode())
                .list().stream().map(SafetyProblemTracing::getSourceId).collect(Collectors.toCollection(HashSet::new));

        // 确定无未处理问题的设备列表
        List<String> resolvedRecords = equipRecords.stream()
                .filter(record -> !problemEquipIds.contains(record))
                .collect(Collectors.toCollection(ArrayList::new));

        // 更新无未处理问题的设备状态
        if (!ValidationUtil.isEmpty(resolvedRecords)) {
            log.info("可更新状态的设备record：---> {}", resolvedRecords);
            updateOtherTableAndES(resolvedRecords);
        }

        log.info("安全追溯-设备问题处理完成！");
    }

    /**
     * 更新Other表和ES状态（提取公共方法）
     */
    private void updateOtherTableAndES(List<String> records) {
        // 更新Other表
        idxBizJgOtherInfoService.lambdaUpdate()
                .set(IdxBizJgOtherInfo::getStatus, SafetyProblemStatusEnum.HANDLED.getCode())
                .in(IdxBizJgOtherInfo::getRecord, records)
                .update();

        // 更新ES状态（添加异常处理）
        try {
            Iterable<ESEquipmentCategoryDto> esEquipmentIter = esEquipmentCategory.findAllById(records);
            esEquipmentIter.forEach(dto ->
                    dto.setProblemStatus(SafetyProblemStatusEnum.HANDLED.getCode()));
            esEquipmentCategory.saveAll(esEquipmentIter);
            log.info("ES状态更新成功，记录数：{}", records.size());
        } catch (Exception e) {
            log.error("ES状态更新失败，设备record：{}，错误原因：{}", records, e.getMessage(), e);
        }
    }

}

