package com.malk.kuaikeli.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.pinyin.PinyinUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.malk.kuaikeli.entity.MaterialDetail;
import com.malk.kuaikeli.entity.Pricing;
import com.malk.kuaikeli.entity.SupplierMaterial;
import com.malk.kuaikeli.listener.SupplierMaterialDataListener;
import com.malk.kuaikeli.mapper.MaterialDetailMapper;
import com.malk.kuaikeli.mapper.SupplierMaterialMapper;
import com.malk.kuaikeli.service.SupplierMaterialService;
import com.malk.server.aliwork.YDConf;
import com.malk.server.aliwork.YDParam;
import com.malk.server.common.McR;
import com.malk.service.aliwork.YDClient;
import com.malk.utils.PublicUtil;
import com.malk.utils.UtilEnv;
import com.malk.utils.UtilMap;
import lombok.extern.slf4j.Slf4j;
import org.apache.xmlbeans.impl.xb.xsdschema.Public;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.util.*;

@Service
@Slf4j
public class SupplierMaterialServiceImpl extends ServiceImpl<SupplierMaterialMapper,SupplierMaterial> implements SupplierMaterialService {

    @Autowired
    private YDClient ydClient;
    @Autowired
    private MaterialDetailMapper materialDetailMapper;

    String _matchFormUuid(String code) {
        Map<String, String> formUuid = UtilMap.empty();
        if (UtilEnv.getActiveProfile().equals(UtilEnv.ENV_PROD)) {
            formUuid.put("SUPPLIERMATERIAL", "FORM-12EB6BCE3C264630824721E7BBABCC03L8U9"); // 供应商原材料档案
            formUuid.put("PRICING", "FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0"); // 定价单
            formUuid.put("MATERIALDETAIL", "FORM-E6766M811CKD2PIXEAKOM9S2DKBM2PBQU1MLL5"); // 定价单明细中间表
            formUuid.put("FOOD", "FORM-GP666M71DIGDE0ZADDLZ85VEFBD128OUH1MLLF"); // 菜品管理
            formUuid.put("DOMAIN", "https://dcuvl8.aliwork.com/"); // 宜搭域名
        } else {
            formUuid.put("SUPPLIERMATERIAL", "FORM-2ADD5797EFB94A5CA18C5E553B420AA7BO75"); // 供应商原材料档案_复制
            formUuid.put("PRICING", "FORM-W2A66Z91B4KDWDIAA7SI1BRBRTKM3XL87BKLL0"); // 定价单
            formUuid.put("MATERIALDETAIL", "FORM-96ED86E480CB4E19851729D055474965FYAL"); // 定价单明细中间表
            formUuid.put("FOOD", "FORM-GP666M71DIGDE0ZADDLZ85VEFBD128OUH1MLLF"); // 菜品管理
            formUuid.put("DOMAIN", "https://dcuvl8.aliwork.com/");
        }
        return formUuid.get(code);
    }

