package com.malk.kuaikeli.service.impl;

import com.alibaba.fastjson.JSON;
import com.malk.kuaikeli.service.KKLService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.service.aliwork.YDClient;
import com.malk.service.aliwork.YDService;
import com.malk.utils.UtilMap;
import com.malk.utils.UtilMc;
import com.malk.utils.UtilNumber;
import lombok.SneakyThrows;
import lombok.Synchronized;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

@Service
@Slf4j
public class KKLImplService implements KKLService {

    @Autowired
    private YDService ydService;

    /**
     * [动态] 发起单据, 分供应商进行流程推送
     */
    @Override
    public void matchSupplier(Map data) {

        // ppExt: 供应商区分发起: 当前表：供应供子表组件ID，子表内供应商编号，名称，负责人
        String[] compIds_supplier = String.valueOf(data.get("compId_supplier")).split(", ");
        String compId_supplier = compIds_supplier[1];

        Map formData = (Map) JSON.parse(String.valueOf(data.get("formData")));
        List<Map> details = (List<Map>) formData.get(compIds_supplier[0]);

        // 供应商编号, 数据去重: 提取数据区分供应商发起
        List<Map> suppliers = UtilMc.distinctByKey(details, compId_supplier);
        for (Map supplier : suppliers) {
            List<Map> dataList = details.stream().filter(item -> supplier.get(compId_supplier).equals(item.get(compId_supplier))).collect(Collectors.toList());
            formData.put(compIds_supplier[0], dataList);
            // ppExt: 参数传递, 目标表组件ID, 对照当前表子表内的子表内供应商编号，名称，负责人已放置主表字段, 此处公共内容提前首条数据进行赋值
            for (int i = 1; i < compIds_supplier.length; i++) {
                formData.put(compIds_supplier[i], YDConf.getDataByCompId(dataList.get(0), compIds_supplier[i]));
            }
            data.put("formData", JSON.toJSONString(formData));
            ydService.copyFormData(data); // 发起流程
        }
    }

    @Autowired
    private YDClient ydClient;

    /**
     * 菜单计划, 编辑校验
     * -
     * 前端提交动作: 校验是否审批通过, 是否当日之前计划, 是否当日且在16点及以后时间, 均不允许提交
     * 后端校验返回、加任何产品都要走审批，减少20%以内直接过，每一个原材料
     */
    @Override
    public void validateApprove(Map data) {

        boolean approve = false;
        List<Map> dataList = UtilMap.getList(data, "list");
        for (Map row : dataList) {

            // 匹配切配工作单, 采购
            List<Map> formList = (List<Map>) ydClient.queryData(YDParam.builder()
                            .formUuid("FORM-RK966E71T0LDSTW39WFHE9OQ5GU23FKRRDNLL2")
                            .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lmsuq8am, textField_lm8zta2z, textField_ln1ez5li", data.get("name"), data.get("area"), row.get("textField_ln1ez5li"))))
                            .build(),
                    YDConf.FORM_QUERY.retrieve_search_form).getData();

            if (formList.size() == 0) {
                approve = true;
                break;
            }
            Map formData = (Map) formList.get(0).get("formData");
            float cur = UtilMap.getFloat(row, "numberField_lmym5628");
            float src = UtilMap.getFloat(formData, "numberField_lnrkgimz");
            if (cur > src || (src - cur) / src > 0.2f) {
                approve = true;
                break;
            }
        }
        if (approve) {
            // 发起菜单审批
            ydClient.operateData(YDParam.builder()
                    .formUuid("FORM-UP96637100HD036TA1M05B74GHLV3DRS54NLLC")
                    .processCode("TPROC--UP96637100HD036TA1M05B74GHLV3ERS54NLLD")
                    .formDataJson(JSON.toJSONString(data.get("form"))) // 前端数据组装
                    .userId(data.get("user").toString())
                    .build(), YDConf.FORM_OPERATION.start);

            // 更新计划状态
            ydService.operateData(YDParam.builder()
                    .formInstanceId(data.get("poid").toString())
                    .updateFormDataJson(JSON.toJSONString(UtilMap.map("textField_lm8znr9n", "执行中")))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }

    /**
     * 定价单: 项目点 & 供应商大类, 数据匹配
     */
    @Override
    @SneakyThrows
    @Synchronized
    public void serviceRate(Map data) {

        // todo: 宜搭更新，校验的超时等待在3s, 因此方法修改为异步. 容错定时任务？匹配不一致数据
        String supperCode = String.valueOf(data.get("code"));
        List<String> types = (List<String>) JSON.parse(String.valueOf(data.get("type")));
        List<String> rates = (List<String>) JSON.parse(String.valueOf(data.get("rate")));
        List<String> rates2 = (List<String>) JSON.parse(String.valueOf(data.get("rate2")));
        List<String> status = (List<String>) JSON.parse(String.valueOf(data.get("status")));

        for (int i = 0; i < types.size(); i++) {

            List<Map> materials = supperMaterials(supperCode, types.get(i));
            List<Map> records = projectMaterials(supperCode, types.get(i));
            log.info("定价单同步, {}, {}", materials.size(), records.size());
            for (Map material : materials) {

                // 数据处理: 服务费率与供货价, 项目信息
                double rate = Double.valueOf(rates.get(i));
                double rate2 = Double.valueOf(rates2.get(i));
                material.putAll(UtilMap.map("numberField_llkb7kcy, numberField_lpalgz04, textField_lm4lxur8", rate, rate2, status.get(i)));
                double price1 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_llkknd6g") * (rate + 100) / 100f);
                double price2 = UtilNumber.formatPrecisionValue(UtilMap.getDouble(material, "numberField_lpalgz05") * (100 + rate2) / 100f);
                material.putAll(UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2));
                material.putAll(UtilMap.map("textField_llm1vtjm, textField_loy1ep8r", data.get("proCode"), data.get("proName")));

                YDParam ydParam = YDParam.builder()
                        .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                        .formDataJson(JSON.toJSONString(material))
                        .build();
                YDConf.FORM_OPERATION operation = YDConf.FORM_OPERATION.create;
                // ppExt: 提交校验逻辑, 匹配定价单数若存在则匹配服务费率, 不一致执行更新
                if (records.size() > 0) {
                    Optional optional = records.stream().filter(item -> item.get("textField_llkb7kd2").equals(material.get("textField_llkb7kd2"))).findAny();
                    if (optional.isPresent()) {
                        ydParam.setUpdateFormDataJson(JSON.toJSONString(material));
                        ydParam.setFormInstanceId(String.valueOf(((Map) optional.get()).get("formInstanceId")));
                        operation = YDConf.FORM_OPERATION.update;
                    }
                }
                ydClient.operateData(ydParam, operation);
            }
        }
    }

    /// 原材料: 供应商第一分类下物料
    List<Map> supperMaterials(String code, String type) {
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkb7kd5", code, type)))
                .build());
        log.info("supperMaterials, {}", dataList.size());
        return dataList;
    }

