package com.sw.mes.itemclean.clean.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.enums.ItemCleanEnums;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.itemclean.clean.domain.MaterialReworkSignature;
import com.sw.mes.itemclean.clean.domain.MaterialReworking;
import com.sw.mes.itemclean.clean.domain.MaterialRewrkingDetail;
import com.sw.mes.itemclean.clean.domain.MaterialStoreSignBox;
import com.sw.mes.itemclean.clean.dto.batchNoOperate.BatchNoOperate;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BatchNo;
import com.sw.mes.itemclean.clean.dto.boxNoOperate.BoxNoOperate;
import com.sw.mes.itemclean.clean.dto.BoxPropertyDto;
import com.sw.mes.itemclean.clean.dto.GeneralScanBoxNoParam;
import com.sw.mes.itemclean.clean.dto.MaterialReworkSignatureDto;
import com.sw.mes.itemclean.clean.mapper.MaterialReworkSignatureMapper;
import com.sw.mes.itemclean.clean.mapper.MaterialReworkingDetailMapper;
import com.sw.mes.itemclean.clean.mapper.MaterialReworkingMapper;
import com.sw.mes.itemclean.clean.mapping.ScanBoxNoMapping;
import com.sw.mes.itemclean.clean.service.GenerateBusinessNoService;
import com.sw.mes.itemclean.clean.service.MaterialReworkSignatureService;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.sw.mes.itemclean.clean.service.MaterialReworkingDetailService;
import com.sw.mes.itemclean.clean.service.MaterialReworkingService;
import com.sw.mes.itemclean.clean.service.MaterialStoreSignBoxService;
import com.sw.mes.itemclean.clean.service.ScanBoxNoService;
import com.sw.mes.itemclean.clean.vo.MaterialReworkingVo;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 返工打签 服务实现类
 * </p>
 *
 * @author liuzemin
 * @since 2022-11-10
 */
@Service
public class MaterialReworkSignatureServiceImpl extends ServiceImpl<MaterialReworkSignatureMapper, MaterialReworkSignature> implements MaterialReworkSignatureService, ScanBoxNoService {

    @Autowired
    private MaterialStoreSignBoxService materialStoreSignBoxService;

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    private MaterialReworkingMapper materialReworkingMapper;

    @Autowired
    private MaterialReworkingDetailMapper materialReworkingDetailMapper;

    @Autowired
    private MaterialReworkingService materialReworkingService;

    @Autowired
    private MaterialReworkingDetailService materialReworkingDetailService;

    @Autowired
    GenerateBusinessNoService generateBusinessNoService;

//    @Autowired
//    private DictionaryItemDao dictionaryItemDao;

    @Override
    public BoxPropertyDto scanBoxNo(GeneralScanBoxNoParam param) {
        LambdaQueryWrapper<MaterialStoreSignBox> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(MaterialStoreSignBox::getMaterialBoxNo, param.getBoxNo());
        queryWrapper.eq(MaterialStoreSignBox::getPickingStatus, 1);
        //queryWrapper.in(MaterialStoreSignBox::getMaterialType, ItemCleanEnums.MaterialType.返工料.getKey());
        queryWrapper.last("limit 1");
        MaterialStoreSignBox box = materialStoreSignBoxService.getOne(queryWrapper);
        if (box == null) {
            throw new RuntimeException(param.getBoxNo() + "该箱号不存在！");
        }
        if (box.getIsEmptyBox() == 1) {
            throw new RuntimeException(param.getBoxNo() + "该箱号为空箱！");
        }
        if (box.getPickingStatus()==0){
            throw new RuntimeException(param.getBoxNo() + "该箱号的箱子尚未被领料！");
        }
        if (box.getDelFlag()==1){
            throw new RuntimeException(param.getBoxNo() + "该箱号的箱子已被删除！");
        }
        return ScanBoxNoMapping.toDto(box);
    }

