package com.sw.mes.sap.service.impl;


import cn.hutool.core.convert.Convert;
import com.sw.mes.base.erp.entity.ErpOrder;
import com.sw.mes.base.erp.service.ErpOrderService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.material.service.MaterialModelService;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.core.dto.erp.ErpAddResultDto;
import com.sw.mes.core.dto.erp.ErpRequestDto;
import com.sw.mes.core.entity.MesToErpCkdDetailEntity;
import com.sw.mes.core.entity.MesToErpCkdEntity;
import com.sw.mes.core.enums.ErpEnum;
import com.sw.mes.core.enums.ErpPypeEnum;
import com.sw.mes.core.response.Result;
import com.sw.mes.core.response.ResultCode;
import com.sw.mes.core.response.ResultGenerator;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.StringUtils;
import com.sw.mes.sap.dao.ReportErpSquareOutputRecordDao;
import com.sw.mes.sap.entity.ReportErpOutputRecordDetail;
import com.sw.mes.sap.entity.ReportErpSquareOutputRecord;
import com.sw.mes.sap.entity.ReportErpSquareOutputRecordDetail;
import com.sw.mes.sap.service.ReportErpOutputRecordDetailService;
import com.sw.mes.sap.service.ReportErpSquareOutputRecordDetailService;
import com.sw.mes.sap.service.ReportErpSquareOutputRecordService;
import com.sw.mes.third.utils.ErpRequestUtil;
import com.sw.mes.yb.plan.entity.FbProductionOrder;
import com.sw.mes.yb.plan.entity.ProductionOrder;
import com.sw.mes.yb.plan.service.FbProductionOrderService;
import com.sw.mes.yb.plan.service.ProductionOrderService;
import com.sw.mes.yb.production.entity.LongCrystal;
import com.sw.mes.yb.production.service.LongCrystalService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.TimeUnit;


/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
public class ReportErpSquareOutputRecordServiceImpl extends BaseServiceImpl<ReportErpSquareOutputRecord> implements ReportErpSquareOutputRecordService {


    @Autowired
    private ReportErpSquareOutputRecordService reportErpSquareOutputRecordService;

    @Autowired
    private ReportErpSquareOutputRecordDetailService reportErpSquareOutputRecordDetailService;

    @Autowired
    private ReportErpOutputRecordDetailService reportErpOutputRecordDetailService;

    @Autowired
    private ErpRequestUtil erpRequestUtil;

    @Autowired
    private LongCrystalService longCrystalService;

    @Autowired
    private ProductionOrderService productionOrderService;

    @Autowired
    private FbProductionOrderService fbProductionOrderService;

    @Autowired
    private MaterialModelService materialModelService;

    @Autowired
    private ErpOrderService erpOrderService;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Value("${spring.erpServiceUrl}")
    private String erpServiceUrl;


    ReportErpSquareOutputRecordDao dao;

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

    @Override
    public Result reportForWork(ReportErpSquareOutputRecord reportErpSquareOutputRecord) {

        ErpRequestDto erpRequestDto = packageData(reportErpSquareOutputRecord);

        ErpAddResultDto erpAddResultDto = erpRequestUtil.postToErp(erpRequestDto);
        if (null != erpAddResultDto) {
            if (null != erpAddResultDto.getErrcode() && erpAddResultDto.getErrcode().equals(String.valueOf(ResultCode.SUCCESS.getCode()))) {
                reportErpSquareOutputRecord.setPushed(1);
                reportErpSquareOutputRecord.setPushTime(new Date());
                reportErpSquareOutputRecord.setPushUser(BaseContextHandler.getUsername());
                reportErpSquareOutputRecord.setSerial(erpAddResultDto.getCcode());
                reportErpSquareOutputRecord.setPushSerial(erpRequestDto.getMesToErpCkdEntity().getCbatch());
                reportErpSquareOutputRecord.setDepartmentCode(erpRequestDto.getMesToErpCkdEntity().getCdepname());
                reportErpSquareOutputRecordService.saveOrUpdate(reportErpSquareOutputRecord);

                List<ReportErpSquareOutputRecordDetail> byRid = reportErpSquareOutputRecordDetailService.findByRid(reportErpSquareOutputRecord.getId());
                for (ReportErpSquareOutputRecordDetail reportErpSquareOutputRecordDetail : byRid) {
                    reportErpSquareOutputRecordDetail.setReportWorkState(1);
                    reportErpSquareOutputRecordDetail.setReportWorkTime(new Date());
                    reportErpSquareOutputRecordDetail.setBatchNo(erpAddResultDto.getCcode());
                    reportErpSquareOutputRecordDetail.setPushBatchNo(erpRequestDto.getMesToErpCkdEntity().getCbatch());
                    reportErpSquareOutputRecordDetailService.saveOrUpdate(reportErpSquareOutputRecordDetail);

                    LongCrystal byCrystalNo = longCrystalService.findByCrystalNo(reportErpSquareOutputRecordDetail.getCrystalNo());
                    byCrystalNo.setSquarePushed(1);
                    longCrystalService.saveOrUpdate(byCrystalNo);
                }
                return ResultGenerator.success("上报成功");
            }
        }
        return ResultGenerator.fail(erpAddResultDto.getErrmsg());
    }

