package com.xisc.pm.app.service.impl;

import com.xisc.boot.common.feign.pojo.MtUserInfo;
import com.xisc.boot.common.sys.UserClient;
import com.xisc.pm.api.dto.PmPdOperationReRequestDTO;
import com.xisc.pm.api.dto.PmPdOperationReResponseDTO;
import com.xisc.pm.app.service.PmPdOperationReService;
import com.xisc.pm.domain.entity.PmPdCcSlab;
import com.xisc.pm.domain.entity.PmPdPlate;
import com.xisc.pm.domain.entity.PmPdSlab;
import com.xisc.pm.domain.repository.PmPdCcSlabRepository;
import com.xisc.pm.domain.repository.PmPdPlateRepository;
import com.xisc.pm.domain.repository.PmPdRecRepository;
import com.xisc.pm.domain.repository.PmPdSlabRepository;
import com.xisc.pm.infra.constant.Constants;
import io.choerodon.core.domain.Page;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import io.choerodon.mybatis.util.StringUtil;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.hzero.boot.platform.lov.adapter.LovAdapter;
import org.hzero.boot.platform.lov.dto.LovValueDTO;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024/7/31 9:51
 */
@Service
public class PmPdOperationReServiceImpl implements PmPdOperationReService {

    private final PmPdRecRepository pmPdRecRepository;

    private final LovAdapter lovAdapter;

    private final PmPdCcSlabRepository pmPdCcSlabRepository;

    private final PmPdPlateRepository pmPdPlateRepository;

    private final PmPdSlabRepository pmPdSlabRepository;

    private final UserClient userClient;

    public static final String EVENT_CODE_VALUE_HP16 = "HP16";
    public static final String EVENT_CODE_VALUE_HP14 = "HP14";
    public static final String EVENT_CODE_VALUE_HP10 = "HP10";


    public PmPdOperationReServiceImpl(PmPdRecRepository pmPdRecRepository, LovAdapter lovAdapter, PmPdCcSlabRepository pmPdCcSlabRepository, PmPdPlateRepository pmPdPlateRepository, PmPdSlabRepository pmPdSlabRepository, UserClient userClient) {
        this.pmPdRecRepository = pmPdRecRepository;
        this.lovAdapter = lovAdapter;
        this.pmPdCcSlabRepository = pmPdCcSlabRepository;
        this.pmPdPlateRepository = pmPdPlateRepository;
        this.pmPdSlabRepository = pmPdSlabRepository;
        this.userClient = userClient;
    }

    @Override
    public Page<PmPdOperationReResponseDTO> list(PageRequest pageRequest, PmPdOperationReRequestDTO dto, Long tenantId) {
        Page<PmPdOperationReResponseDTO> page = PageHelper.doPageAndSort(pageRequest, () -> pmPdRecRepository.selectPdOperationRecord(dto, tenantId));
        if (CollectionUtils.isEmpty(page)) {
            return new Page<>();
        }
        // 组装数据
        assemblyData(page.getContent(), tenantId);
        return page;
    }


    @Override
    public List<PmPdOperationReResponseDTO> exportList(Long tenantId, PmPdOperationReRequestDTO dto) {
        List<PmPdOperationReResponseDTO> pmPdOperationReResponseDTOList = pmPdRecRepository.selectPdOperationRecord(dto, tenantId);
        assemblyData(pmPdOperationReResponseDTOList, tenantId);
        return pmPdOperationReResponseDTOList;
    }

    /**
     * 组装数据
     * 根据材料编号和创建者ID，查询并组装相关数据，包括材料类型、操作事件描述、自动手动标志描述等。
     *
     * @param list     操作响应结果的列表
     * @param tenantId 租户ID，用于查询特定租户的数据
     */
    private void assemblyData(List<PmPdOperationReResponseDTO> list, Long tenantId) {
        // 分别提取材料编号和创建者ID，并去重
        List<String> matNoList = list.stream().map(PmPdOperationReResponseDTO::getMatNo).distinct().collect(Collectors.toList());
        List<Long> userIdList = list.stream().map(PmPdOperationReResponseDTO::getCreateBy).distinct().collect(Collectors.toList());

        // 初始化材料映射表
        Map<String, PmPdCcSlab> pmPdCcSlabrMap = new HashMap<>(list.size());
        Map<String, PmPdPlate> pmPdPlateMap = new HashMap<>(list.size());
        Map<String, PmPdSlab> pmPdSlabMap = new HashMap<>(list.size());

        // 根据材料编号查询并组装板坯信息
        List<PmPdCcSlab> pmPdCcSlabList = pmPdCcSlabRepository.selectByCondition(Condition.builder(PmPdCcSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmPdCcSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmPdCcSlab.FIELD_VIRTUAL_SLAB_NO, matNoList))
                .build());
        if (CollectionUtils.isNotEmpty(pmPdCcSlabList)) {
            pmPdCcSlabrMap = pmPdCcSlabList.stream().collect(Collectors.toMap(PmPdCcSlab::getVirtualSlabNo, Function.identity(), (v1, v2) -> v1));
        }

        // 根据材料编号查询并组装板信息
        List<PmPdPlate> pmPdPlateList = pmPdPlateRepository.selectByCondition(Condition.builder(PmPdPlate.class)
                .andWhere(Sqls.custom().andEqualTo(PmPdPlate.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmPdPlate.FIELD_PLATE_NO, matNoList))
                .build());
        if (CollectionUtils.isNotEmpty(pmPdPlateList)) {
            pmPdPlateMap = pmPdPlateList.stream().collect(Collectors.toMap(PmPdPlate::getPlateNo, Function.identity(), (v1, v2) -> v1));
        }

