package com.fjhx.mes.service.production.impl;

import cn.hutool.core.util.ObjectUtil;
import com.fjhx.item.entity.product.po.ProductInfo;
import com.fjhx.item.service.product.ProductInfoService;
import com.fjhx.mes.entity.production.po.ProductionPlan;
import com.fjhx.mes.entity.production.po.ProductionTask;
import com.fjhx.mes.entity.production.vo.ProductionTaskVo;
import com.fjhx.mes.entity.work.po.WorkOrder;
import com.fjhx.mes.entity.work.vo.WorkOrderVo;
import com.fjhx.mes.mapper.production.ProductionPlanMapper;
import com.fjhx.mes.service.production.ProductionPlanService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.fjhx.mes.service.production.ProductionTaskService;
import com.fjhx.mes.service.work.WorkOrderService;
import com.fjhx.mes.utils.code.CodeEnum;
import com.ruoyi.system.utils.UserUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.fjhx.mes.entity.production.vo.ProductionPlanVo;
import com.fjhx.mes.entity.production.dto.ProductionPlanSelectDto;
import com.ruoyi.common.utils.wrapper.IWrapper;
import com.fjhx.mes.entity.production.dto.ProductionPlanDto;
import cn.hutool.core.bean.BeanUtil;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;


/**
 * <p>
 * 生产计划 服务实现类
 * </p>
 *
 * @author
 * @since 2023-03-29
 */
@Service
public class ProductionPlanServiceImpl extends ServiceImpl<ProductionPlanMapper, ProductionPlan> implements ProductionPlanService {

    @Autowired
    WorkOrderService workOrderService;
    @Autowired
    ProductInfoService productInfoService;
    @Autowired
    ProductionTaskService productionTaskService;

    @Override
    public Page<ProductionPlanVo> getPage(ProductionPlanSelectDto dto) {
        IWrapper<ProductionPlan> wrapper = getWrapper();
        wrapper.orderByDesc("pp", ProductionPlan::getId);
        if(ObjectUtil.isNotEmpty(dto.getKeyword())) {
            wrapper.and(q->q.like(ProductionPlan::getStartDate, dto.getKeyword())
                    .or().like(ProductionPlan::getStopDate, dto.getKeyword())
                    .or().like(ProductionPlan::getQuantity, dto.getKeyword()));
        }
        Page<ProductionPlanVo> page = this.baseMapper.getPage(dto.getPage(), wrapper);
        List<ProductionPlanVo> records = page.getRecords();

        //获取工单信息
        List<Long> workOrderIds = records.stream().map(ProductionPlanVo::getWorkOrderId).collect(Collectors.toList());
        if(ObjectUtil.isNotEmpty(workOrderIds)) {
            List<WorkOrder> workOrderList = workOrderService.list(q -> q.in(WorkOrder::getId, workOrderIds));
            Map<Long, WorkOrder> workOrderMap = workOrderList.stream().collect(Collectors.groupingBy(WorkOrder::getId,
                    Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
            //获取产品信息
            List<Long> productIds = workOrderList.stream().map(WorkOrder::getProductId).collect(Collectors.toList());
            if(ObjectUtil.isNotEmpty(productIds)) {
                List<ProductInfo> productInfos = productInfoService.listByIds(productIds);
                Map<Long, ProductInfo> productInfoMap = productInfos.stream().collect(Collectors.groupingBy(ProductInfo::getId,
                        Collectors.collectingAndThen(Collectors.toList(), value -> value.get(0))));
                for (ProductionPlanVo productionPlanVo : records) {
                    WorkOrder workOrder = workOrderMap.get(productionPlanVo.getWorkOrderId());
                    ProductInfo productInfo = productInfoMap.get(workOrder.getProductId());
                    if (ObjectUtil.isNotEmpty(productInfo)) {
                        productionPlanVo.setProductName(productInfo.getName());
                    }
                }
            }
        }
        //赋值待排程数量
        for (ProductionPlanVo productionPlanVo : records) {
            productionPlanVo.setRemainingQuantity(productionPlanVo.getQuantity());
        }
        List<Long> productionPlanIds = records.stream().map(ProductionPlan::getId).collect(Collectors.toList());
        if (ObjectUtil.isNotEmpty(productionPlanIds)) {
            List<ProductionTask> productionTaskList = productionTaskService.list(q -> q.in(ProductionTask::getProductionPlanId, productionPlanIds));
            if (ObjectUtil.isNotEmpty(productionTaskList)) {
                //根据生产计划id分组
                Map<Long, List<ProductionTask>> productionTaskMap = productionTaskList.stream().collect(Collectors.groupingBy(ProductionTask::getProductionPlanId));
                for (ProductionPlanVo productionPlanVo : records) {
                    List<ProductionTask> productionTaskList1 = productionTaskMap.get(productionPlanVo.getId());
                    BigDecimal count = BigDecimal.ZERO;
                    if (ObjectUtil.isNotEmpty(productionTaskList1)) {
                        count = productionTaskList1.stream().map(ProductionTask::getQuantity)
                                .reduce(BigDecimal.ZERO, BigDecimal::add);
                    }
                    productionPlanVo.setRemainingQuantity(productionPlanVo.getQuantity().subtract(count));
                }
            }
        }
        return page;
    }

    @Override
    public ProductionPlanVo detail(Long id) {
        ProductionPlan ProductionPlan = this.getById(id);
        ProductionPlanVo result = BeanUtil.toBean(ProductionPlan, ProductionPlanVo.class);
        //赋值产品信息
        WorkOrder workOrder = workOrderService.getById(result.getWorkOrderId());
        ProductInfo productInfo = productInfoService.getById(workOrder.getProductId());
        if(ObjectUtil.isNotEmpty(productInfo)) {
            result.setProductName(productInfo.getName());
        }
        //赋值生产任务列表
        List<ProductionTask> list = productionTaskService.list(q -> q.eq(ProductionTask::getProductionPlanId, id));
        List<ProductionTaskVo> productionTaskVos = BeanUtil.copyToList(list, ProductionTaskVo.class);
        //赋值负责人名字
        UserUtil.assignmentNickName(productionTaskVos, ProductionTask::getPersonLiableId, ProductionTaskVo::setPersonLiableName);
        result.setProductionTaskList(productionTaskVos);
        return result;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(ProductionPlanDto productionPlanDto) {
        productionPlanDto.setStatus(0);
        productionPlanDto.setCode(CodeEnum.PRODUCTION_PLAN.getCode());
        this.save(productionPlanDto);
        Long workOrderId = productionPlanDto.getWorkOrderId();
        //修改工单状态为进行中
        WorkOrder byId = workOrderService.getById(workOrderId);
        byId.setStatus(1);
        workOrderService.updateById(byId);
    }

    @Override
    public void edit(ProductionPlanDto productionPlanDto) {
        this.updateById(productionPlanDto);
    }

    @Override
    public void delete(Long id) {
        this.removeById(id);
    }

}
