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

import com.sw.mes.agv.service.RechargeArtBagItemService;
import com.sw.mes.agv.constant.IPCRequest;
import com.sw.mes.agv.dao.MonitorEquipmentRechargeDAO;
import com.sw.mes.agv.dto.MonitorRechargeDto;
import com.sw.mes.agv.dto.RechargeMixDto;
import com.sw.mes.agv.entity.MonitorEquipmentRecharge;
import com.sw.mes.agv.entity.RechargeArtBagItem;

import com.sw.mes.agv.service.MonitorEquipmentRechargeService;
import com.sw.mes.agv.service.RechargeArtBagService;
import com.sw.mes.base.factory.init.service.EquipmentService;
import com.sw.mes.base.factory.material.entity.MaterialModel;
import com.sw.mes.base.factory.utils.PageUtils;
import com.sw.mes.core.base.BaseServiceImpl;
import com.sw.mes.core.utils.DateUtil;
import com.sw.mes.core.utils.RequestPage;
import com.sw.mes.utils.StringUtils;
import org.modelmapper.ModelMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.*;

@Service
@Transactional
public class MonitorEquipmentRechargeServiceImpl extends BaseServiceImpl<MonitorEquipmentRecharge> implements MonitorEquipmentRechargeService {

    MonitorEquipmentRechargeDAO monitorEquipmentRechargeDAO;

    @Autowired
    public void setDao(MonitorEquipmentRechargeDAO monitorEquipmentRechargeDAO) {
        this.monitorEquipmentRechargeDAO = monitorEquipmentRechargeDAO;
        super.setBaseDao(monitorEquipmentRechargeDAO);
    }
//
//    @Autowired
//    private TaskLogService taskLogService;

    @Autowired
    private EquipmentService equipmentService;

//    @Autowired
//    private EquipmentStateService equipmentStateService;
//
//    @Autowired
//    private AgvRequestService agvRequestService;

    @Autowired
    private RechargeArtBagItemService artBagItemService;

    @Autowired
    private RechargeArtBagService rechargeArtBagService;

    @Override
    public List<MonitorEquipmentRecharge> findAll(RequestPage page) {
        org.springframework.data.domain.Page<MonitorEquipmentRecharge> springDataPage = monitorEquipmentRechargeDAO.findAll(PageUtils.createPageable(page));
        page.setTotal(springDataPage.getTotalElements());
        return springDataPage.getContent();
    }

    @Override
    public List<MonitorEquipmentRecharge> findAll(Specification<MonitorEquipmentRecharge> specification) {
        return monitorEquipmentRechargeDAO.findAll(specification);
    }

    @Override
    public List<MonitorEquipmentRecharge> findByExample(
            Specification<MonitorEquipmentRecharge> specification, RequestPage page) {
        org.springframework.data.domain.Page<MonitorEquipmentRecharge> springDataPage = monitorEquipmentRechargeDAO.findAll(specification, PageUtils.createPageable(page));
        page.setTotal(springDataPage.getTotalElements());
        return springDataPage.getContent();
    }

    @Override
    public MonitorEquipmentRecharge getByName(String deviceNo) {
        List<MonitorEquipmentRecharge> list = monitorEquipmentRechargeDAO.findByName(deviceNo);
        if (list != null && list.size() > 0) {
            return list.get(0);
        }

        return null;
    }

    @Override
    public List<MonitorEquipmentRecharge> findBySlingStateNot(String state) {
        return monitorEquipmentRechargeDAO.findBySlingStateNotOrderByPreSlingTimeDesc(state);
    }

    @Override
    public List<MonitorEquipmentRecharge> findByEquipmentsAndSlingStateNotEqual(List<String> equipmentList, String state) {
        return monitorEquipmentRechargeDAO.findByEquipmentsAndSlingStateNotEqual(equipmentList, state);
    }

    @Override
    public List<MonitorEquipmentRecharge> findByEquipmentsAndSlingState(List<String> equipmentList, String state) {
        return monitorEquipmentRechargeDAO.findByEquipmentsAndSlingState(equipmentList, state);
    }

    @Override
    public List<MonitorEquipmentRecharge> findByEquipmentsAndSlingStateNotEqualAndStoreCode(List<String> equipmentList, String state, Boolean isHave) {
        if (isHave) {
            return monitorEquipmentRechargeDAO.findByEquipmentsAndSlingStateNotEqualAndStoreCodeIsNotNull(equipmentList, state);
        } else {
            return monitorEquipmentRechargeDAO.findByEquipmentsAndSlingStateNotEqualAndStoreCodeIsNull(equipmentList, state);
        }
    }