    @Override
    public void uploadData(MultipartFile file) {
        try {
            EasyExcel.read(file.getInputStream(), SupplierMaterial.class, new SupplierMaterialDataListener(baseMapper)).sheet().doRead();

        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /***
     * 同步服务  只查新数据（isNeedSyncYd==是）
     * 1.保存原材料到宜搭表单
     * 2.查询定价单组装数据保存到定价明细中间表
     */
    @Override
    @Async
    public void sync() {
        QueryWrapper<SupplierMaterial> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(SupplierMaterial::getIsNeedSyncYd,"是");
        List<SupplierMaterial> list=baseMapper.selectList(queryWrapper);
        for (SupplierMaterial supplierMaterial:list){
            try {
                syncSupplierMaterial(supplierMaterial);
            }catch (Exception e){
                log.error("同步出现异常：{}",e.getMessage());
                e.printStackTrace();
                supplierMaterial.setIsNeedSyncYd("异常");// 更新是否需要同步到宜搭
                supplierMaterial.setErrorMsg(e.getMessage());
                baseMapper.updateById(supplierMaterial);
            }
        }
    }

    public void syncSupplierMaterial(SupplierMaterial supplierMaterial){
        // 同步到宜搭
        YDParam ydParam = YDParam.builder().formUuid(_matchFormUuid("SUPPLIERMATERIAL"))
                .useLatestVersion(true).build();
        Map formData=supplierMaterial.toYidaFormDataMap();
        // 查询定价单数据
        List<Pricing> pricings=getPricings(supplierMaterial.getSupplierId());
        if(!PublicUtil.isNull(supplierMaterial.getFormInstId())){
            // 更新
            ydParam.setUpdateFormDataJson(JSON.toJSONString(formData));
            ydParam.setFormInstanceId(String.valueOf(supplierMaterial.getFormInstId()));
            ydClient.operateData(ydParam,YDConf.FORM_OPERATION.update);
            for (Pricing pricing:pricings){
                upsertMaterialDetail(pricing,supplierMaterial,formData);
            }
        }else{
            // 新增
            ydParam.setFormDataJson(JSON.toJSONString(formData));
            String formInstId=(String) ydClient.operateData(ydParam,YDConf.FORM_OPERATION.create);
            int st=0;
            for (Pricing pricing:pricings){
                upsertMaterialDetail(pricing,supplierMaterial,formData);
                st++;
            }
            supplierMaterial.setMaterialDetailNumber(String.valueOf(st));
            supplierMaterial.setIsNeedSyncYd("否");// 更新是否需要同步到宜搭
            supplierMaterial.setFormInstId(formInstId);// 更新实例编号
            baseMapper.updateById(supplierMaterial);
        }
    }

    private void upsertMaterialDetail(Pricing pricing,SupplierMaterial supplierMaterial,Map formData){
        YDParam ydParam2 = YDParam.builder().formUuid(_matchFormUuid("MATERIALDETAIL"))
                .useLatestVersion(true).build();
        QueryWrapper<MaterialDetail> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(MaterialDetail::getSupplierId,supplierMaterial.getSupplierId())
                .eq(MaterialDetail::getProjectId,pricing.getProjectId())
                .eq(MaterialDetail::getMaterialId,supplierMaterial.getMaterialId());
        List<MaterialDetail> materialDetails =materialDetailMapper.selectList(queryWrapper);
        if(materialDetails!=null&&materialDetails.size()>0){
            MaterialDetail materialDetail=materialDetails.get(0);
            String rate;// 服务费率
            if(pricing.getRateMap().containsKey(materialDetail.getClassifyTwo())){// 第二分类优先匹配
                rate=pricing.getRateMap().get(materialDetail.getClassifyTwo());
            }else if(pricing.getRateMap().containsKey(materialDetail.getClassifyOne())){// 第一分类匹配
                rate=pricing.getRateMap().get(materialDetail.getClassifyOne());
            }else{
                return;
            }
            String[] rates=rate.split("_");
            materialDetail.setRate(rates[0]);
            materialDetail.setRateNext(rates[1]);
            materialDetail.setSupplyPrice(cal(materialDetail.getUnitPrice(),rates[0]));
            materialDetail.setSupplyPriceNext(cal(materialDetail.getUnitPriceNext(),rates[0]));
            // 更新明细中间表数据库
            materialDetailMapper.updateById(materialDetail);
            // 更新明细中间表宜搭数据
            ydParam2.setUpdateFormDataJson(JSONObject.toJSONString(materialDetail.toYidaFormDataMap()));
            ydParam2.setFormInstanceId(String.valueOf(materialDetail.getFormInstId()));
            ydClient.operateData(ydParam2,YDConf.FORM_OPERATION.update);
        }else{
            MaterialDetail materialDetail=MaterialDetail.toBean(formData);
            String rate;// 服务费率
            if(pricing.getRateMap().containsKey(materialDetail.getClassifyTwo())){// 第二分类优先匹配
                rate=pricing.getRateMap().get(materialDetail.getClassifyTwo());
            }else if(pricing.getRateMap().containsKey(materialDetail.getClassifyOne())){// 第一分类匹配
                rate=pricing.getRateMap().get(materialDetail.getClassifyOne());
            }else{
                return;
            }
            String[] rates=rate.split("_");
            materialDetail.setRate(rates[0]);
            materialDetail.setRateNext(rates[1]);
            materialDetail.setSupplyPrice(cal(materialDetail.getUnitPrice(),rates[0]));
            materialDetail.setSupplyPriceNext(cal(materialDetail.getUnitPriceNext(),rates[0]));
            materialDetail.setProjectId(pricing.getProjectId());
            materialDetail.setProjectName(pricing.getProjectName());
            ydParam2.setFormDataJson(JSONObject.toJSONString(materialDetail.toYidaFormDataMap()));
            String priFormInstId=(String) ydClient.operateData(ydParam2,YDConf.FORM_OPERATION.create);
            materialDetail.setFormInstId(priFormInstId);
            materialDetailMapper.insert(materialDetail.create());
        }
    }

    public IPage<SupplierMaterial> getProducts(Page<SupplierMaterial> page, Map<String, Object> params) {
        // 构造查询条件（可选）
        QueryWrapper<SupplierMaterial> queryWrapper = new QueryWrapper<>();
        // ... 根据params设置查询条件 ...
        // 执行分页查询
        return baseMapper.selectPage(page, queryWrapper);
    }

    @Override
    public McR getList(Integer current, Integer size) {
        Page<SupplierMaterial> page=new Page<>(current,size);
        IPage iPage = getProducts(page,null);
        return McR.success(iPage);
    }

    @Override
    public void syncPrice() {
        // 每周同步  ==> 直接修改数据库供应商原材料表 成本单价为下周成本单价、同步标识为“是”。通过供应商原材料更新业务逻辑实现同步
        baseMapper.updateUnitPrice();
    }

    @Override
    public void projectSupplierChange(String projectId, String oldId, String newId,String newName) {
        Map<String,String> ID_MAP=new HashMap<>();
        // 1.复制原材料数据到数据库？
        List<SupplierMaterial> supplierMaterials=baseMapper.selectListForCopy(projectId,oldId);
        int no = 1;
        String name= PinyinUtil.getFirstLetter(newName.replace("供应商",""),"").toUpperCase();
        for (SupplierMaterial supplierMaterial:supplierMaterials){
            supplierMaterial.create();
            supplierMaterial.setSupplierId(newId);
            supplierMaterial.setSupplierName(newName);
            String id=name+String.format("%05d",no);
            ID_MAP.put(supplierMaterial.getMaterialId(),id);
            supplierMaterial.setMaterialId(id);// 原材料编号怎么处理
            baseMapper.insert(supplierMaterial);
            no++;
        }
        // 等待同步
        sync();
        // 2.宜搭菜品管理表单  替换供应商原材料编号、供应商名称
        List<Map> yidaList= (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("FOOD")).searchCondition(
                JSONObject.toJSONString(UtilMap.map("textField_lln3lmn1",projectId)))
                .build(),YDConf.FORM_QUERY.retrieve_list_all).getData();
        for (Map map:yidaList){
            Map formData=UtilMap.getMap(map,"formData");
            String formInstId=UtilMap.getString(map,"formInstId");
            List<Map> list=UtilMap.getList(formData,"tableField_llm1i9yy");// 材料清单
            for (int i = 0; i < list.size(); i++) {
                // 查询数据库
                String nId=ID_MAP.get(list.get(i).get("textField_lmk94yf5"));
                QueryWrapper<MaterialDetail> queryWrapper = new QueryWrapper<>();
                queryWrapper.lambda().eq(MaterialDetail::getSupplierId,newId)
                        .eq(MaterialDetail::getProjectId,projectId)
                        .eq(MaterialDetail::getMaterialId,nId);
                List<MaterialDetail> materialDetails =materialDetailMapper.selectList(queryWrapper);
                if(materialDetails!=null&&materialDetails.size()>0){
                    list.get(i).put("associationFormField_lln3lmmv", Arrays.asList(UtilMap.map("title, instanceId, appType, formUuid, formType",
                            materialDetails.get(0).getMaterialName(),materialDetails.get(0).getFormInstId(),
                            "APP_OHSG8KMIP9SGXV32XUQJ",_matchFormUuid("MATERIALDETAIL"),"receipt")));// 关联中间表
                }
                list.get(i).put("textField_lmk94yf5",nId);// 原材料编号
            }
            YDParam ydParam = YDParam.builder().formUuid(_matchFormUuid("MATERIALDETAIL"))
                    .updateFormDataJson(JSONObject.toJSONString(UtilMap.map("tableField_llm1i9yy",list)))
                    .formInstanceId(formInstId)
                    .useLatestVersion(true).build();
            ydClient.operateData(ydParam,YDConf.FORM_OPERATION.update);
        }
    }

    // 缓存
    private static Map<String,List<Pricing>> SUPPLIER_PRICING_MAP=new HashMap<>();
    // 获取定价单
    private List<Pricing> getPricings(String supplierId){
        if(SUPPLIER_PRICING_MAP.containsKey(supplierId)){
            return SUPPLIER_PRICING_MAP.get(supplierId);
        }
        List<Pricing> list=new ArrayList<>();
        List<Map> yidaList= (List<Map>) ydClient.queryData(YDParam.builder().formUuid(_matchFormUuid("PRICING")).searchCondition(
                JSONObject.toJSONString(UtilMap.map("textField_llzzbai8",supplierId)))
                .build(),YDConf.FORM_QUERY.retrieve_list_all).getData();
        for(Map map:yidaList){
            Map formData=UtilMap.getMap(map,"formData");
            Pricing pricing= BeanUtil.mapToBean(formData,Pricing.class,false);
            List<Map> detailList= (List<Map>) formData.get("tableField_llq74mwk");
            Map<String,String> data=new HashMap();
            for(Map detailMap:detailList){
                if("已启用".equals(String.valueOf(detailMap.get("selectField_lpw1n0af")))){
                    data.put(String.valueOf(detailMap.get(!PublicUtil.isNull(detailMap.get("selectField_lv3v3911"))?"selectField_lv3v3911":"selectField_llq74mwl")),
                            String.valueOf(detailMap.get("numberField_llq74mwm")).concat("_").concat(String.valueOf(detailMap.get("numberField_lpplr3im"))));
                }
            }
            pricing.setRateMap(data);
            log.info("pricing:{}",JSONObject.toJSONString(pricing));
            list.add(pricing);
        }
        SUPPLIER_PRICING_MAP.put(supplierId,list);
        return list;
    }

    private String cal(String unitPrice,String rate){
        return NumberUtil.roundStr(NumberUtil.div(NumberUtil.mul(unitPrice,NumberUtil.add(rate,"100").toString()).toString(),"100").toString(),2);
    }

    public static void main(String[] args) {
        System.out.println(NumberUtil.sub(5,1));
    }

}
