package com.sw.mes.yb.production.service.impl;


import com.sw.mes.base.system.entity.DictionaryItem;
import com.sw.mes.base.system.service.DictionaryItemService;
import com.sw.mes.core.annotation.ServiceLogs;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.enums.EnumValuesFactory;
import com.sw.mes.core.exception.BusinessException;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.enumvalue.SurplusStepEnum;
import com.sw.mes.yb.plan.entity.ProductionOrder;
import com.sw.mes.yb.plan.entity.ProductionSchedule;
import com.sw.mes.yb.plan.service.ProductionScheduleService;
import com.sw.mes.yb.production.dao.SurplusInfoDao;
import com.sw.mes.yb.production.dto.SurplusInfoDto;
import com.sw.mes.yb.production.entity.SurplusInfo;
import com.sw.mes.yb.production.enums.SurplusInfoStatusEnum;
import com.sw.mes.yb.production.service.SurplusInfoService;
import com.sw.mes.yb.production.utils.RecycledBatchGenerator;
import lombok.extern.slf4j.Slf4j;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.Arrays;
import java.util.Date;
import java.util.List;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
@Slf4j
public class SurplusInfoServiceImpl extends BaseServiceImpl<SurplusInfo> implements SurplusInfoService {
    SurplusInfoDao dao;

    @Autowired
    public void setDao(SurplusInfoDao dao) {
        super.setBaseDao(dao);
        this.dao = dao;
    }

    @Autowired
    ModelMapper modelMapper;

    @Autowired
    ProductionScheduleService productionScheduleService;

    @Autowired
    DictionaryItemService dictionaryItemService;

    @Autowired
    private RecycledBatchGenerator recycledBatchGenerator;

    @Override
    public SurplusInfo queryLimitInfoByDeviceNo(String deviceNo) {
        return dao.queryLimitInfoByDeviceNo(deviceNo);
    }

    @Override
    public SurplusInfo queryLimitInfoBySurplusCode(String surplusCode) {
        return dao.queryLimitInfoBySurplusCode(surplusCode);
    }

    @Override
    public SurplusInfo queryLimitInfoByLotNo(String lotNo) {
        return dao.queryLimitInfoByLotNo(lotNo);
    }

