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.app.service.PmProdLineSectionService;
import com.xisc.pm.domain.entity.PmProdLineSection;
import com.xisc.pm.domain.entity.PmProdLineSectionSpec;
import com.xisc.pm.domain.entity.PmProductionLine;
import com.xisc.pm.domain.repository.PmProdLineSectionRepository;
import com.xisc.pm.domain.repository.PmProdLineSectionSpecRepository;
import com.xisc.pm.domain.repository.PmProductionLineRepository;
import com.xisc.pm.infra.util.Utils;
import io.choerodon.core.domain.Page;
import io.choerodon.core.exception.CommonException;
import io.choerodon.mybatis.pagehelper.PageHelper;
import io.choerodon.mybatis.pagehelper.domain.PageRequest;
import org.apache.commons.collections.CollectionUtils;
import org.apache.logging.log4j.util.Strings;
import org.hzero.mybatis.domian.Condition;
import org.hzero.mybatis.util.Sqls;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

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

/**
 * 产线断面关系表(PmProdLineSection)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-10-10 09:19:39
 */
@Service
public class PmProdLineSectionServiceImpl implements PmProdLineSectionService {
    @Autowired
    private PmProdLineSectionRepository pmProdLineSectionRepository;

    @Autowired
    private PmProductionLineRepository pmProductionLineRepository;

    @Autowired
    private UserClient userClient;

    @Autowired
    private PmProdLineSectionSpecRepository pmProdLineSectionSpecRepository;

