package com.jjt.vms.service.impl;

import com.jjt.common.constant.CacheConstants;
import com.jjt.common.core.redis.RedisCache;
import com.jjt.order.domain.MesStock;
import com.jjt.order.domain.MesStockCalc;
import com.jjt.utils.MssqlService;
import com.jjt.vms.service.IWmsService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.atomic.AtomicLong;
import java.util.stream.Collectors;

/**
 * WMS数据获取业务层处理
 *
 * @author wukai
 * @date 2025-01-16
 */
@Service
public class WmsServiceImpl implements IWmsService {
    @Resource
    private RedisCache redisCache;
    @Resource
    private MssqlService mssqlService;

    /**
     * 获取当前库存
     */
    @Override
    public void currStock() {
        //减少7个小时，班组统计时间
        LocalDate localDate = LocalDateTime.now().minusHours(7).toLocalDate();
        List<MesStock> list = mssqlService.mesStock(localDate);
        List<MesStock> wmsOutTargetList = mssqlService.wmsOutTarget(localDate);
        Map<String, Double> currStock = mssqlService.currStock();
        HashMap<String, Object> initMap = new HashMap<>(16);
        initMap.put("d-in", 0L);
        initMap.put("d-out", 0L);
        initMap.put("m-in", 0L);
        initMap.put("m-out", 0L);
        Map<String, Object> mapping = new HashMap<>(16);
        mapping.put("WH01", "ycl");
        mapping.put("WH03", "pt");
        mapping.put("WH04", "bpb");
        mapping.put("WH08", "cp");
        Map<String, Long> lineMap = new HashMap<>(16);
        Map<String, Object> result = new HashMap<>(16);
        result.put("ycl", initMap.clone());
        result.put("cp", initMap.clone());
        result.put("bpb", initMap.clone());
        result.put("pt", initMap.clone());
        result.put("out-rz-line", lineMap);

        for (String key : currStock.keySet()) {
            HashMap<String, Object> map = (HashMap<String, Object>) result.get(key);
            map.put("curr", BigDecimal.valueOf(currStock.get(key)).longValue());
        }

        //按目标产线分组
        Map<String, List<MesStock>> bpTargetMap = wmsOutTargetList.stream().collect(Collectors.groupingBy(MesStock::getTarget));
        bpTargetMap.forEach((target, targetList) -> {
            //统计出库总量
            long sum = targetList.stream().mapToLong(MesStock::getTotal).sum();
            //“染整白坯7#上料点”，解析产线
            String line = target.replace("染整白坯", "").replace("#上料点", "");
            lineMap.put(line, sum);
        });

        //先按仓库分组
        Map<String, List<MesStock>> codeMap = list.stream().collect(Collectors.groupingBy(MesStock::getCode));

        codeMap.forEach((code, codeList) -> {
            //按时间分组
            Map<String, Object> map = (Map<String, Object>) result.get(mapping.get(code));
            if (map != null) {
                AtomicLong dIn = new AtomicLong((Long) map.get("d-in"));
                AtomicLong dOut = new AtomicLong((Long) map.get("d-out"));
                AtomicLong mIn = new AtomicLong((Long) map.get("m-in"));
                AtomicLong mOut = new AtomicLong((Long) map.get("m-out"));

                List<MesStockCalc> calcList = new ArrayList<>();
                Map<LocalDate, List<MesStock>> dateMap = codeList.stream().collect(Collectors.groupingBy(MesStock::getDate));
                dateMap.forEach((date, dateList) -> {
                    List<MesStock> inList = dateList.stream().filter(MesStock::getFlag).collect(Collectors.toList());
                    List<MesStock> outList = dateList.stream().filter(o -> !o.getFlag()).collect(Collectors.toList());
                    //统计入库
                    long inNum = inList.stream().mapToLong(MesStock::getTotal).sum();
                    //统计出库
                    long outNum = outList.stream().mapToLong(MesStock::getTotal).sum();

                    MesStockCalc calc = new MesStockCalc();
                    calc.setCode(code);
                    calc.setDate(date);
                    calc.setInNum(inNum);
                    calc.setOutNum(outNum);
                    calcList.add(calc);
                    if (localDate.isEqual(date)) {
                        //如果是当天数据
                        dIn.addAndGet(inNum);
                        dOut.addAndGet(outNum);
                        map.put("in", inList);
                        map.put("out", outList);
                    }
                    if (localDate.getYear() == date.getYear() && localDate.getMonthValue() == date.getMonthValue()) {
                        mIn.addAndGet(inNum);
                        mOut.addAndGet(outNum);
                    }
                    map.put("d-in", dIn.longValue());
                    map.put("d-out", dOut.longValue());
                    map.put("m-in", mIn.longValue());
                    map.put("m-out", mOut.longValue());
                });
                calcList.sort(Comparator.comparing(MesStockCalc::getDate));
                map.put("trend", calcList);
            }
        });
        redisCache.setCacheObject(CacheConstants.VMS_STOCK, result);
    }
}
