package com.sw.mes.sap.reconciliation.sap;

import cc.cczn.matrix.common.monitor.RecordLogger;
import com.sw.mes.sap.reconciliation.framework.IntermediateResult;
import com.sw.mes.sap.reconciliation.framework.ReconResult;
import com.sw.mes.sap.reconciliation.framework.Reconciliation;
import com.sw.mes.sap.reconciliation.sap.dao.SAPNativeSQL;
import com.sw.mes.utils.StringUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * SAP上报对账，按日出数据
 *
 * @Author：wanjia
 * @Date：2024/3/5 23:18
 */
@Service
@Slf4j
public class SAPReconciliation {
    @Autowired
    private Reconciliation reconciliation;

    @Autowired
    private SAPNativeSQL sapNativeSQL;

    /**
     * 按日进行消耗和sap上报的对账
     *
     * @param date 查询日期 格式 yyyy-MM-dd
     * @return
     */
    public ReconResult sapReconciliation(String date) {
        return reconciliation.checkById("sap", date, (data, intermediateResults) -> {
            RecordLogger.warn("sap内部工具消耗数据记录，时间：【" + date + "】");
            for (IntermediateResult<SAPInterResult> intermediateResult : intermediateResults) {
                for (Map.Entry<String, SAPInterResult> detail : intermediateResult.getResultMap().entrySet()) {
                    SAPInterResult interResult = detail.getValue();
                    RecordLogger.warn("工序：" + detail.getKey() + " 记录数：" + interResult.getCount() + " 重量：" + interResult.getSum().doubleValue());
                }
            }
            ReconResult<IntermediateResult<SAPInterResult>[]> result = new ReconResult<>();
            result.setData(intermediateResults);
            return result;
        }, dateTime -> {//处理投料和sap工单中的数据
            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            //投料任务
            SAPInterResult againTask = new SAPInterResult();
            List<Map<String, Object>> list = sapNativeSQL.queryAgainTask(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : list) {
                BigDecimal weight = (BigDecimal) map.get("weight");
                total = total.add(Optional.ofNullable(weight).orElse(new BigDecimal(0)));
            }
            againTask.setSum(total);
            againTask.setCount(list.size());
            result.add("单晶投料确认", againTask);

            //查询sap
            List<Map<String, Object>> listSAP = sapNativeSQL.queryAgainTaskInSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            SAPInterResult againTaskSAP = new SAPInterResult();
            BigDecimal totalSAP = new BigDecimal(0);
            for (Map<String, Object> map : listSAP) {
                String menge = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(menge) ? "0" : menge);
                totalSAP = totalSAP.add(weight);
            }
            againTaskSAP.setSum(totalSAP);
            againTaskSAP.setCount(listSAP.size());
            result.add("单晶消耗（未传SAP）", againTaskSAP);

            result.setCode(200);
            result.setQueryKey("againTask");
            return result;
        }, dateTime -> {//查询截断数据
            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            SAPInterResult crystalCheck = new SAPInterResult();
            //MES毛棒检验
            List<Map<String, Object>> list = sapNativeSQL.queryCrystalCheck(dateTime + " 00:00:00", dateTime + " 23:59:59");
            //单晶收货
            List<Map<String, Object>> listSAP = sapNativeSQL.queryCrystalCutSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            //毛棒调拨
            List<Map<String, Object>> listCrystalAllotSAP = sapNativeSQL.queryCrystalAllotSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : list) {
                BigDecimal weight = (BigDecimal) map.get("weight");
                total = total.add(Optional.ofNullable(weight).orElse(new BigDecimal(0)));
            }
            crystalCheck.setSum(total);
            crystalCheck.setCount(list.size());
            result.add("MES毛棒检验过站", crystalCheck);//MES毛棒检验

            SAPInterResult crystalCutSAP = new SAPInterResult();
            BigDecimal totalSap = new BigDecimal(0);
            for (Map<String, Object> map : listSAP) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                totalSap = totalSap.add(weight);
            }
            crystalCutSAP.setSum(totalSap);
            crystalCutSAP.setCount(listSAP.size());
            result.add("单晶收货（未传SAP）", crystalCutSAP);