    /// 定价单: 供应商第一分类下物料
    List<Map> projectMaterials(String code, String type) {
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llzzbyj1, selectField_llkb7kd5", code, type)))
                .build());
        log.info("projectMaterials, {}", dataList.size());
        return dataList;
    }


    /**
     * 物料档案: 价格调整
     */
    @Override
    public void adjustCost(Map data) {

        double cost1 = UtilMap.getDouble(data, "cost");
        double cost2 = UtilMap.getDouble(data, "cost2");

        // todo: 服务执行, 周日凌晨更新价格前, 是否重新匹配数据?
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_llkb7kd2", data.get("code"))))
                .build());
        log.info("adjustCost, {}", dataList.size());

        for (Map record : dataList) {

            if (cost1 == UtilMap.getDouble(record, "numberField_llkknd6g") && cost2 == UtilMap.getDouble(record, "numberField_lpalgz05")) {
                continue;
            }
            double rate = UtilMap.getDouble(record, "numberField_llkb7kcy");
            double rate2 = UtilMap.getDouble(record, "numberField_lpalgz04");
            double price1 = UtilNumber.formatPrecisionValue(cost1 * (rate + 100) / 100f);
            double price2 = UtilNumber.formatPrecisionValue(cost2 * (100 + rate2) / 100f);
            Map update = UtilMap.map("numberField_llkknd6h, numberField_lpalgz0a", price1, price2);
            update.putAll(UtilMap.map("numberField_llkknd6g, numberField_lpalgz05", cost1, cost2));
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
                    .updateFormDataJson(JSON.toJSONString(update))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }

    /**
     * 供应商原材料档案: 新增匹配
     */
    @Override
    public void additionMaterial(Map data) {

        // 定价单供应商
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0")
                .searchFieldJson(JSON.toJSONString(UtilMap.map("textField_lllovku7", data.get("supplier"))))
                .build());
    }

    /**
     * 周日同步更新价格
     */
    @Override
    @SneakyThrows
    public void syncPrice() {

        // 定价单明细表
        List<Map> dataList = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5")
                .build());
        for (Map record : dataList) {

            double price1 = UtilMap.getDouble(record, "numberField_llkknd6h");
            double price2 = UtilMap.getDouble(record, "numberField_lpalgz0a");
            if (price1 == price2) {
                continue;
            }
            // 本质上是对比供货价差异, 下周全覆盖
            Map update = UtilMap.map("numberField_llkknd6h, numberField_llkb7kcy, numberField_llkknd6g", price2, record.get("numberField_lpalgz04"), record.get("numberField_lpalgz05"));
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
                    .updateFormDataJson(JSON.toJSONString(update))
                    .build(), YDConf.FORM_OPERATION.update);
        }

        // 供应商原材料表
        List<Map> dataList2 = ydService.queryFormData_all(YDParam.builder()
                .formUuid("FORM-12EB6BCE3C264630824721E7BBABCC03L8U9")
                .build());
        for (Map record : dataList2) {

            double cost1 = UtilMap.getDouble(record, "numberField_llkknd6g");
            double cost2 = UtilMap.getDouble(record, "numberField_lpalgz05");
            if (cost1 == cost2) {
                continue;
            }
            Map update = UtilMap.map("numberField_llkknd6g", cost2);
            ydClient.operateData(YDParam.builder()
                    .formInstanceId(String.valueOf(record.get("formInstanceId")))
                    .updateFormDataJson(JSON.toJSONString(update))
                    .build(), YDConf.FORM_OPERATION.update);
        }
    }
}