    private ErpRequestDto packageData(ReportErpSquareOutputRecord reportErpSquareOutputRecord) {
        ErpRequestDto erpRequestDto = new ErpRequestDto();
        erpRequestDto.setUrl(erpServiceUrl);

        MesToErpCkdEntity mesToErpCkdEntity = new MesToErpCkdEntity();
        String orderNo = reportErpSquareOutputRecord.getOrderNo();
        ProductionOrder byeErpOrderNo = productionOrderService.findByFbOrderNo(orderNo);
        FbProductionOrder byAufnr = fbProductionOrderService.findByAufnr(orderNo);

        MaterialModel byCode = new MaterialModel();

        if (null != byeErpOrderNo) {
            String date = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//            String date1 = LocalDate.now().format(DateTimeFormatter.ofPattern("yyMMdd"));
            String date1 = DateUtil.packageDocDate(reportErpSquareOutputRecord.getCreateTime());
            String number = getNumber(date);
            String batchNo = null;
            if(byeErpOrderNo.getAuart().equals("研发")){
                batchNo = byeErpOrderNo.getRdonlylogo() + "-" + date1;
            } else {
                batchNo = date1 + "1202" + number + "-" + byeErpOrderNo.getProductType() + byeErpOrderNo.getSideLengthRange();
            }
            //todo 批次号按样单拼接数据   目前拼接存在问题
            mesToErpCkdEntity.setCbatch(batchNo);

            //部门编号  无问题（数据库已填充该数据）
            if(byeErpOrderNo.getAuart().equals("研发")){
                mesToErpCkdEntity.setCdepcode("18");
            } else {
                mesToErpCkdEntity.setCdepcode("1202");
            }
            //部门名称
//            mesToErpCkdEntity.setCdepname(byeErpOrderNo.getWorkShop());
        }
        if(null != byAufnr){
            //需根据方棒订单查到物料编号
            mesToErpCkdEntity.setCinvcode(byAufnr.getMatnr());
            //todo 订单id暂时不对
            mesToErpCkdEntity.setIproorderid(byAufnr.getTid());
            //新封装数据
            mesToErpCkdEntity.setImquantity(String.valueOf(byAufnr.getMenge()));
            mesToErpCkdEntity.setCpspcode(byAufnr.getMatnr());
            byCode = materialModelService.findByCode(byAufnr.getMatnr());
            mesToErpCkdEntity.setInvname(byCode.getName());
            mesToErpCkdEntity.setCinvstd(byCode.getSpecification());
            mesToErpCkdEntity.setImoseq(byCode.getUnit().getCode());
        }
        mesToErpCkdEntity.setCdepname("开方一车间");
        mesToErpCkdEntity.setCmpocode(orderNo);
        mesToErpCkdEntity.setErpType(ErpPypeEnum.机加投入.getKey());
        mesToErpCkdEntity.setCrdcode(reportErpSquareOutputRecord.getReceiveCode());

        //todo 有疑问？？？
        mesToErpCkdEntity.setCwhcode(reportErpSquareOutputRecord.getWarehouseCode());
        mesToErpCkdEntity.setCwhname(String.valueOf(ErpEnum.WarehouseName.机加车间.getValue()));

        //无问题
        mesToErpCkdEntity.setIquantity(reportErpSquareOutputRecord.getQuantity().toString());
        mesToErpCkdEntity.setDocTime(reportErpSquareOutputRecord.getCreateTime());


        List<MesToErpCkdDetailEntity> mesToErpCkdDetailEntityList = new ArrayList<>();
        List<ReportErpSquareOutputRecordDetail> byRid = reportErpSquareOutputRecordDetailService.findByRid(reportErpSquareOutputRecord.getId());
        if(!CollectionUtils.isEmpty(byRid)){
            for (ReportErpSquareOutputRecordDetail reportErpSquareOutputRecordDetail : byRid) {
                MesToErpCkdDetailEntity mesToErpCkdDetailEntity = new MesToErpCkdDetailEntity();

                mesToErpCkdDetailEntity.setInvname(byCode.getName());
                mesToErpCkdDetailEntity.setInvstd(byCode.getSpecification());
                ProductionOrder byeErpOrderNo1 = productionOrderService.findByeErpOrderNo(reportErpSquareOutputRecordDetail.getOrderNo());
                MaterialModel byCode1 = materialModelService.findByCode(byeErpOrderNo1.getMatnr());
                if(null != byCode1.getMaterialType()){
                    mesToErpCkdDetailEntity.setCinvccode(byCode1.getMaterialType().getName());
                }
                mesToErpCkdDetailEntity.setCinvcode(byCode1.getCode());
                mesToErpCkdDetailEntity.setCinvm_unit(byCode1.getUnit().getName());
                mesToErpCkdDetailEntity.setCinvname(byCode1.getName());
                mesToErpCkdDetailEntity.setCinvstd(byCode1.getSpecification());
                //取生产订单
                mesToErpCkdDetailEntity.setImoseq(byeErpOrderNo1.getAufnr());
                //todo 查询工单信息表【erp_order】 此处有疑问？？？
                ErpOrder erpOrder = new ErpOrder();
                List<ErpOrder> byModIdAndInCode1 = erpOrderService.findByModIdAndInvCode1(byeErpOrderNo1.getModid(), byCode1.getMatnr());
                if(!CollectionUtils.isEmpty(byModIdAndInCode1)){
                    erpOrder = byModIdAndInCode1.get(0);
                }
                mesToErpCkdDetailEntity.setImpoids(String.valueOf(erpOrder.getComponentId()));
                mesToErpCkdDetailEntity.setInquantity(String.valueOf(erpOrder.getIssQty()));
//                mesToErpCkdDetailEntity.setIquantity(String.valueOf(erpOrder.getAuxQty()));

                mesToErpCkdDetailEntity.setIquantity(String.valueOf(reportErpSquareOutputRecordDetail.getWeight()));//默认0
                mesToErpCkdDetailEntity.setIorderdid(String.valueOf(erpOrder.getIorderdid()));
                //默认1
                mesToErpCkdDetailEntity.setIrowno(String.valueOf(erpOrder.getIrowno()));
                //默认1
                mesToErpCkdDetailEntity.setIpesoseq(String.valueOf(erpOrder.getIpesoseq()));
//                mesToErpCkdDetailEntity.setIpesodid();
//                mesToErpCkdDetailEntity.setBcanreplace();

                ReportErpOutputRecordDetail byCrystalNo = reportErpOutputRecordDetailService.findByCrystalNo(reportErpSquareOutputRecordDetail.getCrystalNo());
                if(null != byCrystalNo){
                    mesToErpCkdDetailEntity.setCbatch(byCrystalNo.getBatchNo());
                } else {
                    throw new RuntimeException("未查询到长晶棒产成品报工批次");
                }
//                mesToErpCkdDetailEntity.setCbatchproperty9();
                mesToErpCkdDetailEntityList.add(mesToErpCkdDetailEntity);
            }
        }
        //子键详情
        mesToErpCkdEntity.setMesToErpCkdDetailEntitys(mesToErpCkdDetailEntityList);

        erpRequestDto.setMesToErpCkdEntity(mesToErpCkdEntity);
        return erpRequestDto;
    }

    private String getNumber(String date) {
        String key = "crystal_square_seq:" + date;
        String serialNumber =  redisTemplate.opsForValue().get(key);
        if(StringUtils.isBlank(serialNumber)){
            serialNumber="1";
            redisTemplate.opsForValue().set(key, serialNumber, 2L, TimeUnit.DAYS);

        }else{
            Long increment = redisTemplate.opsForValue().increment(key);
            redisTemplate.expire(key, 2L, TimeUnit.DAYS);
            serialNumber = Convert.toStr(increment);
        }
        int sequence = Convert.toInt(serialNumber);
        String strSequence = Convert.toStr(sequence);
        strSequence = StringUtils.leftPad(strSequence, 2, "0");
        return strSequence;
    }
}