        // 根据材料编号查询并组装坯料信息
        List<PmPdSlab> pmPdSlabList = pmPdSlabRepository.selectByCondition(Condition.builder(PmPdSlab.class)
                .andWhere(Sqls.custom().andEqualTo(PmPdSlab.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andIn(PmPdSlab.FIELD_VIRTUAL_SLAB_NO, matNoList))
                .build());
        if (CollectionUtils.isNotEmpty(pmPdSlabList)) {
            pmPdSlabMap = pmPdSlabList.stream().collect(Collectors.toMap(PmPdSlab::getVirtualSlabNo, Function.identity(), (v1, v2) -> v1));
        }

        // 查询组板类型和自动人工标记的值集
        List<LovValueDTO> eventCodeLovList = lovAdapter.queryLovValue(Constants.LovCode.RECORD_EVENT_CODE, tenantId);
        List<LovValueDTO> autoManualFlagLovList = lovAdapter.queryLovValue(Constants.LovCode.AUTO_MANUAL_FLAG, tenantId);
        List<LovValueDTO> formPlateModeLovList = lovAdapter.queryLovValue(Constants.LovCode.FORM_PLATE_MODE, tenantId);

        // 组装组板类型和自动手动标志的描述信息
        Map<String, String> eventCodeLovMap = new HashMap<>(eventCodeLovList.size());
        Map<String, String> autoManualFlagLovMap = new HashMap<>(autoManualFlagLovList.size());
        Map<String, String> formPlateModeLovMap = new HashMap<>(formPlateModeLovList.size());
        if (CollectionUtils.isNotEmpty(eventCodeLovList)) {
            eventCodeLovMap = eventCodeLovList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }
        if (CollectionUtils.isNotEmpty(autoManualFlagLovList)) {
            autoManualFlagLovMap = autoManualFlagLovList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }
        if (CollectionUtils.isNotEmpty(formPlateModeLovList)) {
            formPlateModeLovMap = formPlateModeLovList.stream().collect(Collectors.toMap(LovValueDTO::getValue, LovValueDTO::getMeaning));
        }


        // 查询责任人名称
        Map<Long, MtUserInfo> userInfoMap = userClient.userInfoBatchGet(tenantId, userIdList);

        // 遍历列表，根据不同的事件代码填充相应的信息
        for (PmPdOperationReResponseDTO reResponseDTO : list) {
            // 填充事件描述和自动手动标志描述
            if (!eventCodeLovMap.isEmpty()) {
                reResponseDTO.setEventCodeDesc(eventCodeLovMap.getOrDefault(reResponseDTO.getEventCode(), null));
            }
            if (!userInfoMap.isEmpty() && userInfoMap.containsKey(reResponseDTO.getCreateBy())) {
                MtUserInfo userInfo = userInfoMap.get(reResponseDTO.getCreateBy());
                reResponseDTO.setCreatedByName(Strings.concat(userInfo.getLoginName(), userInfo.getRealName()));
            }

            // 根据事件代码填充板坯、板、坯料相关信息
            // 出钢材
            if (EVENT_CODE_VALUE_HP16.equals(reResponseDTO.getEventCode())) {
                if (!pmPdCcSlabrMap.isEmpty() && pmPdCcSlabrMap.containsKey(reResponseDTO.getMatNo())) {
                    PmPdCcSlab pmPdCcSlab = pmPdCcSlabrMap.get(reResponseDTO.getMatNo());
                    reResponseDTO.setFormPlateMode(pmPdCcSlab.getFormPlateMode());
                    reResponseDTO.setAutoManualFlag(pmPdCcSlab.getAutoManualFlag());
                }
                // 余材
            } else if (EVENT_CODE_VALUE_HP14.equals(reResponseDTO.getEventCode())) {
                if (!pmPdPlateMap.isEmpty() && pmPdPlateMap.containsKey(reResponseDTO.getMatNo())) {
                    PmPdPlate pmPdPlate = pmPdPlateMap.get(reResponseDTO.getMatNo());
                    reResponseDTO.setFormPlateMode(pmPdPlate.getFormPlateMode());
                    reResponseDTO.setAutoManualFlag(pmPdPlate.getAutoManualFlag());
                }
                // 余坯
            } else if (EVENT_CODE_VALUE_HP10.equals(reResponseDTO.getEventCode())) {
                if (!pmPdSlabMap.isEmpty() && pmPdSlabMap.containsKey(reResponseDTO.getMatNo())) {
                    PmPdSlab pmPdSlab = pmPdSlabMap.get(reResponseDTO.getMatNo());
                    reResponseDTO.setFormPlateMode(pmPdSlab.getFormPlateMode());
                    reResponseDTO.setAutoManualFlag(pmPdSlab.getAutoManualFlag());
                }
            }
            // 填充自动手动标志描述
            if (!eventCodeLovMap.isEmpty() && StringUtil.isNotEmpty(reResponseDTO.getAutoManualFlag())) {
                reResponseDTO.setAutoManualFlagDesc(autoManualFlagLovMap.getOrDefault(reResponseDTO.getAutoManualFlag(), null));
            }
            if (!formPlateModeLovMap.isEmpty() && StringUtil.isNotEmpty(reResponseDTO.getFormPlateMode())) {
                reResponseDTO.setFormPlateModeDesc(formPlateModeLovMap.getOrDefault(reResponseDTO.getFormPlateMode(), null));
            }

        }
    }
}
