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

import com.sw.mes.agv.constant.IPCRequest;
import com.sw.mes.agv.entity.MonitorEquipmentCharge;
import com.sw.mes.agv.service.MonitorEquipmentChargeService;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.context.BaseContextHandler;
import com.sw.mes.base.factory.material.dao.MaterialModelDao;
import com.sw.mes.third.service.SapGiService;
import com.sw.mes.third.service.SendWebService;
import com.sw.mes.yb.pc.dao.CrucibleCheckDataDAO;
import com.sw.mes.yb.pc.dao.StoreMixInfoDao;
import com.sw.mes.yb.pc.dao.StoreMixInfoItemDao;
import com.sw.mes.yb.pc.dto.StoreMixInfoDto;
import com.sw.mes.yb.pc.entity.CrucibleCheckData;
import com.sw.mes.yb.pc.entity.StoreMixInfo;
import com.sw.mes.yb.pc.entity.StoreMixInfoItem;
import com.sw.mes.yb.pc.service.CrucibleCheckDataService;
import com.sw.mes.yb.pc.service.StoreMixInfoItemService;
import com.sw.mes.yb.pc.service.StoreMixInfoService;
import com.sw.mes.yb.plan.dao.ProductionOrderDao;
import com.sw.mes.yb.plan.dao.ProductionScheduleDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.modelmapper.ModelMapper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.validation.Valid;
import java.math.BigDecimal;
import java.util.*;

/**
 * @Author
 * @Description：
 * @Date: Create in
 * @Modified By:
 */
@Service
@Transactional
@Slf4j
public class StoreMixInfoServiceImpl extends BaseServiceImpl<StoreMixInfo> implements StoreMixInfoService {
    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Autowired
    ModelMapper modelMapper;

    StoreMixInfoDao dao;

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

//    @Autowired
//    StoreInventoryDetailService storeInventoryDetailService;

    @Autowired
    StoreMixInfoItemDao storeMixInfoItemDao;

//    @Autowired
//    StoreOutputBillService storeOutputBillService;
//
//    @Autowired
//    StoreOutputApplyService storeOutputApplyService;

    @Autowired
    private MonitorEquipmentChargeService monitorChargeService;


    @Autowired
    private CrucibleCheckDataService crucibleCheckDataService;

    @Autowired
    private ProductionScheduleDao sapProductionScheduleDao;

    @Autowired
    private SendWebService sendWebService;

    @Autowired
    private MaterialModelDao materialModelDao;

    @Autowired
    private SapGiService sapGiService;

    @Autowired
    private StoreMixInfoItemService storeMixInfoItemService;

    @Autowired
    private ProductionOrderDao sapProductionOrderDao;

    @Autowired
    private CrucibleCheckDataDAO crucibleCheckDataDAO;

