package com.cf.imes.module.manage.service.process;


import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.cf.imes.framework.common.enums.ProcessProcessingTypeEnum;
import com.cf.imes.framework.common.enums.ProcessingStatusEnum;
import com.cf.imes.framework.common.exception.util.ServiceExceptionUtil;
import com.cf.imes.framework.common.pojo.PageResult;
import com.cf.imes.framework.common.util.object.BeanUtils;
import com.cf.imes.module.manage.controller.admin.process.vo.*;
import com.cf.imes.module.manage.controller.admin.query.vo.productionStatus.OrderModuleVO;
import com.cf.imes.module.manage.dal.dataobject.pack.OrderBodyDO;
import com.cf.imes.module.manage.dal.dataobject.plate.OrderPlateDO;
import com.cf.imes.module.manage.dal.dataobject.plate.PlateDO;
import com.cf.imes.module.manage.dal.dataobject.process.OrderProcessStepItemNDO;
import com.cf.imes.module.manage.dal.mysql.pack.OrderBodyMapper;
import com.cf.imes.module.manage.dal.mysql.plate.OrderPlateMapper;
import com.cf.imes.module.manage.dal.mysql.plate.PlateMapper;
import com.cf.imes.module.manage.dal.mysql.process.*;
import com.cf.imes.module.manage.dal.mysql.query.OrderItemMapper;
import com.cf.imes.module.system.enums.ErrorCodeConstants;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getLoginUser;
import static com.cf.imes.framework.security.core.util.SecurityFrameworkUtils.getUserOrganId;
import static com.cf.imes.module.manage.util.search.SearchUtil.insertSeparator;


/**
 * 生产单工序表 order_process_{N}  实现类
 *
 * @author 晨丰科技
 */
@Service
@Validated
public class ProductionProcessServiceImpl implements ProductionProcessService {



    @Resource
    private ProcessStepMapper processStepMapper;


    @Resource
    private ProcessStepItemMapper processStepItemMapper;




    @Resource
    private OrderBodyMapper orderBodyMapper;


    @Resource
    private OrderItemMapper orderItemMapper;

    @Resource
    private OrderPlateMapper orderPlateMapper;






    // 生产工序单分页查询
    @Override
    public PageResult<ProcessRespVO> getProcessPage(ProcessPageReqVO pageReqVO) {

        // 模糊搜索添加条件
        pageReqVO.setCustomer(insertSeparator(pageReqVO.getCustomer()));
        pageReqVO.setCustomOrderNo(insertSeparator(pageReqVO.getCustomOrderNo()));
        pageReqVO.setAddress(insertSeparator(pageReqVO.getAddress()));

        PageDTO<ProcessRespVO> page = new PageDTO<>(pageReqVO.getPageNo(), pageReqVO.getPageSize());

        IPage<ProcessRespVO> processRespVOS = processStepMapper.selectOrder(page,pageReqVO,getUserOrganId());

        // 判断生产步骤表在传入的状态查询后是否为空
        if(processRespVOS == null){

            return null;
        }

        if (CollectionUtil.isEmpty(processRespVOS.getRecords())) {
            return new PageResult<>();
        }


        return new PageResult<>(processRespVOS.getRecords(), processRespVOS.getTotal());


    }







    // 修改工序明细表的工序状态
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateProcessStatus(OrderProcessStepItemVO reqVo) {

        // 工序加工添加负责人
        String nickname = getLoginUser().getNickname();

        // 根据工序步骤 id 查询当前生产单步骤和明细的生产状态
        ProcessStepStatus processStepStatuses = processStepItemMapper.selectStatusById(reqVo.getProcessStepId(),reqVo.getName(),getUserOrganId());


        // 判断生产明细表的状态查询后是否为空
        if(processStepStatuses.getProcessStepItemStatus().equals(ProcessingStatusEnum.PROCESSED.getStatus())){

            throw ServiceExceptionUtil.exception(ErrorCodeConstants.UNPROCESSED_BEFORE_PROCESSING);
        }
        // 判断生产工序步骤表的状态是否为空
        if(processStepStatuses.getProcessStepStatus().equals(ProcessingStatusEnum.PROCESSED.getStatus())){

            throw ServiceExceptionUtil.exception(ErrorCodeConstants.UNPROCESSED_BEFORE_PROCESSING);
        }

        // 判断生产单工序的状态是否为组件加工
        if(processStepStatuses.getType().equals(ProcessProcessingTypeEnum.COMPONENTPROCESSING.getNumber())){

            processStepItemMapper.updateStemStatus(reqVo.getProcessStepId(),reqVo.getName(),nickname);

            List<OrderProcessStepItemNDO> orderProcessStepItemNDOS = processStepItemMapper.selectStemById(reqVo.getProcessStepId(),ProcessingStatusEnum.RAW.getStatus(),getUserOrganId());
            if(orderProcessStepItemNDOS.isEmpty()){

                // 修改生产单工序步骤表的状态
                BigDecimal salary = calculateSalary(reqVo.getProcessStepId());

                processStepMapper.updateStatusById(reqVo.getProcessStepId(),salary);

            }

            return;

        }

        try {

            BigDecimal salary = calculateSalary(reqVo.getProcessStepId());
            // 修改生产明细表和步骤表的工序状态
            processStepItemMapper.updateStatus(reqVo.getProcessStepId(),nickname,salary);
        }catch (Exception e){
            throw  ServiceExceptionUtil.exception(ErrorCodeConstants.UNPROCESSED_BEFORE_PROCESSING);
        }



    }



