package com.zt.plat.module.qms.resource.material.dal.mapper;

import cn.hutool.core.collection.CollUtil;
import com.github.yulichang.wrapper.MPJLambdaWrapper;
import com.zt.plat.framework.common.pojo.PageResult;
import com.zt.plat.framework.mybatis.core.mapper.BaseMapperX;
import com.zt.plat.framework.mybatis.core.query.LambdaQueryWrapperX;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailPageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialLifecycleDetailRespVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.*;
import org.apache.ibatis.annotations.Mapper;

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

/**
 * 物料通用流程明细 Mapper
 *
 * @author 后台管理
 */
@Mapper
public interface MaterialLifecycleDetailMapper extends BaseMapperX<MaterialLifecycleDetailDO> {

    default PageResult<MaterialLifecycleDetailDO> selectPage(MaterialLifecycleDetailPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<MaterialLifecycleDetailDO>()
                .eqIfPresent(MaterialLifecycleDetailDO::getLifecycleId, reqVO.getLifecycleId())
                .eqIfPresent(MaterialLifecycleDetailDO::getProductId, reqVO.getProductId())
                .eqIfPresent(MaterialLifecycleDetailDO::getBatchId, reqVO.getBatchId())
                .eqIfPresent(MaterialLifecycleDetailDO::getBatchGongduanId, reqVO.getBatchGongduanId())
                .eqIfPresent(MaterialLifecycleDetailDO::getInfomationId, reqVO.getInfomationId())
                .eqIfPresent(MaterialLifecycleDetailDO::getInfluenceCount, reqVO.getInfluenceCount())
                .eqIfPresent(MaterialLifecycleDetailDO::getBusinessType, reqVO.getBusinessType())
                .eqIfPresent(MaterialLifecycleDetailDO::getTreatmentStatus, reqVO.getTreatmentStatus())
                .eqIfPresent(MaterialLifecycleDetailDO::getFormData, reqVO.getFormData())
                .eqIfPresent(MaterialLifecycleDetailDO::getSystemDepartmentCode, reqVO.getSystemDepartmentCode())
                .eqIfPresent(MaterialLifecycleDetailDO::getRemark, reqVO.getRemark())
                .betweenIfPresent(MaterialLifecycleDetailDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(MaterialLifecycleDetailDO::getId));
    }

    default List<MaterialLifecycleDetailRespVO> selectListWithGongPdtBatInfo(Long id){
        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .selectAll(MaterialLifecycleDetailDO.class)
                .selectAs("product.NAME", MaterialLifecycleDetailRespVO::getProductName)
                .selectAs("product.CD", MaterialLifecycleDetailRespVO::getProductCode)
                .selectAs("product.SPEC", MaterialLifecycleDetailRespVO::getProductSpecification)
                .selectAs("product.MDL_NO", MaterialLifecycleDetailRespVO::getProductModelNo)
                .selectAs("product.UNT", MaterialLifecycleDetailRespVO::getUnit)
                .selectAs("product.SMP_IDS", MaterialLifecycleDetailRespVO::getProductSampleIds)
                .selectAs("batch.BAT_NO", MaterialLifecycleDetailRespVO::getBatchNo)
                .selectAs("gongduan.INB_QTY", MaterialLifecycleDetailRespVO::getInfluenceCount)
                .selectAs("gongduan.ASN_DEPT_NAME", MaterialLifecycleDetailRespVO::getAssignDepartmentName)
                .leftJoin(MaterialProductDO.class, "product", MaterialProductDO::getId, MaterialLifecycleDetailDO::getProductId)
                .leftJoin(MaterialBatchDO.class, "batch", MaterialBatchDO::getId, MaterialLifecycleDetailDO::getBatchId)
                .leftJoin(MaterialBatchDO.class, "gongduan", MaterialBatchDO::getId, MaterialLifecycleDetailDO::getBatchGongduanId)
                .eq(MaterialLifecycleDetailDO::getLifecycleId, id);

        return selectJoinList(MaterialLifecycleDetailRespVO.class, wrapper);
    }

    default List<MaterialLifecycleDetailRespVO> selectNotMakeList(MaterialLifecycleDetailPageReqVO reqVO) {
        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .selectAll(MaterialLifecycleDetailDO.class)
                .selectAs(MaterialProductDO::getName, MaterialLifecycleDetailRespVO::getProductName)
                .selectAs(MaterialProductDO::getCode, MaterialLifecycleDetailRespVO::getProductCode)
                .selectAs(MaterialProductDO::getModelNo, MaterialLifecycleDetailRespVO::getProductModelNo)
                .selectAs(MaterialProductDO::getUnit, MaterialLifecycleDetailRespVO::getUnit)
                .select(MaterialLifecycleDO::getApplyUserId, MaterialLifecycleDO::getApplyUser,
                        MaterialLifecycleDO::getApplyDepartmentId, MaterialLifecycleDO::getApplyDepartment,
                        MaterialLifecycleDO::getApplyTime)
                .leftJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialLifecycleDetailDO::getProductId)
                .leftJoin(MaterialLifecycleDO.class, MaterialLifecycleDO::getId, MaterialLifecycleDetailDO::getLifecycleId)
                .eqIfExists(MaterialLifecycleDetailDO::getProductId, reqVO.getProductId())
                .eqIfExists(MaterialLifecycleDetailDO::getBusinessType, reqVO.getBusinessType())
                .eqIfExists(MaterialLifecycleDetailDO::getTreatmentStatus, reqVO.getTreatmentStatus())
                .likeIfExists(MaterialLifecycleDetailDO::getFormData, reqVO.getFormData())
                .likeIfExists(MaterialLifecycleDetailDO::getRemark, reqVO.getRemark())
                .orderByDesc(MaterialLifecycleDetailDO::getId);

