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

import com.xisc.pm.api.dto.QdToPoOrderAndRELDTO;
import com.xisc.pm.api.dto.QdToPoOrderAndRELReqDTO;
import com.xisc.pm.api.dto.QdToPoOrderDTO;
import com.xisc.pm.app.service.PmCompositeOrderRelService;
import com.xisc.pm.domain.entity.PmCompositeOrderRel;
import com.xisc.pm.domain.entity.PmCompositeSlabList;
import com.xisc.pm.domain.entity.PmPdContSum;
import com.xisc.pm.domain.repository.PmCompositeOrderRelRepository;
import com.xisc.pm.domain.repository.PmCompositeSlabListRepository;
import com.xisc.pm.domain.repository.PmContMscTechRepository;
import com.xisc.pm.domain.repository.PmPdContSumRepository;
import com.xisc.pm.domain.vo.QdToLineupResultSteelVO;
import com.xisc.pm.infra.mapper.PmCompositeOrderRelMapper;
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.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.hzero.core.util.IpAddressUtils;
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 javax.servlet.http.HttpServletRequest;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * 复合板成品合同与基材合同对应关系表(PmCompositeOrderRel)应用服务
 *
 * @author 纪文桃 wentao.ji01@hand-china.com
 * @since 2024-09-25 09:20:38
 */
@Service
public class PmCompositeOrderRelServiceImpl implements PmCompositeOrderRelService {
    @Autowired
    private PmCompositeOrderRelRepository pmCompositeOrderRelRepository;
    @Autowired
    private PmCompositeOrderRelMapper pmCompositeOrderRelMapper;
    @Autowired
    private PmCompositeSlabListRepository pmCompositeSlabListRepository;

    @Autowired
    private PmPdContSumRepository pmPdContSumRepository;

    @Autowired
    private PmContMscTechRepository pmContMscTechRepository;

    @Override
    public Page<PmCompositeOrderRel> selectList(PageRequest pageRequest, PmCompositeOrderRel pmCompositeOrderRel) {
        return PageHelper.doPageAndSort(pageRequest, () -> pmCompositeOrderRelRepository.selectList(pmCompositeOrderRel));
    }

    @Override
    public List<QdToPoOrderDTO> listQdOrder(String productOrderNo, Long tenantId) {
        List<QdToPoOrderDTO> resultList = pmCompositeOrderRelMapper.listQdOrder(productOrderNo, null, tenantId);
        if (CollectionUtils.isEmpty(resultList)) {
            return Collections.EMPTY_LIST;
        }
        // 查询合同号对应内部钢种
        List<String> orderNoList = resultList.stream().map(QdToPoOrderDTO::getOrderNo).distinct().collect(Collectors.toList());
        List<QdToLineupResultSteelVO> steelList = pmCompositeOrderRelMapper.selectStNoBySteel(orderNoList, tenantId);
        if (CollectionUtils.isNotEmpty(steelList)) {
            Map<String, String> steelMap = steelList.stream().collect(Collectors.toMap(QdToLineupResultSteelVO::getOrderNo, QdToLineupResultSteelVO::getStNo));
            resultList.forEach(item -> {
                if (steelMap.containsKey(item.getOrderNo())) {
                    item.setStNo(steelMap.get(item.getOrderNo()));
                }
            });
        }
        return resultList.stream().filter(item-> StringUtils.isNotEmpty(item.getStNo())).collect(Collectors.toList());
    }