    @Override
    public void saveOrUpdate(@Valid StoreMixInfoDto storeMixInfoDto) throws RuntimeException {
//
//        String lotNo = storeMixInfoDto.getLotNo();
//        //SAP订单号
//        String sapOrderNo = storeMixInfoDto.getSapOrderNo();
//        String sapDate = SapUtil.getDateNowForSap(540);
//        if (StringUtils.isBlank(lotNo)) {
//            throw new RuntimeException("炉次号不能为空！");
//        }
//        if (StringUtils.isBlank(sapOrderNo)) {
//            throw new RuntimeException("SAP订单号不能为空！");
//        }
//        if (lotNo.length() != 9 || !lotNo.contains(storeMixInfoDto.getDeviceNo())) {
//            throw new RuntimeException("炉次号格式错误，请联系管理员！");
//        }
//
//        ProductionOrder sapProductionOrder = sapProductionOrderDao.getByAufnrAndDate(sapOrderNo, sapDate);
//        if (sapProductionOrder == null) {
//            throw new RuntimeException("SAP订单号不存在或不是当前时间段的订单！");
//        }
//        //SAP订单物料号
//        String sapProductNo = sapProductionOrder.getMatnr();
//
//        StoreMixInfo storeMixInfo = modelMapper.map(storeMixInfoDto, StoreMixInfo.class);
//        storeMixInfo.setCreateUserId(BaseContextHandler.getUserID());
//        storeMixInfo.setCreateUserName(BaseContextHandler.getUsername());
//        storeMixInfo.setCreateTime(new Date());
//
//        List<StoreMixInfoItem> storeMixInfoItems = new ArrayList<>();
//
//        List<StoreMixInfoItemDto> storeMixInfoItemDtos = storeMixInfoDto.getStoreMixInfoItemDtos();
//        Map<String, BigDecimal> detailMap = new HashMap<>();
//        for (StoreMixInfoItemDto itemDto : storeMixInfoItemDtos) {
//            StoreMixInfoItem infoItem = modelMapper.map(itemDto, StoreMixInfoItem.class);
//            infoItem.setId(null);
//            String detailKey = itemDto.getGoodsCode() + itemDto.getStoreLocationId();
//            BigDecimal count;
//            if (detailMap.containsKey(detailKey)) {
//                count = detailMap.get(detailKey);
//            } else {
//                StoreInventoryDetail storeInventoryDetail = storeInventoryDetailService.findByGoodsCodeAndLocationId(itemDto.getGoodsCode(), itemDto.getStoreLocationId());
//                if (storeInventoryDetail == null) {
//                    throw new RuntimeException("未发现库存,无法完成出库");
//                }
//                count = storeInventoryDetail.getCount();
//            }
//            storeInventoryDetailTest(infoItem, count);
//            detailMap.put(detailKey, count);
//            infoItem.setStoreMixInfo(storeMixInfo);
//            infoItem.setIsGi(0);
//            storeMixInfoItems.add(infoItem);
//        }
//
//        saveOrUpdate(storeMixInfo);
//
//        if (storeMixInfoItems.size() > 0) {
//            storeMixInfoItemDao.saveAll(storeMixInfoItems);
//        }
//        String deviceNo = storeMixInfoDto.getDeviceNo();
//        if (StringUtils.isNotBlank(deviceNo) && deviceNo.length() == 3) {
////            deviceNo = deviceNo.substring(4, 7);
//            MonitorEquipmentCharge charge = monitorChargeService.getByName(deviceNo);
//            if (charge != null) {
//                charge.setSlingState(IPCRequest.YIPEILIAO);
//                charge.setSixInfo(1);
//                monitorChargeService.saveOrUpdate(charge);
//            }
//        }
//
//        // 生成炉次数据
//        batchInfoService.initBatchInfo(storeMixInfo);
//
//        ProductionSchedule sapProductionScheduleCheckEntity = sapProductionScheduleDao.getByLotNo(storeMixInfoDto.getLotNo());
//        //炉次号不存在排程
//        if (sapProductionScheduleCheckEntity == null) {
//            //doProductionSchedule(storeMixInfoDto, storeMixInfoItemDtos, lotNo, sapOrderNo, sapProductNo);
//            doProductionSchedule(storeMixInfoDto, sapOrderNo, sapProductNo);
//        }
    }

    public void doProductionSchedule(StoreMixInfoDto storeMixInfoDto, String sapOrderNo, String sapProductNo) {
    }

    @Override
    public StoreMixInfo findByCode(String code) {
        List<StoreMixInfo> storeMixInfos = dao.findByCode(code);
        if (storeMixInfos != null && storeMixInfos.size() > 0) {
            return storeMixInfos.get(0);
        }
        return null;
    }

    @Override
    public void StoreOutput(String code) {
    }

    @Override
    public List<Map<String, Object>> reportPreMaterials(String lotNo, String device, String series, String ggSupplier, String date1, String date2, Long start, Integer rows) {
        return this.dao.reportPreMaterials(lotNo, device, series, ggSupplier, date1, date2, start, rows);
    }

    @Override
    public List<Map<String, Object>> countPreMaterials(String lotNo, String device, String series, String ggSupplier, String date1, String date2) {
        return this.dao.countPreMaterials(lotNo, device, series, ggSupplier, date1, date2);
    }

    @Override
    public List<Map<String, Object>> materialsUse(String device, String modelName, String date1, String date2, Long start, Integer rows) {
        return this.dao.materialsUse(device, modelName, date1, date2, start, rows);
    }