    @Override
    public Result reworkSignature(MaterialReworkSignatureDto materialReworkSignatureDto) {
        //生成箱号、批次号
        BatchNoOperate batchNoOperate = new BatchNoOperate(ItemCleanEnums.BatchType.返工料, ItemCleanEnums.MaterialResource.valueOf(materialReworkSignatureDto.getReworkProcedure()), materialReworkSignatureDto.getMaterialCode());
        String productBatchNo = generateBusinessNoService.generateProductBatchNo(batchNoOperate);
        String materialBoxNo= generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.默认, new BatchNo(productBatchNo)));
        //成箱箱号
        materialReworkSignatureDto.setMaterialBoxNo(materialBoxNo);
        //生产批次号
        materialReworkSignatureDto.setProductBatchNo(productBatchNo);
        materialReworkSignatureDto.setCreateUser(BaseContextHandler.getUsername());
        materialReworkSignatureDto.setCreateTime(LocalDateTime.now());
        materialReworkSignatureDto.setDelFlag(0);
        MaterialReworkSignature materialReworkSignature = fromDto(materialReworkSignatureDto);
        this.saveOrUpdate(materialReworkSignature);
        //保存新的打签箱暂存表
        //旧的箱子暂时不做处理
        MaterialStoreSignBox materialStoreSignBox = toMaterialStoreSignBox(materialReworkSignatureDto);
        materialStoreSignBoxService.save(materialStoreSignBox);
        return ResultGenerator.success(materialBoxNo);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public Result reworkSignature2(MaterialReworkingVo materialReworkingVo) {

        //TODO 当前逻辑值只处理了先暂存后成箱打签的场景，要增加不暂存直接成箱打签的场景
        BatchNoOperate batchNoOperate = new BatchNoOperate(ItemCleanEnums.BatchType.返工料, ItemCleanEnums.MaterialResource.valueOf(materialReworkingVo.getReworkProcedure()), materialReworkingVo.getMaterialCode());
        String productBatchNo = generateBusinessNoService.generateProductBatchNo(batchNoOperate);
        String materialBoxNo= generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.默认,new BatchNo(productBatchNo)));

        //1保存返工打签记录
        MaterialReworkSignature materialReworkSignature = new MaterialReworkSignature();
        materialReworkSignature.setReworkWeight(materialReworkingVo.getReworkWeight());
        materialReworkSignature.setReworkProcedure(materialReworkingVo.getReworkProcedure());
        materialReworkSignature.setReworkDesc(materialReworkingVo.getReworkDesc());
        materialReworkSignature.setNote(materialReworkingVo.getNote());
        if (materialReworkingVo.getMaterialRewrkingDetails().size()>0){
            StringBuilder stringBuilder = new StringBuilder();
            for (MaterialRewrkingDetail materialRewrkingDetail : materialReworkingVo.getMaterialRewrkingDetails()) {
                if (!materialRewrkingDetail.getReworkingBoxNo().isEmpty()){
                    stringBuilder.append(materialRewrkingDetail.getReworkingBoxNo()+" ");
                }
            }
            if (StringUtils.isNotEmpty(stringBuilder.toString())){
                materialReworkSignature.setReworkBoxNo(stringBuilder.toString());//返工箱号（原箱号，可能多个）
            }
            if (!materialReworkingVo.getMaterialRewrkingDetails().get(0).getProductBatchNo().isEmpty()){
                materialReworkSignature.setReworkProductBatchNo(materialReworkingVo.getMaterialRewrkingDetails().get(0).getProductBatchNo());//原生产批次号
            }
        }else {
            throw new RuntimeException("返工打签明细信息缺失！无法操作打签成箱");
        }
        //箱号、批次号要重新赋值
        materialReworkSignature.setProductBatchNo(productBatchNo);//成箱批次号
        materialReworkSignature.setMaterialBoxNo(materialBoxNo);//成箱箱号
        materialReworkSignature.setMaterialName(materialReworkingVo.getMaterialName());
        materialReworkSignature.setMaterialCode(materialReworkingVo.getMaterialCode());
        materialReworkSignature.setMaterialModel(materialReworkingVo.getMaterialModel());
        materialReworkSignature.setMaterialLevel(materialReworkingVo.getMaterialLevel());
        materialReworkSignature.setMaterialGear(materialReworkingVo.getMaterialGear());
        materialReworkSignature.setCreateUser(BaseContextHandler.getUsername());
        materialReworkSignature.setCreateTime(LocalDateTime.now());
        materialReworkSignature.setDelFlag(0);
        this.saveOrUpdate(materialReworkSignature);
        //2更新返工暂存打签主表为“非暂存”状态
        MaterialReworking materialReworking = fromVo(materialReworkingVo);
        materialReworking.setStagingFlag(0);
        if (materialReworking.getMaterialBoxNo()!=null){
            materialReworkingService.saveOrUpdate(materialReworking);
        }
        //3，保存新的打签箱暂存表
        //旧的箱子暂时不做处理
        MaterialStoreSignBox materialStoreSignBox = toMaterialStoreSignBox2(materialReworkSignature);
        materialStoreSignBoxService.save(materialStoreSignBox);
        return ResultGenerator.success(materialReworkingVo.getMaterialBoxNo());
    }

    public MaterialReworking fromVo(MaterialReworkingVo vo) {
        return modelMapper.map(vo, MaterialReworking.class);
    }

    /**
     * 返工打签暂存
     * @param materialReworkingVo
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    //暂存，主表与附表通过成箱箱号这个字段连接，一对多
    public int createStorageSign(MaterialReworkingVo materialReworkingVo) {
        MaterialReworking materialReworking = fromVo(materialReworkingVo);

        //新增，不传主表id
        if(materialReworkingVo.getMaterialBoxNo()==null){
            //主表信息
            BatchNoOperate batchNoOperate = new BatchNoOperate(ItemCleanEnums.BatchType.返工料, ItemCleanEnums.MaterialResource.valueOf(materialReworkingVo.getReworkProcedure()), materialReworkingVo.getMaterialCode());
            String productBatchNo = generateBusinessNoService.generateProductBatchNo(batchNoOperate);
            String materialBoxNo= generateBusinessNoService.generateBoxNo(new BoxNoOperate(ItemCleanEnums.BoxNoType.默认,new BatchNo(productBatchNo)));
            materialReworking.setMaterialBoxNo(materialBoxNo);
            materialReworking.setProductBatchNo(productBatchNo);
            materialReworking.setCreateUser(BaseContextHandler.getUsername());
            materialReworking.setCreateTime(LocalDateTime.now());
            materialReworking.setStagingFlag(1);
            materialReworking.setDelFlag(0);
            materialReworking.setWeight(materialReworkingVo.getReworkWeight());
            materialReworkingService.saveOrUpdate(materialReworking);

            //附表信息
            List<MaterialRewrkingDetail> materialRewrkingDetails = materialReworkingVo.getMaterialRewrkingDetails();
            for(MaterialRewrkingDetail materialRewrkingDetail:materialRewrkingDetails){
                materialRewrkingDetail.setMaterialBoxNo(materialBoxNo);
                materialRewrkingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialRewrkingDetail.setCreateTime(LocalDateTime.now());
                materialRewrkingDetail.setDelFlag(0);
                materialRewrkingDetail.setMaterialType(materialRewrkingDetail.getMaterialType());
                // 更新原箱子的“是否空箱”字段
                MaterialStoreSignBox box = materialStoreSignBoxService.getByBoxNo(materialRewrkingDetail.getReworkingBoxNo());
                if (box!=null && !box.getIsEmptyBox().equals(materialRewrkingDetail.getIsEmptyBox())){
                    box.setIsEmptyBox(materialRewrkingDetail.getIsEmptyBox());
                    materialStoreSignBoxService.saveOrUpdate(box);
                }
            }
            //批量插入附表信息
            materialReworkingDetailService.insertReworkingDetails(materialRewrkingDetails);
        }else{
            //更新，需要传主表id
            if (materialReworkingVo.getId()==null){
                throw new RuntimeException("更新暂存打签参数id不能为空！");
            }
            //修改
            materialReworking.setWeight(materialReworkingVo.getReworkWeight());
            materialReworking.setUpdateUser(BaseContextHandler.getUsername());
            materialReworking.setUpdateTime(LocalDateTime.now());
            LambdaQueryWrapper<MaterialReworking> updataWrapper = new LambdaQueryWrapper<>();
            updataWrapper.eq(MaterialReworking::getMaterialBoxNo,materialReworking.getMaterialBoxNo());
            materialReworkingMapper.update(materialReworking,updataWrapper);
            //materialReworkingMapper.updateById(materialReworking);

            //删除附表相关子数据
            LambdaQueryWrapper<MaterialRewrkingDetail> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(MaterialRewrkingDetail::getMaterialBoxNo, materialReworking.getMaterialBoxNo());
            materialReworkingDetailMapper.delete(queryWrapper);

            //插入新的附表数据
            List<MaterialRewrkingDetail> materialRewrkingDetails = materialReworkingVo.getMaterialRewrkingDetails();

            for(MaterialRewrkingDetail materialRewrkingDetail:materialRewrkingDetails){
                materialRewrkingDetail.setCreateUser(BaseContextHandler.getUsername());
                materialRewrkingDetail.setCreateTime(LocalDateTime.now());
                materialRewrkingDetail.setUpdateUser(BaseContextHandler.getUsername());
                materialRewrkingDetail.setUpdateTime(LocalDateTime.now());
                materialRewrkingDetail.setDelFlag(0);
                materialRewrkingDetail.setMaterialBoxNo(materialReworking.getMaterialBoxNo());
                materialRewrkingDetail.setMaterialType(materialRewrkingDetail.getMaterialType());
                //更新原箱子的“是否空箱”字段
                MaterialStoreSignBox box = materialStoreSignBoxService.getByBoxNo(materialRewrkingDetail.getReworkingBoxNo());
                if (box!=null && !box.getIsEmptyBox().equals(materialRewrkingDetail.getIsEmptyBox())){
                    box.setIsEmptyBox(materialRewrkingDetail.getIsEmptyBox());
                    materialStoreSignBoxService.saveOrUpdate(box);
                }
            }
            //批量插入附表信息
            materialReworkingDetailService.insertReworkingDetails(materialRewrkingDetails);

        }
        return 1;
    }

    public MaterialReworkSignature fromDto(MaterialReworkSignatureDto dto) {
        return modelMapper.map(dto, MaterialReworkSignature.class);
    }
    public MaterialStoreSignBox toMaterialStoreSignBox(MaterialReworkSignatureDto materialReworkSignatureDto){
        MaterialStoreSignBox materialStoreSignBox = modelMapper.map(materialReworkSignatureDto, MaterialStoreSignBox.class);
        materialStoreSignBox.setMaterialType(4);
        materialStoreSignBox.setPickingStatus(0);
        materialStoreSignBox.setDelFlag(0);
        return materialStoreSignBox;
    }

    public MaterialStoreSignBox toMaterialStoreSignBox2(MaterialReworkSignature materialReworkSignature){
        MaterialStoreSignBox materialStoreSignBox = modelMapper.map(materialReworkSignature, MaterialStoreSignBox.class);
        materialStoreSignBox.setMaterialType(4);
        materialStoreSignBox.setPickingStatus(0);
        materialStoreSignBox.setDelFlag(0);
        materialStoreSignBox.setId(null);
        if (materialReworkSignature.getReworkProcedure()!=null && !materialReworkSignature.getReworkProcedure().equals("")){
            //返工工序
            switch (materialReworkSignature.getReworkProcedure()){
                case"清洗":materialStoreSignBox.setMaterialResource(1);break;
                case "循环料破碎":materialStoreSignBox.setMaterialResource(2);break;
                case "多晶破碎":materialStoreSignBox.setMaterialResource(3);break;
                case "分选":materialStoreSignBox.setMaterialResource(4);break;
            }
        }
        //TODO查数据字段，根据工序名称得到值
        //Integer reworkProcedureCode = dictionaryItemDao.findExtendValueByThemeValueAndItemName("reworkProcedure", materialReworkSignature.getReworkProcedure());
        //materialStoreSignBox.setMaterialResource(reworkProcedureCode);
        return materialStoreSignBox;
    }
}