    // 计算工资金额
    public BigDecimal calculateSalary(Long processStepId){

        // 查询当前工序对应的板材的面积
        BigDecimal area = processStepItemMapper.selectAreaByProcessStepId(processStepId);


        // 计算当前工序的工资金额
        BigDecimal salary = processStepMapper.calculateSalary(processStepId, area);

        return salary;

    }



    // 查看板材信息的组合名称
    @Override
    public List<OrderModuleVO> selectPlateName(Long stepItemId) {


        List<OrderModuleVO> orderModuleVOS = processStepItemMapper.selectPlateName(stepItemId);

        for (OrderModuleVO orderModuleVO : orderModuleVOS) {
            if(orderModuleVO.getGroupName().isEmpty()){
                return orderModuleVOS;
            }

            // 修改组合名称为加工组的名称
            orderModuleVO.setName(orderModuleVO.getGroupName());
        }

        return orderModuleVOS;

    }



    // 查询生产单对应的柜体名称
    @Override
    public List<OrderBodyRespVo> selectBodyName(OrderBodyReqVO reqVO) {

        if(reqVO.getProcessType() == 7){
            // 等于 7(组件加工) ，则不返回柜体信息
            return null;
        }

        List<OrderBodyDO> orderBodyDOS = orderBodyMapper.selectListByOrderId(reqVO.getOrderId(),getUserOrganId(),null);


        return BeanUtils.toBean(orderBodyDOS, OrderBodyRespVo.class);


    }



    @Override
    public OrderPlateReqVO selectPlate(ProcessPlateReqVO reqVO) {

        OrderPlateReqVO orderPlateReqVO = new OrderPlateReqVO();

        if(reqVO.getProcessType().equals(ProcessProcessingTypeEnum.COMPONENTPROCESSING.getNumber())){

            // 等于 7(组件加工) ,根据生产单工序步骤ID查询对应的柜体ID，再根据柜体ID查询对应的板件ID

            List<OrderBodyRespVo> OrderBodyRespVos = processStepItemMapper.selectBodyIds(reqVO.getProcessStepId(),reqVO.getName(),getUserOrganId());
            List<Long> collect = OrderBodyRespVos.stream().map(m -> m.getId()).collect(Collectors.toList());
            List<PlateDetails> plateDetails = orderItemMapper.selectPlateListByBodyIds(collect, reqVO.getOrderId(), getUserOrganId());

            orderPlateReqVO.setOrderBodyRespVoList(OrderBodyRespVos);
            orderPlateReqVO.setPlateDetails(plateDetails);

            return orderPlateReqVO;

        }


        // 不等于 7(组件加工) ，现根据订单号查询所有的柜体信息
        // 进行判断，如果传入的柜体ID为空，进行详细查询，不为空，直接根据订单ID查询全部的板材信息
        if(reqVO.getBodyId() == null){

            List<OrderBodyDO> orderBodyDOS = orderBodyMapper.selectListByOrderId(reqVO.getOrderId(), getUserOrganId(),reqVO.getBodyId());

            List<OrderBodyRespVo> orderBodyRespVos = BeanUtils.toBean(orderBodyDOS, OrderBodyRespVo.class);
            // 查询全部的板材信息
            List<PlateDetails> orderPlateReqVOS = orderPlateMapper.selectListByOrderId(reqVO.getOrderId(),getUserOrganId());
            orderPlateReqVO.setOrderBodyRespVoList(orderBodyRespVos);
            orderPlateReqVO.setPlateDetails(orderPlateReqVOS);

            return orderPlateReqVO;
        }


        //  有柜体ID，进行详细查询
        List<OrderBodyDO> orderBodyDOS = orderBodyMapper.selectListByOrderId(reqVO.getOrderId(), getUserOrganId(),reqVO.getBodyId());

        List<OrderBodyRespVo> orderBodyRespVos = BeanUtils.toBean(orderBodyDOS, OrderBodyRespVo.class);

        List<PlateDetails> plateDetails = orderItemMapper.selectByOrderId(reqVO, getUserOrganId());

        orderPlateReqVO.setOrderBodyRespVoList(orderBodyRespVos);
        orderPlateReqVO.setPlateDetails(plateDetails);

        return orderPlateReqVO;


    }


}