    @Override
    public List<Map<String, Object>> countMaterialsUse(String device, String modelName, String date1, String date2) {
        return this.dao.countMaterialsUse(device, modelName, date1, date2);
    }

    @Override
    public void change(@Valid StoreMixInfoDto storeMixInfoDto) throws RuntimeException {
        String lotNo = storeMixInfoDto.getLotNo();
        if (StringUtils.isBlank(lotNo)) {
            throw new RuntimeException("炉次号不能为空！");
        }
        if (lotNo.length() != 9 || !lotNo.contains(storeMixInfoDto.getDeviceNo())) {
            throw new RuntimeException("炉次号格式错误，请联系管理员！");
        }

        String code = storeMixInfoDto.getCode();
        if (StringUtils.isBlank(code)) {
            throw new RuntimeException("坩埚编号不能为空！");
        }

        StoreMixInfo storeMixInfo = modelMapper.map(storeMixInfoDto, StoreMixInfo.class);
        storeMixInfo.setCreateUserId(BaseContextHandler.getUserID());
        storeMixInfo.setCreateUserName(BaseContextHandler.getUsername());
        storeMixInfo.setCreateTime(new Date());
        storeMixInfo.setStoreOutputApplyId(null);

//        // 修改炉次信息
//        batchInfoService.initBatchInfo(storeMixInfo);

        //待配料信息
        String deviceNo = storeMixInfoDto.getDeviceNo();
        MonitorEquipmentCharge charge = monitorChargeService.getByName(deviceNo);
        if (charge != null) {
            charge.setSlingState(IPCRequest.YIPEILIAO);
            charge.setSixInfo(1);
            monitorChargeService.saveOrUpdate(charge);
        }

        saveOrUpdate(storeMixInfo);

        crucibleCheckDataService.updateLotNo(code, lotNo);
    }

    @Override
    public Long countByCode(String code) {
        return this.dao.countByCode(code);
    }

    @Override
    public Long countByLotNo(String lotNo) {
        return this.dao.countByLotNo(lotNo);
    }

