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

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
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.framework.mybatis.core.query.MPJLambdaWrapperX;
import com.zt.plat.module.qms.core.aspect.annotation.QmsPermission;
import com.zt.plat.module.qms.enums.QmsPermissionConstant;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundPageReqVO;
import com.zt.plat.module.qms.resource.material.controller.vo.MaterialInventoryOutboundRespVO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInfomationDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInventoryOutboundDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialInventoryOutboundDetailDO;
import com.zt.plat.module.qms.resource.material.dal.dataobject.MaterialProductDO;
import com.zt.plat.module.qms.resource.material.enums.MaterialOutboundType;
import org.apache.ibatis.annotations.Mapper;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

/**
 * 物料出库 Mapper
 *
 * @author 后台管理
 */
@Mapper
public interface MaterialInventoryOutboundMapper extends BaseMapperX<MaterialInventoryOutboundDO> {
    @QmsPermission(moduleDataRoleCodes = QmsPermissionConstant.ADMIN_ROLE + "," + QmsPermissionConstant.MATERIAL_ADMIN_ROLE)
    default PageResult<MaterialInventoryOutboundDO> selectPage(MaterialInventoryOutboundPageReqVO reqVO) {
        return selectPage(reqVO, new LambdaQueryWrapperX<MaterialInventoryOutboundDO>()
                .eqIfPresent(MaterialInventoryOutboundDO::getTitle, reqVO.getTitle())
                .eqIfPresent(MaterialInventoryOutboundDO::getBusinessType, reqVO.getBusinessType())
                .eqIfPresent(MaterialInventoryOutboundDO::getBusinessTypeCode, reqVO.getBusinessTypeCode())
                .eqIfPresent(MaterialInventoryOutboundDO::getApplyUser, reqVO.getApplyUser())
                .eqIfPresent(MaterialInventoryOutboundDO::getApplyUserId, reqVO.getApplyUserId())
                .eqIfPresent(MaterialInventoryOutboundDO::getApplyDepartment, reqVO.getApplyDepartment())
                .eqIfPresent(MaterialInventoryOutboundDO::getApplyDepartmentId, reqVO.getApplyDepartmentId())
                .betweenIfPresent(MaterialInventoryOutboundDO::getApplyTime, reqVO.getApplyTime())
                .eqIfPresent(MaterialInventoryOutboundDO::getSuperviseUser, reqVO.getSuperviseUser())
                .eqIfPresent(MaterialInventoryOutboundDO::getSuperviseUserId, reqVO.getSuperviseUserId())
                .eqIfPresent(MaterialInventoryOutboundDO::getFlowInstanceId, reqVO.getFlowInstanceId())
                .eqIfPresent(MaterialInventoryOutboundDO::getCommentJson, reqVO.getCommentJson())
                .eqIfPresent(MaterialInventoryOutboundDO::getFlowStatus, reqVO.getFlowStatus())
                .eqIfPresent(MaterialInventoryOutboundDO::getSystemDepartmentCode, reqVO.getSystemDepartmentCode())
                .eqIfPresent(MaterialInventoryOutboundDO::getRemark, reqVO.getRemark())
                .betweenIfPresent(MaterialInventoryOutboundDO::getCreateTime, reqVO.getCreateTime())
                .orderByDesc(MaterialInventoryOutboundDO::getId));
    }

    @QmsPermission(deptIdColumn = "APL_DEPT_ID",
            moduleDataRoleCodes = QmsPermissionConstant.ADMIN_ROLE + "," + QmsPermissionConstant.MATERIAL_ADMIN_ROLE)
    default List<MaterialInventoryOutboundRespVO> selectListUsageStatisticsMainDataByDept(MaterialInventoryOutboundPageReqVO reqVO) {
        MPJLambdaWrapper<MaterialInventoryOutboundDO> wrapper = new MPJLambdaWrapperX<MaterialInventoryOutboundDO>()
                .select(MaterialInfomationDO::getProductId)
                .select(MaterialInventoryOutboundDO::getApplyDepartmentId)
                .selectCount(MaterialInventoryOutboundDetailDO::getId, "USAGE_QUANTITY")
                .leftJoin(MaterialInventoryOutboundDetailDO.class, MaterialInventoryOutboundDetailDO::getOutboundId, MaterialInventoryOutboundDO::getId)
                .leftJoin(MaterialInfomationDO.class, MaterialInfomationDO::getId, MaterialInventoryOutboundDetailDO::getInfomationId)
                .leftJoin(MaterialProductDO.class, MaterialProductDO::getId, MaterialInfomationDO::getProductId)
                .eq(MaterialInventoryOutboundDO::getBusinessType, MaterialOutboundType.receive_outbound.getName())
                .eqIfExists(MaterialInventoryOutboundDO::getApplyDepartmentId, reqVO.getApplyDepartmentId())
                .likeIfExists(MaterialInventoryOutboundDO::getApplyDepartment, reqVO.getApplyDepartment())
                .likeIfExists(MaterialProductDO::getName, reqVO.getProductName())
                .groupBy(MaterialInfomationDO::getProductId)
                .groupBy(MaterialInventoryOutboundDO::getApplyDepartmentId)
                ;
        if (reqVO.getApplyTime() != null && reqVO.getApplyTime().length == 2)
            wrapper.between(MaterialInventoryOutboundDO::getApplyTime, reqVO.getApplyTime()[0], reqVO.getApplyTime()[1]);
        List<Map<String, Object>> statisticsMaps = selectJoinMaps(wrapper);
        if (CollUtil.isEmpty(statisticsMaps)) return List.of();

        // 2. 将 Map 转换为 MaterialInventoryOutboundRespVO
        List<MaterialInventoryOutboundRespVO> result = new ArrayList<>();
        for (Map<String, Object> statMap : statisticsMaps) {
            MaterialInventoryOutboundRespVO respVO = new MaterialInventoryOutboundRespVO();

            // 从 Map 中提取数据并设置到 VO 中
            Long productId = MapUtil.getLong(statMap, "PDT_ID");
            Long departmentId = MapUtil.getLong(statMap, "APL_DEPT_ID");
            String usageQuantity = MapUtil.getStr(statMap, "USAGE_QUANTITY");

            // 设置基础统计信息
            respVO.setProductId(productId);
            respVO.setApplyDepartmentId(departmentId);
            respVO.setUsageQuantity(usageQuantity);

            result.add(respVO);
        }

        return result;
    }
}