        return selectJoinList(MaterialLifecycleDetailRespVO.class, wrapper);
    }

    default List<MaterialLifecycleDetailRespVO> selectDetailRespVOListByLfcIds(List<Long> lfcIds) {
        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .selectAll(MaterialLifecycleDetailDO.class)
                .select(MaterialProductDO::getDue, MaterialProductDO::getUnit)
                .selectAs(MaterialProductDO::getName, MaterialLifecycleDetailRespVO::getProductName)
                .selectAs(MaterialProductDO::getCode, MaterialLifecycleDetailRespVO::getProductCode)
                .selectAs(MaterialProductDO::getModelNo, MaterialLifecycleDetailRespVO::getProductModelNo)
                .leftJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialLifecycleDetailDO::getProductId)
                .in(MaterialLifecycleDetailDO::getLifecycleId, lfcIds);
        return selectJoinList(MaterialLifecycleDetailRespVO.class, wrapper);
    }

    default Map<Long, Long> getMadeCountMapByDetailIds(List<Long> detailIds) {

        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .select(MaterialLifecycleDetailDO::getId)
                .selectCount(MaterialStandardSolutionDO::getId, "quantity")
                .leftJoin(MaterialStandardSolutionDO.class, MaterialStandardSolutionDO::getDetailId, MaterialLifecycleDetailDO::getId)
                .in(MaterialLifecycleDetailDO::getId, detailIds)
                .groupBy(MaterialLifecycleDetailDO::getId);

        List<Map<String, Object>> maps = selectJoinMaps(wrapper);
        if (CollUtil.isEmpty(maps)) return new HashMap<>();

        return maps.stream().collect(Collectors.toMap(
                map -> (Long) map.get("ID"),
                map -> (Long) map.get("QUANTITY")
        ));
    }

    default List<MaterialLifecycleDetailRespVO> selectListWithReturnExchangeInfo(Long id) {
        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .selectAll(MaterialLifecycleDetailDO.class)
                .selectAs("batch.BAT_NO", MaterialLifecycleDetailRespVO::getBatchNo)
                .selectAs("gongduan.ASN_DEPT_NAME", MaterialLifecycleDetailRespVO::getAssignDepartmentName)
                .selectAs(MaterialInfomationDO::getCode, MaterialLifecycleDetailRespVO::getInfomationCode)
                .selectAs("product_infomation.NAME", MaterialLifecycleDetailRespVO::getInfomationName)
                .selectAs("product_infomation.SPEC", MaterialLifecycleDetailRespVO::getInfomationSpecification)
                .selectAs("product_infomation.MDL_NO", MaterialLifecycleDetailRespVO::getInfomationModelNo)
                .selectAs("product_infomation.UNT", MaterialLifecycleDetailRespVO::getInfomationUnit)
                .leftJoin(MaterialBatchDO.class, "batch", MaterialBatchDO::getId, MaterialLifecycleDetailDO::getBatchId)
                .leftJoin(MaterialBatchDO.class, "gongduan", MaterialBatchDO::getId, MaterialLifecycleDetailDO::getBatchGongduanId)
                .leftJoin(MaterialInfomationDO.class, MaterialInfomationDO::getId, MaterialLifecycleDetailDO::getInfomationId)
                .leftJoin(MaterialProductDO.class, "product_infomation", MaterialProductDO::getId, MaterialInfomationDO::getProductId)
                .eq(MaterialLifecycleDetailDO::getLifecycleId, id);

        return selectJoinList(MaterialLifecycleDetailRespVO.class, wrapper);
    }

    default List<MaterialLifecycleDetailRespVO> selectListWithBatchPdtBatInfo(Long id) {
        MPJLambdaWrapper<MaterialLifecycleDetailDO> wrapper = new MPJLambdaWrapper<MaterialLifecycleDetailDO>()
                .selectAll(MaterialLifecycleDetailDO.class)
                .selectAs("product.NAME", MaterialLifecycleDetailRespVO::getProductName)
                .selectAs("product.CD", MaterialLifecycleDetailRespVO::getProductCode)
                .selectAs("product.MDL_NO", MaterialLifecycleDetailRespVO::getProductModelNo)
                .selectAs("product.UNT", MaterialLifecycleDetailRespVO::getUnit)
                .selectAs(MaterialBatchDO::getBatchNo, MaterialLifecycleDetailRespVO::getBatchNo)
                .selectAs(MaterialBatchDO::getInboundQuantity, MaterialLifecycleDetailRespVO::getInboundQuantity)
                .selectAs(MaterialBatchDO::getRemaineQuantity, MaterialLifecycleDetailRespVO::getRemaineQuantity)
                .leftJoin(MaterialBatchDO.class, "batch", MaterialBatchDO::getId, MaterialLifecycleDetailDO::getBatchId)
                .leftJoin(MaterialProductDO.class, "product", MaterialProductDO::getId, MaterialBatchDO::getProductId)

                .eq(MaterialLifecycleDetailDO::getLifecycleId, id);

        return selectJoinList(MaterialLifecycleDetailRespVO.class, wrapper);
    }
}