package cn.iocoder.yudao.module.mes.service.workreportplan;

import cn.hutool.core.collection.CollUtil;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.collection.MapUtils;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.erp.dal.dataobject.product.ErpProductDO;
import cn.iocoder.yudao.module.erp.service.product.ErpProductService;
import cn.iocoder.yudao.module.mes.controller.admin.producereportplan.vo.*;
import cn.iocoder.yudao.module.mes.dal.dataobject.plan.PlanDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.workreportplan.ReportPlanSummaryDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.workreportplan.ReportPlanViewDO;
import cn.iocoder.yudao.module.mes.dal.dataobject.workreportplan.WorkReportPlanDO;
import cn.iocoder.yudao.module.mes.dal.mysql.workreportplan.ReportPlanSummaryMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.workreportplan.ReportPlanViewMapper;
import cn.iocoder.yudao.module.mes.dal.mysql.workreportplan.WorkReportPlanMapper;
import cn.iocoder.yudao.module.mes.service.organization.OrganizationService;
import cn.iocoder.yudao.module.mes.service.plan.PlanService;
import org.springframework.stereotype.Service;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.framework.common.util.collection.CollectionUtils.convertSet;
import static cn.iocoder.yudao.module.mes.enums.ErrorCodeConstants.WORK_REPORT_PLAN_NOT_EXISTS;

/**
 * 报工分配计划 Service 实现类
 *
 * @author 内蒙必硕
 */
@Service
@Validated
public class WorkReportPlanServiceImpl implements WorkReportPlanService {

    @Resource
    private WorkReportPlanMapper workReportPlanMapper;
    @Resource
    private ReportPlanViewMapper reportPlanViewMapper;
    @Resource
    private ErpProductService productService;
    @Resource
    private PlanService planService;
    @Resource
    private ReportPlanSummaryMapper planSummaryMapper;
    @Resource
    private OrganizationService organizationService;
    @Override
    public Long createWorkReportPlan(WorkReportPlanSaveReqVO createReqVO) {
        // 插入
        WorkReportPlanDO workReportPlan = BeanUtils.toBean(createReqVO, WorkReportPlanDO.class);
        workReportPlanMapper.insert(workReportPlan);
        // 返回
        return workReportPlan.getId();
    }

    @Override
    public void updateWorkReportPlan(WorkReportPlanSaveReqVO updateReqVO) {
        // 校验存在
        validateWorkReportPlanExists(updateReqVO.getId());
        // 更新
        WorkReportPlanDO updateObj = BeanUtils.toBean(updateReqVO, WorkReportPlanDO.class);
        workReportPlanMapper.updateById(updateObj);
    }

    @Override
    public void deleteWorkReportPlan(Long id) {
        // 校验存在
        validateWorkReportPlanExists(id);
        // 删除
        workReportPlanMapper.deleteById(id);
    }

    private void validateWorkReportPlanExists(Long id) {
        if (workReportPlanMapper.selectById(id) == null) {
            throw exception(WORK_REPORT_PLAN_NOT_EXISTS);
        }
    }

    @Override
    public WorkReportPlanDO getWorkReportPlan(Long id) {
        return workReportPlanMapper.selectById(id);
    }

    @Override
    public PageResult<WorkReportPlanDO> getWorkReportPlanPage(WorkReportPlanPageReqVO pageReqVO) {
        return workReportPlanMapper.selectPage(pageReqVO);
    }

    @Override
    public BigDecimal selectSumBy(Long planId, String orgType){
        return reportPlanViewMapper.selectSumBy(planId, orgType);
    }

    @Override
    public List<WorkReportPlanRespVO> buildVOList(List<WorkReportPlanDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductDO> map = productService.getProductMap(
                convertSet(list, WorkReportPlanDO::getProductId));
        Map<Long, PlanDO> planMap = planService.getPlanMap(
                convertSet(list, WorkReportPlanDO::getPlanId));
        return BeanUtils.toBean(list, WorkReportPlanRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getProductId(),
                    product -> item.setProductName(product.getName()));
            MapUtils.findAndThen(planMap, item.getPlanId(),
                    plan -> item.setPlanCode(plan.getCode()));

        });
    }

    @Override
    public List<ReportPlanViewDO> getReportPlanViewList() {
        return reportPlanViewMapper.selectList();
    }
    @Override
    public PageResult<ReportPlanViewRespVO> getReportPlanViewPage(ReportPlanViewReqVO reqVO) {
        PageResult<ReportPlanViewDO> pageResult = reportPlanViewMapper.selectPage(reqVO);
        return new PageResult<>(buildViewList(pageResult.getList()), pageResult.getTotal());
    }
    @Override
    public List<ReportPlanViewRespVO> buildViewList(List<ReportPlanViewDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductDO> map = productService.getProductMap(
                convertSet(list, ReportPlanViewDO::getProductId));
        Map<Long, PlanDO> planMap = planService.getPlanMap(
                convertSet(list, ReportPlanViewDO::getPlanId));

        return BeanUtils.toBean(list, ReportPlanViewRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getProductId(),
                    product -> item.setProductName(product.getName()));
            MapUtils.findAndThen(planMap, item.getPlanId(),
                    plan -> item.setPlanCode(plan.getCode()));

        });
    }

    @Override
    public List<ReportPlanSummaryRespVO> getPlanSummary(ReportPlanSummaryRespVO respVO){
        List<ReportPlanSummaryDO> list = planSummaryMapper.selectList(respVO);
        return buildSummaryList(list);
    }

    @Override
    public List<ReportPlanSummaryRespVO> buildSummaryList(List<ReportPlanSummaryDO> list) {
        if (CollUtil.isEmpty(list)) {
            return Collections.emptyList();
        }
        Map<Long, ErpProductDO> map = productService.getProductMap(
                convertSet(list, ReportPlanSummaryDO::getProductId));
        Map<Long, PlanDO> planMap = planService.getPlanMap(
                convertSet(list, ReportPlanSummaryDO::getPlanId));

        return BeanUtils.toBean(list, ReportPlanSummaryRespVO.class, item -> {
            MapUtils.findAndThen(map, item.getProductId(),
                    product -> item.setProductName(product.getName()));
            MapUtils.findAndThen(planMap, item.getPlanId(),
                    plan -> item.setPlanCode(plan.getCode()));

        });
    }
}