    @Override
    public List<MonitorEquipmentRecharge> findByStateAndArea(Integer state, String area) {

        // 删除2小时前的复投记录
        Date date = DateUtil.getDate(new Date(), -3);
        monitorEquipmentRechargeDAO.deleteByPreSlingTime(date);

        if (StringUtils.isNotEmpty(area)) {
            return monitorEquipmentRechargeDAO.findByStateAndArea(state, area);
        } else {
            return monitorEquipmentRechargeDAO.findByState(state);
        }
    }

    @Override
    public void updateRechargeStartTime(Date rechargeStartTime, String deviceNo) {
        monitorEquipmentRechargeDAO.updateRechargeStartTime(rechargeStartTime, deviceNo);
    }

    @Override
    public void updateRechargeEndTime(Date rechargeEndTime, String deviceNo) {
        monitorEquipmentRechargeDAO.updateRechargeEndTime(rechargeEndTime, deviceNo);
    }

    @Override
    public List<MonitorEquipmentRecharge> findRechargeEndTimeIsNull(String userIp) {
        if (StringUtils.isNotBlank(userIp)) {
            return monitorEquipmentRechargeDAO.findRechargeEndTimeIsNull(userIp);
        } else {
            return monitorEquipmentRechargeDAO.findRechargeEndTimeIsNull();
        }
    }

    @Override
    public List<MonitorEquipmentRecharge> findRechargeChangeWeight(String userIp) {
        if (StringUtils.isNotBlank(userIp)) {
            return monitorEquipmentRechargeDAO.findRechargeChangeWeight(userIp);
        } else {
            return monitorEquipmentRechargeDAO.findRechargeChangeWeight();
        }
    }

    @Override
    public List<MonitorEquipmentRecharge> findRechargeCall(String userIp, String deviceCode) {
        if (StringUtils.isNotBlank(userIp)) {
            if (StringUtils.isBlank(deviceCode)) {
                return monitorEquipmentRechargeDAO.findRechargeCall(userIp);
            }
            return monitorEquipmentRechargeDAO.findRechargeCall(userIp, deviceCode);
        } else {
            if (StringUtils.isBlank(deviceCode)) {
                return monitorEquipmentRechargeDAO.findRechargeCall();
            }
            return monitorEquipmentRechargeDAO.findRechargeCallBydeviceCode(deviceCode);
        }
    }