    @Override
    public StoreMixInfo findByLotNo(String lotNo) {
        List<StoreMixInfo> list = dao.findByLotNo(lotNo);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }
        return null;
    }

    @Override
    public void deleteByMainId(Integer id) {
        StoreMixInfo mixInfo = dao.getOne(id);
        if (mixInfo != null) {
            CrucibleCheckData crucibleCheckData = crucibleCheckDataService.getByCode(mixInfo.getCode());
            if (crucibleCheckData != null) {
                throw new RuntimeException("坩埚[" + mixInfo.getCode() + "]已点检完成！");
            }
            MonitorEquipmentCharge charge = monitorChargeService.getByName(mixInfo.getDeviceNo());
            if (charge != null) {
                charge.setSlingState(IPCRequest.ZHUANGLIAOHUJIAO);
                charge.setSixInfo(0);
                monitorChargeService.saveOrUpdate(charge);
            }
            dao.deleteById(id);
            storeMixInfoItemService.deleteByStoreMixInfo_Id(id);
            //删除排程记录
            //sapProductionScheduleDao.deleteByLotNo(mixInfo.getLotNo());
        }
    }

    @Override
    public String findSapOrderNoByDeviceNo(String name) {
        return dao.findSapOrderNoByDeviceNo(name);
    }

    @Override
    public void exchange(StoreMixInfo storeMixInfoOld, StoreMixInfo storeMixInfoNew) {
        String oldDeviceNo = storeMixInfoOld.getDeviceNo();
        String oldCode = storeMixInfoOld.getLotNo();
        String oldSapOderNo = storeMixInfoOld.getSapOrderNo();
        String newCode = storeMixInfoNew.getLotNo();
        storeMixInfoOld.setLotNo(storeMixInfoNew.getLotNo());
        storeMixInfoOld.setDeviceNo(storeMixInfoNew.getDeviceNo());
        storeMixInfoOld.setSapOrderNo(storeMixInfoNew.getSapOrderNo());
        storeMixInfoNew.setLotNo(oldCode);
        storeMixInfoNew.setDeviceNo(oldDeviceNo);
        storeMixInfoNew.setSapOrderNo(oldSapOderNo);
        saveOrUpdate(storeMixInfoNew);
        saveOrUpdate(storeMixInfoOld);
        //更新点检记录表
        Long oldId = crucibleCheckDataDAO.getIdByLotNo(oldCode);
        crucibleCheckDataDAO.changeLotNo(newCode,oldCode);
        if (oldId != null){
            crucibleCheckDataDAO.changeLotNoById(String.valueOf(oldId.intValue()), newCode);
        }
//        // 修改炉次信息
//        batchInfoService.initBatchInfo(storeMixInfoOld);
//        batchInfoService.initBatchInfo(storeMixInfoNew);
    }

    @Override
    public void changeDeviceNo(StoreMixInfo storeMixInfos, String newCode, String newDeviceNo) {
//        String oldCode = storeMixInfos.getLotNo();
//        storeMixInfos.setLotNo(newCode);
//        storeMixInfos.setDeviceNo(newDeviceNo);
//        saveOrUpdate(storeMixInfos);
//        //更新点检记录表
//        crucibleCheckDataDAO.changeLotNo(oldCode, newCode);
//        // 修改炉次信息
//       // batchInfoService.initBatchInfo(storeMixInfos);
//        //region 处理SAP订单相关生成新炉次号排程
//        //获取原炉次号排程
//        ProductionSchedule oldProductionSchedule = sapProductionScheduleDao.getByLotNo(oldCode);
//        if(oldProductionSchedule!=null){
//            //查询新炉次号是否有排程
//            ProductionSchedule newProductionSchedule = sapProductionScheduleDao.getByLotNo(newCode);
//            if(newProductionSchedule==null){
//                //生成新炉次号的排程
//                ProductionSchedule sapProductionScheduleEntity = new ProductionSchedule();
//                BeanUtils.copyProperties(oldProductionSchedule, sapProductionScheduleEntity);
//                sapProductionScheduleEntity.setId(null);
//                sapProductionScheduleEntity.setLotNo(newCode);
//                sapProductionScheduleEntity.setDeviceNo(newDeviceNo);
//                sapProductionScheduleEntity.setCreateTime(new Date());
//                sapProductionScheduleEntity.setCreateBy("自动创建");
//                sapProductionScheduleEntity.setStatus(ProductionStateEnums.ProductionStateType.进行中.getValue());
//                sapProductionScheduleEntity.setOrderNo(oldProductionSchedule.getOrderNo());
//                sapProductionScheduleEntity.setProductNo(oldProductionSchedule.getProductNo());
//                sapProductionScheduleDao.save(sapProductionScheduleEntity);
//                //结束该设备之前的工单
//                sapProductionScheduleDao.updateByDeviceNo(ProductionStateEnums.ProductionStateType.已完成.getValue(), newDeviceNo, sapProductionScheduleEntity.getId());
//                //处理SAP订单相关 删除原炉次号的排程
//                sapProductionScheduleDao.updateInfoByLotNo(ProductionStateEnums.ProductionStateType.未开始.getValue(),oldCode);
//                //sapProductionScheduleDao.deleteByLotNo(oldCode);
//            }
//        }
//        //endregion
    }

    @Override
    public void updateCode(String oldCode, String newCode) {
        dao.updateCode(oldCode, newCode);
        //更新点检记录表
        Long oldId = crucibleCheckDataDAO.getIdByCode(oldCode);
        crucibleCheckDataDAO.changeCode(newCode,oldCode);
        if (oldId != null){
            crucibleCheckDataDAO.changeCodeById(String.valueOf(oldId.intValue()), newCode);
        }
    }

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

    public BigDecimal storeInventoryDetailTest(StoreMixInfoItem item, BigDecimal count) throws RuntimeException {

        if (item.getCount().compareTo(BigDecimal.ZERO) > 0) {
            if (count == null || count.compareTo(item.getCount()) < 0) {
                throw new RuntimeException("库存不足,无法完成出库");
            }
            count = count.subtract(item.getCount());
        }
        return count;
    }


}