    @Override
    public SurplusInfo saveData(SurplusInfoDto surplusInfoDto) {
        String deviceNo = surplusInfoDto.getDeviceNo();
        String surplusType = surplusInfoDto.getSurplusType();

        ProductionSchedule productionSchedule = null;
        if (SurplusStepEnum.StepNameEnum.埚底.getValue().equals(surplusType) || SurplusStepEnum.StepNameEnum.焖炉.getValue().equals(surplusType)) {
            //埚底/焖炉 查找最近一次的已关闭的排程工单
            productionSchedule = productionScheduleService.findCloseByEquipmentCode(deviceNo, 2);
            if (productionSchedule == null) {
                throw new BusinessException("收集类型为:" + surplusType + ":该炉台无关闭的排程工单!");
            }
        } else {
            productionSchedule = productionScheduleService.findByEquipmentCode(deviceNo);
        }
        if (productionSchedule == null) {
            throw new BusinessException("该炉台当前无排程工单!");
        }
        ProductionOrder order = productionSchedule.getProductionOrder();
        if (order == null) {
            throw new BusinessException("该炉台当前无对应工单!");
        }
        String lotNo =productionSchedule.getLotNo();
        surplusInfoDto.setLotNo(lotNo);
        surplusInfoDto.setWorkOrderNo(order.getAufnr());
        String workOrderNo = surplusInfoDto.getWorkOrderNo();
        Integer againNum = surplusInfoDto.getFeedTimes();
        BigDecimal weight = surplusInfoDto.getWeight();
        //1 转换类型
        if (SurplusStepEnum.StepNameEnum.埚底.getValue().equals(surplusType)||SurplusStepEnum.StepNameEnum.焖炉.getValue().equals(surplusType)) {
            //卡控一个订单只能有一个坩埚或焖炉类型的数据,增加字典开关配置
            //埚底/焖炉 允许多条录入开关-0: 开 1: 关 ;默认关闭1
            String bottomOrFurnaceSwitch = "1";
            //埚底,允许焖炉转换的开关 0开 1关
            String typeChangeSwitch ="1";
            //1.1根据字典配置区分是埚底/焖炉
            DictionaryItem dictionaryItem = dictionaryItemService.findByThemeValueAndNameAndEnable("bottomOrFurnace", "埚底焖炉", true);
            if (null == dictionaryItem || StringUtils.isBlank(dictionaryItem.getValue())) {
                throw new BusinessException("请维护关键字[bottomOrFurnace]字典!");
            }
            bottomOrFurnaceSwitch = dictionaryItem.getExtendValue1();
            typeChangeSwitch = dictionaryItem.getExtendValue2();

            List<String> strings = Arrays.asList(SurplusStepEnum.StepNameEnum.埚底.getValue(), SurplusStepEnum.StepNameEnum.焖炉.getValue());
            SurplusInfo checkSurplusInfo = this.queryLimitInfoByWorkOrderNoAndSurplusType(workOrderNo, strings);
            if ("1".equals(bottomOrFurnaceSwitch) && null != checkSurplusInfo) {
                log.info("手动新增单晶余料:对应订单号:" + workOrderNo + "已存在类型:" + checkSurplusInfo.getSurplusType() + "的数据!");
                throw new BusinessException("订单号:" + workOrderNo + "已存在类型:" + checkSurplusInfo.getSurplusType() + "的数据!");
            }
            if ("0".equals(typeChangeSwitch)) {
                if (weight.compareTo(new BigDecimal(dictionaryItem.getValue())) > 0) {
                    surplusType = SurplusStepEnum.StepNameEnum.焖炉.getValue();
                } else {
                    surplusType = SurplusStepEnum.StepNameEnum.埚底.getValue();
                }
            }
        }
        //重新赋值余料类型
        surplusInfoDto.setSurplusType(surplusType);

        DictionaryItem dictionaryItem = dictionaryItemService.findByThemeValueAndNameAndEnable("ResidualType", surplusType, true);
        if (null == dictionaryItem || StringUtils.isBlank(dictionaryItem.getValue())) {
            throw new BusinessException("请维护关键字[ResidualType]字典!");
        }
        String residualTypeValue = dictionaryItem.getValue();
        //再加四位流水号
        String directionalSign = order.getZorientationind();
        String directionalSignValue = "B";
        if (StringUtils.isBlank(directionalSign)) {
            directionalSign = "非定向";
        }
        DictionaryItem directionalSignValueResult = dictionaryItemService.findByThemeValueAndNameAndEnable("creatCrystalNo", directionalSign, true);
        if (null != directionalSignValueResult) {
            if (directionalSignValueResult.getValue().length() > 1) {
                log.info("字典关键字[creatCrystalNo]词条:实际值 [" + directionalSign + "配置值异常,必须一位字符!");
            }
            directionalSignValue = directionalSignValueResult.getValue();
        } else {
            log.info("字典关键字[creatCrystalNo]词条:实际值 [" + directionalSign + "未配置!");
        }
        String surplusCode = directionalSignValue + lotNo + againNum + residualTypeValue + workOrderNo;
        String surplusCodeNo = surplusCode + recycledBatchGenerator.buildSurplusBatchNo(surplusCode);
        surplusInfoDto.setSurplusCode(surplusCodeNo);
        surplusInfoDto.setStatus(SurplusInfoStatusEnum.待入库.getKey());
        surplusInfoDto.setCreateBy(BaseContextHandler.getUsername());
        surplusInfoDto.setCreateTime(new Date());
        surplusInfoDto.setDataType(SurplusInfoStatusEnum.人工采集.getKey());
        surplusInfoDto.setDel(SurplusInfoStatusEnum.未删除.getKey());
        if (StringUtils.isBlank(order.getField4())) {
            throw new BusinessException("该炉台对应工单: [" + order.getAufnr() + "] 无成本中心!");
        }
        surplusInfoDto.setArea(order.getField4());
        SurplusInfo surplusInfo = fromDto(surplusInfoDto);
        SurplusInfo oldSurplusInfo = this.queryLimitInfoBySurplusCode(surplusCodeNo);
        if (null != oldSurplusInfo) {
            throw new BusinessException("该编号: [" + surplusCodeNo + "] 余料数据已存在");
        }
        this.saveOrUpdate(surplusInfo);
        return surplusInfo;
    }

    @Override
    public SurplusInfo queryLimitInfoByWorkOrderNoAndSurplusType(String surplusCode, List<String> surplusTypes) {
        return dao.queryLimitInfoByWorkOrderNoAndSurplusType(surplusCode, surplusTypes);
    }

    /**
     * @param originalWeight 原始重量
     * @param weight         修改后重量
     * @param recycleNo      余料单晶编号
     * @return
     */
    @Override
    @ServiceLogs(description = "比对单晶余料重量")
    public SurplusInfo updateWeightBySurplusCode(BigDecimal originalWeight, BigDecimal weight, String recycleNo) {
        if (originalWeight.compareTo(weight) != 0) {
            SurplusInfo surplusInfo = dao.queryLimitInfoBySurplusCode(recycleNo);
            if (null != surplusInfo) {
                surplusInfo.setOriginalWeight(originalWeight);
                surplusInfo.setWeight(weight);
                surplusInfo.setUpdateBy(BaseContextHandler.getUserClassNo());
                surplusInfo.setUpdateTime(new Date());
                this.saveOrUpdate(surplusInfo);
            }
            return surplusInfo;
        }
        return null;
    }


    public SurplusInfo fromDto(SurplusInfoDto dto) {
        return modelMapper.map(dto, SurplusInfo.class);
    }
}