    @Override
    public List<MonitorEquipmentRecharge> findRechargeInfoByMixTime(String userIp, String deviceCode) {
        if (StringUtils.isNotBlank(userIp)) {
            if (StringUtils.isBlank(deviceCode)) {
                return monitorEquipmentRechargeDAO.findRechargeInfoByMixTime(userIp);
            }
            return monitorEquipmentRechargeDAO.findRechargeInfoByMixTime(userIp, deviceCode);
        } else {
            if (StringUtils.isBlank(deviceCode)) {
                return monitorEquipmentRechargeDAO.findRechargeInfoByMixTime();
            }
            return monitorEquipmentRechargeDAO.findRechargeInfoByMixTimeAndDeviceNo(deviceCode);
        }
    }

//    @Override
//    public void initRechargeWeight(RechargeWeightDto dto) throws Exception {
//
//        String deviceNo = dto.getDeviceNo();
//        BigDecimal weight = dto.getWeight();
//
//        MonitorEquipmentRecharge recharge = getByName(deviceNo);
//
//        if (recharge == null) {
//            recharge = new MonitorEquipmentRecharge();
//            recharge.setName(deviceNo);
//            recharge.initNum();
//            recharge.setRechargeType(IPCRequest.TYPE_CHARGE);
//            recharge.setPreSlingTime(dto.getPreSlingTime());
//            recharge.setPareWeight(dto.getPareWeight().doubleValue());
//            recharge.setState(1);
//            recharge.setMixTime(null);
//            recharge.setTechBom("");
//            recharge.setTechBomItem("");
//
//            EquipmentState state = equipmentStateService.getByCode(deviceNo);
//            if (state != null) {
//                recharge.setArea(state.getArea());
//                recharge.setLotNo(state.getLotno());
//            } else {
//                recharge.setLotNo("");
//                Equipment equipment = equipmentService.findByCode(deviceNo);
//                if (equipment == null) {
//                    throw new Exception("编号[" + deviceNo + "]设备信息不存在！");
//                }
//                recharge.setArea(equipment.getArea());
//            }
//        } else {
//            recharge.setPreSlingTime(dto.getPreSlingTime());
//            recharge.setPareWeight(dto.getPareWeight().doubleValue());
//        }
//
//        if (StringUtils.isNotBlank(dto.getLotNo())) {
//            recharge.setLotNo(dto.getLotNo());
//        }
//
//        int recount = 1;
//        if (weight.compareTo(new BigDecimal(70)) >= 0) {
//            recount = (int) Math.ceil(weight.doubleValue() / 70);
//            recharge.setRechargeNum(recount);
//        } else {
//            recharge.setRechargeNum(recount);
//        }
//        recharge.setRechargeWeight(weight.doubleValue());
//        recharge.setSlingState(IPCRequest.FUTOUHUJIAO);
//        saveOrUpdate(recharge);
//    }

//    @Override
//    public List<RechargeInfoDto> findPadSend(String userIp, String deviceCode) {
//        if (StringUtils.isNotBlank(userIp)) {
//            List<Map<String, Object>> mapList;
//            if (StringUtils.isBlank(deviceCode)) {
//                mapList = monitorEquipmentRechargeDAO.findPadSend(userIp);
//            } else {
//                mapList = monitorEquipmentRechargeDAO.findPadSend(userIp, deviceCode);
//            }
//            List<RechargeInfoDto> list = new ArrayList<>();
//            if (mapList != null && mapList.size() > 0) {
//                for (Map<String, Object> map : mapList) {
//                    if (map.containsKey("name")) {
//                        RechargeInfoDto dto = new RechargeInfoDto();
//                        dto.setName((String) map.get("name"));
//                        if (map.containsKey("preSlingTime")) {
//                            dto.setPreSlingTime((Date) map.get("preSlingTime"));
//                        }
//                        if (map.containsKey("rechargeType")) {
//                            dto.setRechargeType((String) map.get("rechargeType"));
//                        }
//                        list.add(dto);
//                    }
//                }
//            }
//            return list;
//        } else {
//            if (StringUtils.isBlank(deviceCode))
//                return monitorEquipmentRechargeDAO.findPadSend();
//            return monitorEquipmentRechargeDAO.findPadSendByName(deviceCode);
//        }
//    }

    @Override
    public List<MonitorEquipmentRecharge> findByInitWeightAndPreSlingTime() {
        return monitorEquipmentRechargeDAO.findByInitWeightAndPreSlingTime();
    }