    @Override
    public Page<PmProdLineSection> selectList(PageRequest pageRequest, PmProdLineSection pmProdLineSection) {
        // 查询条件：产线编码，断面厚，断面宽
        Page<PmProdLineSection> page = PageHelper.doPageAndSort(pageRequest, () -> pmProdLineSectionRepository.selectByCondition(
                Condition.builder(PmProdLineSection.class)
                        .andWhere(Sqls.custom().andIn(PmProdLineSection.FIELD_PROD_LINE_ID, pmProdLineSection.getProdLineIdList(), true))
                        .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_MOLD_THICK, pmProdLineSection.getMoldThick(), true))
                        .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_MOLD_WID, pmProdLineSection.getMoldWid(), true))
                        .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_TENANT_ID, pmProdLineSection.getTenantId()))
                        .build()));
        // 未查到数据则返回
        if (CollectionUtils.isEmpty(page.getContent())) {
            return page;
        }

        // 查询产线编码和名称
        List<Long> prodLineIdList = page.getContent().stream().map(PmProdLineSection::getProdLineId).distinct().collect(Collectors.toList());
        List<PmProductionLine> pmProductionLineList = pmProductionLineRepository.selectByCondition(Condition.builder(PmProductionLine.class)
                .andWhere(Sqls.custom().andIn(PmProductionLine.FIELD_PROD_LINE_ID, prodLineIdList))
                .andWhere(Sqls.custom().andEqualTo(PmProductionLine.FIELD_TENANT_ID, pmProdLineSection.getTenantId()))
                .build());
        Map<Long, PmProductionLine> pmProductionLineMap = new HashMap<>(pmProductionLineList.size());
        if (CollectionUtils.isNotEmpty(pmProductionLineList)) {
            pmProductionLineMap = pmProductionLineList.stream().collect(Collectors.toMap(PmProductionLine::getProdLineId, Function.identity()));
        }

        // 查询用户信息
        List<Long> userIdList = page.getContent().stream().map(PmProdLineSection::getCreatedBy).distinct().collect(Collectors.toList());
        List<Long> updateByIdList = page.getContent().stream().map(PmProdLineSection::getLastUpdatedBy).distinct().collect(Collectors.toList());
        userIdList.addAll(updateByIdList);
        Map<Long, MtUserInfo> mtUserInfoMap = userClient.userInfoBatchGet(pmProdLineSection.getTenantId(), userIdList);

        // 组装参数
        for (PmProdLineSection prodLineSection : page.getContent()) {
            // 产线信息
            if (pmProductionLineMap.containsKey(prodLineSection.getProdLineId())) {
                prodLineSection.setProdLineCode(pmProductionLineMap.get(prodLineSection.getProdLineId()).getProdLineCode());
                prodLineSection.setProdLineName(pmProductionLineMap.get(prodLineSection.getProdLineId()).getProdLineName());
            }
            // 用户信息
            if (mtUserInfoMap.containsKey(prodLineSection.getCreatedBy())) {
                MtUserInfo mtUserInfo = mtUserInfoMap.get(prodLineSection.getCreatedBy());
                prodLineSection.setCreatedByName(Strings.concat(mtUserInfo.getLoginName(), mtUserInfo.getRealName()));
            }
            if (mtUserInfoMap.containsKey(prodLineSection.getLastUpdatedBy())) {
                MtUserInfo updateUserInfo = mtUserInfoMap.get(prodLineSection.getLastUpdatedBy());
                prodLineSection.setLastUpdatedByName(Strings.concat(updateUserInfo.getLoginName(), updateUserInfo.getRealName()));
            }
        }
        return page;
    }

    @Override
    public Page<PmProdLineSectionSpec> selectLineList(PageRequest pageRequest, Long prodLineSectionId, Long tenantId) {
        Page<PmProdLineSectionSpec> page = PageHelper.doPageAndSort(pageRequest, () -> pmProdLineSectionSpecRepository.selectByCondition(
                Condition.builder(PmProdLineSectionSpec.class)
                        .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_PROD_LINE_SECTION_ID, prodLineSectionId))
                        .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_TENANT_ID, tenantId))
                        .build()));
        // 未查到数据则返回
        if (CollectionUtils.isEmpty(page.getContent())) {
            return page;
        }

        // 查询用户信息
        List<Long> userIdList = page.getContent().stream().map(PmProdLineSectionSpec::getCreatedBy).distinct().collect(Collectors.toList());
        List<Long> updateByIdList = page.getContent().stream().map(PmProdLineSectionSpec::getLastUpdatedBy).distinct().collect(Collectors.toList());
        userIdList.addAll(updateByIdList);
        Map<Long, MtUserInfo> mtUserInfoMap = userClient.userInfoBatchGet(tenantId, userIdList);

        // 组装参数
        for (PmProdLineSectionSpec pmProdLineSectionSpec : page.getContent()) {
            // 用户信息
            if (mtUserInfoMap.containsKey(pmProdLineSectionSpec.getCreatedBy())) {
                MtUserInfo mtUserInfo = mtUserInfoMap.get(pmProdLineSectionSpec.getCreatedBy());
                pmProdLineSectionSpec.setCreatedByName(Strings.concat(mtUserInfo.getLoginName(), mtUserInfo.getRealName()));
            }
            if (mtUserInfoMap.containsKey(pmProdLineSectionSpec.getLastUpdatedBy())) {
                MtUserInfo updateUserInfo = mtUserInfoMap.get(pmProdLineSectionSpec.getLastUpdatedBy());
                pmProdLineSectionSpec.setLastUpdatedByName(Strings.concat(updateUserInfo.getLoginName(), updateUserInfo.getRealName()));
            }
        }
        return page;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveData(Long tenantId, PmProdLineSection pmProdLineSection) {
        checkUnique(pmProdLineSection, tenantId);
        if (pmProdLineSection.getProdLineSectionId() != null) {
            // 更新
            pmProdLineSectionRepository.updateByPrimaryKey(pmProdLineSection);
        } else {
            // 新增
            pmProdLineSectionRepository.insertSelective(pmProdLineSection);
        }
    }

    private void checkUnique(PmProdLineSection pmProdLineSection, Long tenantId) {
        // 	根据维护的PROD_LINE_ID+优先级，关联表PM_PROD_LINE_SECTION.PROD_LINE_ID+PRIORITY，获取数据
        List<PmProdLineSection> pmProdLineSectionList = pmProdLineSectionRepository.selectByCondition(Condition.builder(PmProdLineSection.class)
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_PROD_LINE_ID, pmProdLineSection.getProdLineId()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_PRIORITY, pmProdLineSection.getPriority()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_VALID_FLAG, 1L))
                .andWhere(Sqls.custom().andNotEqualTo(PmProdLineSection.FIELD_PROD_LINE_SECTION_ID, pmProdLineSection.getProdLineSectionId(), true))
                .build());
        // 若存在数据，则提示pm.production_mold_001：“产线编码{0}优先级{1}已存在，不允许重复，请检查！”
        if (CollectionUtils.isNotEmpty(pmProdLineSectionList)) {
            throw new CommonException("pm.production_mold_001", pmProdLineSection.getProdLineCode(), pmProdLineSection.getPriority());
        }

        // 若不存在数据，则进入下方校验
        // 根据维护的PROD_LINE_ID+断面厚+断面宽，关联表PM_PROD_LINE_SECTION.PROD_LINE_ID+MOLD_THICK+MOLD_WID，获取数据
        List<PmProdLineSection> prodLineSectionList = pmProdLineSectionRepository.selectByCondition(Condition.builder(PmProdLineSection.class)
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_PROD_LINE_ID, pmProdLineSection.getProdLineId()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_MOLD_THICK, pmProdLineSection.getMoldThick()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_MOLD_WID, pmProdLineSection.getMoldWid()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSection.FIELD_VALID_FLAG, 1L))
                .andWhere(Sqls.custom().andNotEqualTo(PmProdLineSection.FIELD_PROD_LINE_SECTION_ID, pmProdLineSection.getProdLineSectionId(), true))
                .build());
        // 若存在数据，则提示pm.production_mold_002：“产线编码{0}断面厚{1}断面宽{2}已存在，不允许重复，请检查！”
        if (CollectionUtils.isNotEmpty(prodLineSectionList)) {
            throw new CommonException("pm.production_mold_002", pmProdLineSection.getProdLineCode(),
                    pmProdLineSection.getMoldThick(), pmProdLineSection.getMoldWid());
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveLineData(Long tenantId, PmProdLineSectionSpec pmProdLineSectionSpec) {
        // 	根据PROD_LINE_SECTION_ID，关联表PM_PROD_LINE_SECTION_SPEC.PROD_LINE_SECTION_ID，
        // 获取THICK_FROM、THICK_TO、WID_FROM、WID_TO、LENGTH_FROM、LENGTH_TO
        List<PmProdLineSectionSpec> pmProdLineSectionSpecList = pmProdLineSectionSpecRepository.selectByCondition(Condition.builder(PmProdLineSectionSpec.class)
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_PROD_LINE_SECTION_ID, pmProdLineSectionSpec.getProdLineSectionId()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_TENANT_ID, tenantId))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_VALID_FLAG, 1L))
                .andWhere(Sqls.custom().andNotEqualTo(PmProdLineSectionSpec.FIELD_PROD_LINE_SECTION_SPEC_ID, pmProdLineSectionSpec.getProdLineSectionSpecId(), true))
                .build());
        if (CollectionUtils.isNotEmpty(pmProdLineSectionSpecList)) {
            for (PmProdLineSectionSpec item : pmProdLineSectionSpecList) {
                // 	若维护的厚度规格起+厚度规格止的范围与获取的数据存在交集，则提示pm.production_mold_003
                boolean thickIntervalCheck = Utils.isIntersect(pmProdLineSectionSpec.getThickFrom(),
                        pmProdLineSectionSpec.getThickTo(), item.getThickFrom(), item.getThickTo());
                if (thickIntervalCheck) {
                    throw new CommonException("pm.production_mold_003",pmProdLineSectionSpec.getThickFrom(), pmProdLineSectionSpec.getThickTo());
                }
                // 若维护的宽度规格起+宽度规格止的范围与获取的数据存在交集，则提示pm.production_mold_004
                boolean widIntervalCheck = Utils.isIntersect(pmProdLineSectionSpec.getWidFrom(),
                        pmProdLineSectionSpec.getWidTo(), item.getWidFrom(), item.getWidTo());
                if (widIntervalCheck) {
                    throw new CommonException("pm.production_mold_004", pmProdLineSectionSpec.getWidFrom(), pmProdLineSectionSpec.getWidTo());
                }
                // 若维护的长度规格起+长度规格止的范围与获取的数据存在交集，则提示pm.production_mold_005;
                boolean lengthIntervalCheck = Utils.isIntersect(pmProdLineSectionSpec.getLengthFrom(),
                        pmProdLineSectionSpec.getLengthTo(), item.getLengthFrom(), item.getLengthTo());
                if (lengthIntervalCheck) {
                    throw new CommonException("pm.production_mold_005", pmProdLineSectionSpec.getLengthFrom(), pmProdLineSectionSpec.getLengthTo());
                }
            }
        }
        if (pmProdLineSectionSpec.getProdLineSectionSpecId() != null) {
            // 更新
            pmProdLineSectionSpecRepository.updateByPrimaryKey(pmProdLineSectionSpec);
        } else {
            // 新增
            pmProdLineSectionSpecRepository.insertSelective(pmProdLineSectionSpec);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cpoyData(Long tenantId, PmProdLineSection pmProdLineSection) {
        PmProdLineSection prodLineSection = new PmProdLineSection();
        prodLineSection.setProdLineId(pmProdLineSection.getProdLineId());
        prodLineSection.setMoldThick(pmProdLineSection.getMoldThick());
        prodLineSection.setMoldWid(pmProdLineSection.getMoldWid());
        prodLineSection.setPriority(pmProdLineSection.getPriority());
        prodLineSection.setValidFlag(pmProdLineSection.getValidFlag());
        prodLineSection.setTenantId(pmProdLineSection.getTenantId());
        prodLineSection.setProdLineCode(pmProdLineSection.getProdLineCode());

        // 校验唯一性
        checkUnique(prodLineSection, tenantId);

        // 获取断面信息
        List<PmProdLineSectionSpec> pmProdLineSectionSpecList = pmProdLineSectionSpecRepository.selectByCondition(Condition.builder(PmProdLineSectionSpec.class)
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_PROD_LINE_SECTION_ID, pmProdLineSection.getProdLineSectionId()))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_TENANT_ID, tenantId))
                .build());

        pmProdLineSectionRepository.insertSelective(prodLineSection);

        // 复制断面信息
        List<PmProdLineSectionSpec> newPmProdLineSectionSpecList = new ArrayList<>();
        for (PmProdLineSectionSpec sectionSpec : pmProdLineSectionSpecList) {
            PmProdLineSectionSpec newPmProdLineSectionSpec = new PmProdLineSectionSpec();
            newPmProdLineSectionSpec.setProdLineSectionId(prodLineSection.getProdLineSectionId());
            newPmProdLineSectionSpec.setThickFrom(sectionSpec.getThickFrom());
            newPmProdLineSectionSpec.setThickTo(sectionSpec.getThickTo());
            newPmProdLineSectionSpec.setWidFrom(sectionSpec.getWidFrom());
            newPmProdLineSectionSpec.setWidTo(sectionSpec.getWidTo());
            newPmProdLineSectionSpec.setLengthFrom(sectionSpec.getLengthFrom());
            newPmProdLineSectionSpec.setLengthTo(sectionSpec.getLengthTo());
            newPmProdLineSectionSpec.setSteelSpecificationWeight(sectionSpec.getSteelSpecificationWeight());
            newPmProdLineSectionSpec.setValidFlag(sectionSpec.getValidFlag());
            newPmProdLineSectionSpec.setTenantId(sectionSpec.getTenantId());
            newPmProdLineSectionSpecList.add(newPmProdLineSectionSpec);
        }
        pmProdLineSectionSpecRepository.batchInsertSelective(newPmProdLineSectionSpecList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteForUi(List<PmProdLineSection> pmProdLineSectionList) {
        // 若勾选的为头数据则根据勾选的PROD_LINE_SECTION_ID，关联PM_PROD_LINE_SECTION.PROD_LINE_SECTION_ID+
        pmProdLineSectionRepository.batchDeleteByPrimaryKey(pmProdLineSectionList);
        // PM_PROD_LINE_SECTION_SPEC.PROD_LINE_SECTION_ID，获取数据进行删除
        List<Long> prodLineSectionIdList = pmProdLineSectionList.stream().map(PmProdLineSection::getProdLineSectionId).collect(Collectors.toList());
        List<PmProdLineSectionSpec> pmProdLineSectionSpecList = pmProdLineSectionSpecRepository.selectByCondition(Condition.builder(PmProdLineSectionSpec.class)
                .andWhere(Sqls.custom().andIn(PmProdLineSectionSpec.FIELD_PROD_LINE_SECTION_ID, prodLineSectionIdList))
                .andWhere(Sqls.custom().andEqualTo(PmProdLineSectionSpec.FIELD_TENANT_ID, pmProdLineSectionList.get(0).getTenantId()))
                .build());
        pmProdLineSectionSpecRepository.batchDeleteByPrimaryKey(pmProdLineSectionSpecList);
    }
}