    @Override
    public QdToPoOrderAndRELDTO listOrderForUi(String stNo, String productOrderNo, Long tenantId) {
        QdToPoOrderAndRELDTO result = new QdToPoOrderAndRELDTO();
        // 合同处理产线组合(QD_TO_LINEUP_RESULT_STEEL)表中可选合同的内部钢种与前台传入的成品合同内部钢种相同
        List<String> orderNoList = pmCompositeOrderRelMapper.listQdToLineupResultSteel(stNo, tenantId);
        if (CollectionUtils.isNotEmpty(orderNoList)) {
            // 过滤掉已经维护的基材合同
            List<PmCompositeOrderRel> pmCompositeOrderRelList = pmCompositeOrderRelRepository.selectByProductAndOrderList(productOrderNo, orderNoList, tenantId);
            if (CollectionUtils.isNotEmpty(pmCompositeOrderRelList)) {
                List<String> existOrderList = pmCompositeOrderRelList.stream().map(PmCompositeOrderRel::getBaseOrderNo).collect(Collectors.toList());
                orderNoList.removeAll(existOrderList);
            }

            // 合同主档表表(QD_TO_PO_ORDER)中合同性质为基材合同（order_type_code等于ZFH 合同跟踪主表(CT_MAIN)合同状态小于等于67
            List<QdToPoOrderDTO> resultList = pmCompositeOrderRelMapper.selectQdAndCtOrder(orderNoList, tenantId);
            result.setQdToPoOrderDTOList(resultList);
        }
        // 查询复合板成品合同与基材合同对应关系表（PM_COMPOSITE_ORDER_REL）中成品合同号等于前台传入的成品合同号的所有基材合同，
        List<PmCompositeOrderRel> pmCompositeOrderRelList = pmCompositeOrderRelRepository.selectByCondition(Condition.builder(PmCompositeOrderRel.class)
                .andWhere(Sqls.custom().andEqualTo(PmCompositeOrderRel.FIELD_PRODUCT_ORDER_NO, productOrderNo))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeOrderRel.FIELD_TENANT_ID, tenantId))
                .build());
        if (CollectionUtils.isNotEmpty(pmCompositeOrderRelList)) {
            List<String> orderList = pmCompositeOrderRelList.stream().map(PmCompositeOrderRel::getBaseOrderNo).distinct().collect(Collectors.toList());
            //并通过基材合同号关联合同主档表表(QD_TO_PO_ORDER)
            List<QdToPoOrderDTO> resultList = pmCompositeOrderRelMapper.queryQdOrderByOrder(orderList, tenantId);
            result.setSelectedToPoOrderDTOList(resultList);
        }
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(Long tenantId, QdToPoOrderAndRELReqDTO dto, HttpServletRequest request) {
        // 校验基材合同号，与表格1中选择的成品合同在成品合同与基材合同对应关系表（PM_COMPOSITE_ORDER_REL）中不存在对应关系
        String productOrderNo = dto.getProductOrderNo();
        List<String> selectOrderList = dto.getQdToPoOrderDTOList().stream().map(QdToPoOrderDTO::getOrderNo).collect(Collectors.toList());
        List<PmCompositeOrderRel> pmCompositeOrderRelList = pmCompositeOrderRelRepository.selectByProductAndOrderList(productOrderNo, selectOrderList, tenantId);
        if (CollectionUtils.isNotEmpty(pmCompositeOrderRelList)) {
            Map<String, PmCompositeOrderRel> pmCompositeOrderRelMap = pmCompositeOrderRelList.stream()
                    .collect(Collectors.toMap(item -> item.getProductOrderNo() + item.getBaseOrderNo(), Function.identity()));
            dto.getQdToPoOrderDTOList().forEach(item -> {
                if (pmCompositeOrderRelMap.containsKey(productOrderNo + item.getOrderNo())) {
                    throw new CommonException("pm.composite_order_rel_001", productOrderNo, item.getOrderNo());
                }
            });
        }
        // 获取ip
        String ip = IpAddressUtils.getIpAddress(request);

        // 保存
        List<PmCompositeOrderRel> compositeOrderRelList = dto.getQdToPoOrderDTOList().stream().map(item -> {
            PmCompositeOrderRel pmCompositeOrderRel = new PmCompositeOrderRel();
            pmCompositeOrderRel.setProductOrderNo(productOrderNo);
            pmCompositeOrderRel.setBaseOrderNo(item.getOrderNo());
            pmCompositeOrderRel.setTenantId(tenantId);
            pmCompositeOrderRel.setIpAddress(ip);
            return pmCompositeOrderRel;
        }).collect(Collectors.toList());
        pmCompositeOrderRelRepository.batchInsertSelective(compositeOrderRelList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(Long tenantId, QdToPoOrderAndRELReqDTO dto) {
        String productOrderNo = dto.getProductOrderNo();
        List<String> selectOrderList = dto.getQdToPoOrderDTOList().stream().map(QdToPoOrderDTO::getOrderNo).collect(Collectors.toList());
        List<PmCompositeSlabList> pmCompositeSlabLists = pmCompositeSlabListRepository.selectByCondition(Condition.builder(PmCompositeSlabList.class)
                .andWhere(Sqls.custom().andIn(PmCompositeSlabList.FIELD_BASE_ORDER_NO, selectOrderList))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeSlabList.FIELD_TENANT_ID, tenantId))
                .build());
        if (CollectionUtils.isNotEmpty(pmCompositeSlabLists)) {
            List<String> baseMatNoList = pmCompositeSlabLists.stream().map(PmCompositeSlabList::getBaseMatNo).collect(Collectors.toList());
            // 获取基材的成品合同信息
            List<PmPdContSum> pdContSumList = pmPdContSumRepository.selectBySlabNoList(baseMatNoList, tenantId);
            // 校验是否生成组坯计划
            Optional<PmPdContSum> productOrderNoOptional = pdContSumList.stream().filter(item -> item.getOrderNo().equals(productOrderNo)).findFirst();
            if (productOrderNoOptional.isPresent()) {
                throw new CommonException("pm.composite_order_rel_002", selectOrderList);
            }
        }

        // 删除
        List<PmCompositeOrderRel> pmCompositeOrderRelList = pmCompositeOrderRelRepository.selectByCondition(Condition.builder(PmCompositeOrderRel.class)
                .andWhere(Sqls.custom().andIn(PmCompositeOrderRel.FIELD_BASE_ORDER_NO, selectOrderList))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeOrderRel.FIELD_PRODUCT_ORDER_NO, productOrderNo))
                .andWhere(Sqls.custom().andEqualTo(PmCompositeOrderRel.FIELD_TENANT_ID, tenantId))
                .build());

        pmCompositeOrderRelRepository.batchDeleteByPrimaryKey(pmCompositeOrderRelList);
    }

}