    @Override
    public void handleTaskLog() {

        List<MonitorEquipmentRecharge> recharges = findAll();

        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.HOUR_OF_DAY, -10);
        Date date = calendar.getTime();
        Map<String, MonitorEquipmentRecharge> rechargeMap = new HashMap<>();
        if (recharges != null && recharges.size() > 0) {
            for (MonitorEquipmentRecharge item : recharges) {
                if (item.getPreSlingTime().after(date)) {
                    rechargeMap.put(item.getName(), item);
                } else {
                    delete(item.getId());
                }
            }
        }

//        Double maxWeight = 70d;
//        Double minWeight = 20d;
//        List<String> items = dictionaryItemService.findItemValueByThemeValue("rechargeRange", true);
//        if (items != null && items.size() > 0) {
//            String item = items.get(0);
//            String[] values = item.split("-");
//            if (values.length == 2) {
//                if (NumberUtil.isNumeric(values[0])) {
//                    minWeight = Double.valueOf(values[0]);
//                }
//                if (NumberUtil.isNumeric(values[1])) {
//                    maxWeight = Double.valueOf(values[1]);
//                }
//            }
//        }
//
//        handleSpcUrl();

//        List<Equipment> equipmentList = equipmentService.findByDeviceId(3L);
//
//        Map<String, Object> taskMap;
//        String deviceNo;
//        MonitorEquipmentRecharge recharge;
//        for (Equipment item : equipmentList) {
//            deviceNo = item.getCode();
//            if (rechargeMap.containsKey(deviceNo)) {
////                taskMap = getSpcInfo(rechargeMap.get(deviceNo), maxWeight, minWeight);
//                recharge = rechargeMap.remove(deviceNo);
//                if (recharge.getSending() == null || !recharge.getSending()) {
//                    recharge.setSending(true);
//                    saveOrUpdate(recharge);
//                    continue;
//                }
//            }
//            taskMap = new HashMap<>();
//            taskMap.put("MES201", 0);
//            taskMap.put("MES202", 0);
//            taskMap.put("MES203", -1);
//            taskMap.put("MES204", 0);
//            taskMap.put("MES205", 0);
//
//            try {
//                taskLogService.task(deviceNo, taskMap);
//            } catch (Exception ignored) {
//            }
//        }

    }

    @Override
    public void initRechargeWeight(String deviceNo, BigDecimal weight) throws Exception {
        MonitorEquipmentRecharge recharge = getByName(deviceNo);
        if (recharge != null) {
            if (recharge.getMixTime() != null) {
                throw new Exception("设备[" + deviceNo + "]复投搭配方案已完成！");
            }
            int recount = 1;
            if (weight.compareTo(new BigDecimal(70)) >= 0) {
                recount = (int) Math.ceil(weight.doubleValue() / 70);
//                Integer count = (recount + 1) / 2;
//                try {
//                    agvRequestService.agvStatus(deviceNo, deviceNo, 26, count, 1);
//                } catch (Exception e) {
//                    throw new Exception(e.getMessage());
//                }

                recharge.setRechargeNum(recount);
            } else {
//                try {
//                    agvRequestService.agvStatus(deviceNo, deviceNo, 26, 1, 1);
//                } catch (Exception e) {
//                    throw new Exception(e.getMessage());
//                }

                recharge.setRechargeNum(recount);
            }
            recharge.setRechargeWeight(weight.doubleValue());
            recharge.setSlingState(IPCRequest.FUTOUHUJIAO);
            saveOrUpdate(recharge);
        } else {
            throw new Exception("设备[" + deviceNo + "]未进行复投呼叫！");
        }
    }

    @Autowired
    private ModelMapper modelMapper;

    private RechargeArtBagItem fromDto(RechargeMixDto dto) {
        return modelMapper.map(dto, RechargeArtBagItem.class);
    }

    @Override
    public void saveOrUpdateArtBag(MonitorRechargeDto dto) throws Exception {

        String deviceNo = dto.getName();
        MonitorEquipmentRecharge entity = getByName(deviceNo);
        if (entity != null) {
            List<RechargeMixDto> list = dto.getMixDtos();
            List<RechargeArtBagItem> itemEntitys = new ArrayList<>();
            if (list != null && list.size() > 0) {
                StringBuilder str = new StringBuilder();
                BigDecimal dosage = BigDecimal.ZERO;
                for (RechargeMixDto item : list) {

                    RechargeArtBagItem itemEntity = fromDto(item);
                    MaterialModel materialModel = itemEntity.getMaterialModel();

                    if (item.getDosage() == null) {
                        throw new Exception(item.getMaterialModelName() + "重量为空！");
                    }
                    dosage = dosage.add(item.getDosage());

                    if (materialModel != null) {
                        str.append(materialModel.getCode()).append("-")
                                .append(materialModel.getName()).append("-")
                                .append(materialModel.getSupplier()).append("-")
                                .append(item.getDosage());
                        if (materialModel.getUnit() != null) {
                            str.append(materialModel.getUnit().getName()).append(";");
                        } else {
                            str.append("KG").append(";");
                        }
                    }

//                    if (itemEntity.getCount() == null) {
                    itemEntity.setCount(BigDecimal.ZERO);
//                    }
                    itemEntity.setCreateTime(new Date());
                    itemEntity.setDeviceNo(deviceNo);

                    itemEntitys.add(itemEntity);
                }

                if (entity.getRechargeWeight() < dosage.doubleValue()) {
                    throw new Exception("搭配方案重量大于复投呼叫重量：" + entity.getRechargeWeight());
                }

                entity.setTechBomItem(str.toString());

                artBagItemService.deleteByDeviceNo(deviceNo);

                artBagItemService.saveAll(itemEntitys);
            }
            entity.setPn(dto.getPn());
            entity.setRechargeTimes(dto.getRechargeTimes());
            if (dto.getLeftWeight() != null && dto.getLeftWeight().compareTo(BigDecimal.ZERO) > 0) {
                entity.setLeftWeight(dto.getLeftWeight().doubleValue());
            }
            entity.setMixUser(dto.getMixUser());
            entity.setMixTime(new Date());
            entity.setSlingState(IPCRequest.WANCHENG);
            saveOrUpdate(entity);

            // 创建记录
            rechargeArtBagService.handleRecord(entity, itemEntitys);
        }

    }

}