            SAPInterResult crystalAllotSAP = new SAPInterResult();
            BigDecimal totalAllot = new BigDecimal(0);
            for (Map<String, Object> map : listCrystalAllotSAP) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                totalAllot = totalAllot.add(weight);
            }
            crystalAllotSAP.setCount(listCrystalAllotSAP.size());
            crystalAllotSAP.setSum(totalAllot);
            result.add("MES毛棒调拨（未传SAP）", crystalAllotSAP);//对应sql里面的毛棒调拨


            result.setCode(200);
            result.setQueryKey("crystalCut");
            return result;
        }, dateTime -> {//截断消耗
            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            SAPInterResult cutCost = new SAPInterResult();
            List<Map<String, Object>> list = sapNativeSQL.queryCutCostSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : list) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                total = total.add(weight);
            }
            cutCost.setSum(total);
            cutCost.setCount(list.size());
            result.add("截断消耗（未传SAP）", cutCost);

            result.setCode(200);
            result.setQueryKey("cutCost");
            return result;
        }, dateTime -> {//截断收货、截断调拨 和刀剖消耗在刀刨站上报圆棒检验晶段重量
            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            //截断收货
            SAPInterResult cutInput = new SAPInterResult();
            List<Map<String, Object>> cutInputList = sapNativeSQL.cutInputSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : cutInputList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                total = total.add(weight);
            }
            cutInput.setCount(cutInputList.size());
            cutInput.setSum(total);
            result.add("截断收货(未传SAP)", cutInput);

            //截断调拨
            SAPInterResult cutAllot = new SAPInterResult();
            List<Map<String, Object>> cutAllotList = sapNativeSQL.cutAllotSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal cutAllotTotal = new BigDecimal(0);
            for (Map<String, Object> map : cutAllotList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                cutAllotTotal = cutAllotTotal.add(weight);
            }
            cutAllot.setCount(cutAllotList.size());
            cutAllot.setSum(cutAllotTotal);
            result.add("截断调拨（未传SAP）", cutAllot);

            //刀剖消耗
            SAPInterResult kfCost = new SAPInterResult();
            List<Map<String, Object>> kfCostList = sapNativeSQL.kfCostSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal kfCostTotal = new BigDecimal(0);
            for (Map<String, Object> map : kfCostList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                kfCostTotal = kfCostTotal.add(weight);
            }
            kfCost.setCount(kfCostList.size());
            kfCost.setSum(kfCostTotal);
            result.add("刀剖消耗（未传SAP）", kfCost);

            //MES刀刨截断
            SAPInterResult kfCut = new SAPInterResult();
            List<Map<String, Object>> kfCutList = sapNativeSQL.kfCut(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal kfCutTotal = new BigDecimal(0);
            for (Map<String, Object> map : kfCutList) {
                BigDecimal weight = (BigDecimal) map.get("weight");
                kfCutTotal = kfCutTotal.add(Optional.ofNullable(weight).orElse(new BigDecimal(0)));
            }
            kfCut.setCount(kfCutList.size());
            kfCut.setSum(kfCutTotal);
            result.add("MES刀剖进站记录", kfCut);

            return result;
        }, dateTime -> {//刀剖收货在方棒检验上报方棒重量

            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            //刀剖收货
            SAPInterResult kfInput = new SAPInterResult();
            List<Map<String, Object>> kfInputList = sapNativeSQL.kfInputSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : kfInputList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                total = total.add(weight);
            }
            kfInput.setCount(kfInputList.size());
            kfInput.setSum(total);
            result.add("刀剖收货(未传SAP)", kfInput);

            //MES方棒检验
            SAPInterResult fbCheck = new SAPInterResult();
            List<Map<String, Object>> fbCheckList = sapNativeSQL.fbCheck(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal fbCheckTotal = new BigDecimal(0);
            for (Map<String, Object> map : fbCheckList) {
                BigDecimal weight = (BigDecimal) map.get("weight");
                fbCheckTotal = fbCheckTotal.add(Optional.ofNullable(weight).orElse(new BigDecimal(0)));
            }
            fbCheck.setCount(fbCheckList.size());
            fbCheck.setSum(fbCheckTotal);
            result.add("MES方棒检验合格记录", fbCheck);

            return result;
        }, dateTime -> {//余料+硅料
            IntermediateResult<SAPInterResult> result = new IntermediateResult<>();
            //余料
            SAPInterResult recycled = new SAPInterResult();
            List<Map<String, Object>> recycledList = sapNativeSQL.recycledMaterial(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal total = new BigDecimal(0);
            for (Map<String, Object> map : recycledList) {
                BigDecimal weight = (BigDecimal) map.get("weight");
                total = total.add(Optional.ofNullable(weight).orElse(new BigDecimal(0)));
            }
            recycled.setCount(recycledList.size());
            recycled.setSum(total);
            result.add("余料", recycled);

            //余料sap
            SAPInterResult recycledSAP = new SAPInterResult();
            List<Map<String, Object>> recycledSAPList = sapNativeSQL.recycledMaterialSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal totalSAP = new BigDecimal(0);
            for (Map<String, Object> map : recycledSAPList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                totalSAP = totalSAP.add(weight);
            }
            recycledSAP.setCount(recycledSAPList.size());
            recycledSAP.setSum(totalSAP);
            result.add("余料（未传SAP）", recycledSAP);

            //硅料
            SAPInterResult storeSignSAP = new SAPInterResult();
            List<Map<String, Object>> storeSignSAPList = sapNativeSQL.storeSignSAP(dateTime + " 00:00:00", dateTime + " 23:59:59");
            BigDecimal totalStoreSign = new BigDecimal(0);
            for (Map<String, Object> map : storeSignSAPList) {
                String matnr = (String) map.get("menge");
                BigDecimal weight = new BigDecimal(StringUtils.isEmpty(matnr) ? "0" : matnr);
                totalStoreSign = totalStoreSign.add(weight);
            }
            storeSignSAP.setCount(storeSignSAPList.size());
            storeSignSAP.setSum(totalStoreSign);
            result.add("硅料（未传SAP）", storeSignSAP);

            return result;
        });
    }

}
