package nckd.jimin.jyyy.fi.mservice;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import kd.bos.dataentity.entity.DynamicObject;
import kd.bos.dataentity.entity.DynamicObjectCollection;
import kd.bos.exception.KDBizException;
import kd.bos.ext.fi.plugin.ArApConvert.util.EmptyUtils;
import kd.bos.logging.Log;
import kd.bos.logging.LogFactory;
import kd.bos.orm.query.QCP;
import kd.bos.orm.query.QFilter;
import kd.bos.sdk.util.KHttpClientUtils;
import kd.bos.servicehelper.BusinessDataServiceHelper;
import kd.bos.servicehelper.QueryServiceHelper;
import kd.bos.util.StringUtils;
import nckd.base.helper.CommonHelperUtils;

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

public class SyncSapFIUtils {
    private static final Log logger = LogFactory.getLog(SyncSapFIUtils.class);
    /**
     * 向SAP系统发送POST请求并返回结果
     * 该方法主要用于与SAP系统进行数据交互，通过POST请求发送JSON数据，并接收SAP系统的响应
     *
     * @param jsonData 要发送的JSON数据
     * @return SAP系统的响应结果，以字符串形式返回
     * @throws KDBizException 如果请求失败，抛出业务异常
     */
    public static String postDataToSAP(String urlType, String jsonData)
    {
        try {
            Map<String, String> mapentity = CommonHelperUtils.getCommonParams("SAP");
            if(mapentity == null){
                return null;
            }
            String param_voucher_url = mapentity.get("voucher_url");
            String param_voucher_archive_url = mapentity.get("voucher_archive_url");
            String param_username = mapentity.get("username");
            String param_password = mapentity.get("password");

            String post_url = null;
            switch (urlType) {
                case "voucher":
                    post_url = param_voucher_url;break;
                case "voucherArchive":
                    post_url = param_voucher_archive_url;break;
                default:
                    break;
            }

            if( StringUtils.isEmpty(param_username) || StringUtils.isEmpty(param_password)
                    || StringUtils.isEmpty(post_url) ){
                return null;
            }

            String encoded = Base64.getEncoder().encodeToString((param_username + ":" + param_password).getBytes());
            Map<String, String> header = new HashMap<>();
            header.put("Content-Type", "application/json; charset=UTF-8");
            header.put("Authorization", "Basic " + encoded);

            String result = KHttpClientUtils.postjson(post_url, header, jsonData);
            return result;
        } catch (Exception e) {
            throw new KDBizException("请求SAP接口失败：" + e.getMessage());
        }
    }

    /**
     * 获取字符串中最后一个 '.' 之前的部分
     *
     * @param str 输入字符串
     * @return 第一个 '.' 之前的部分，如果没有 '.' 则返回NULL
     */
    public static String getProjectNumberForParent(String str) {
        int firstDotIndex = str.indexOf('.');
        if (firstDotIndex == -1) {
            return null; // 没有找到 '.'，返回NULL
        }
        return str.substring(0, firstDotIndex);
    }


    public static  JSONObject convertCosmicVoucherToSAPForEntry(DynamicObject voucher,String maincfitemNumber,String projectNumber,Map<String, String> auxpropertiesMap) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        //账套代码
        String ZZTM = "FDZT";  //法定账套
        //公司代码
        //String BUKRS = voucher.getString("org.number");
        //币制代码
        String WAERS = StringUtils.isEmpty(voucher.getString("entries.currency.number")) ? "" : voucher.getString("entries.currency.number");
        //上游单据编号
        String BKTXT = "";
        String ZUONR = ""; 
        String billtype = voucher.getString("sourcebilltype");
        if(StringUtils.isNotEmpty(billtype)) {
            String sourcebill = voucher.getString("sourcebill");
            if(StringUtils.isNotEmpty(sourcebill) && !sourcebill.equals("0")) {
                //上游单据编号
                DynamicObject sourcebillDyn = BusinessDataServiceHelper.loadSingle(sourcebill, billtype);
                BKTXT = sourcebillDyn.getString("billno");
                //如果有上游单据有合同号，需要取出合同号  当单据类型为对公报错单，或者预付单 时
                if (billtype.equals("er_publicreimbursebill") || billtype.equals("er_prepaybill")) {
                    String contractcode = sourcebillDyn.getString("contractsconn");
                    if (StringUtils.isNotEmpty(contractcode)) {
                        ZUONR = contractcode;
                    }
                }
            }
        }
        String BUZEI = voucher.getString("entries.seq"); //凭证条目
        String HKONT = voucher.getString("entries.account.number"); //科目
        int entrydc = voucher.getInt("entries.entrydc"); //凭证方向  1 借贷方  -1 贷方
        BigDecimal WRBTR = BigDecimal.ZERO;
        BigDecimal DMBTR = BigDecimal.ZERO;
        if(entrydc == 1){
            WRBTR = voucher.getBigDecimal("entries.debitori"); //原币金额
            DMBTR = voucher.getBigDecimal("entries.debitlocal"); //本币金额
        }else if((entrydc == -1)){
            WRBTR = voucher.getBigDecimal("entries.creditori");  //原币金额
            DMBTR = voucher.getBigDecimal("entries.creditlocal"); //本币金额            
        }
        if(WRBTR.compareTo(BigDecimal.ZERO) == 0){
            WRBTR = DMBTR;
        }

        String BSCHL = String.valueOf(entrydc); //过账码

        String SGTXT = StringUtils.isEmpty(voucher.getString("entries.edescription")) ? "" : voucher.getString("entries.edescription"); //凭证行项目文本
        String KOSTL = "";  //成本中心
        String PROJK = "";  //项目
        String KUNNR = "";  //客户
        String RSTGR = ""; //现金流量项目
        String LIFNR = ""; //供应商
        String VBUND = "";
        String ZFBDT = sdf.format(voucher.getDate(GlVoucherConstantInfo.BOOKEDDATE));  //到期日 取记账日期

        ///申请人
        String XREF1 = StringUtils.isEmpty(voucher.getString("entries.nckd_applierv")) ? "" : voucher.getString("entries.nckd_applierv");  //凭证辅助项1  nckd_applierv
        logger.info ("SAP凭证辅助项2:"+voucher.getString("entries.nckd_applierv"));
        String XREF2 = "";
        //交易流水号
        String XREF3 = StringUtils.isEmpty(voucher.getString("entries.nckd_detailseqid")) ? "" : voucher.getString("entries.nckd_detailseqid");
        logger.info ("SAP凭证辅助项1:"+voucher.getString("entries.nckd_detailseqid"));
        String ZZATTRI1 = "";
        String ZZATTRI2 = "";
        String ZZATTRI3 = StringUtils.isEmpty(voucher.getString("entries.nckd_documentitem")) ? "" : voucher.getString("entries.nckd_documentitem");;

        //现金流量项目    科目HKONT为1002*行项目需填写，现金流量表项
        if(StringUtils.isNotEmpty(HKONT)  && (HKONT.startsWith("1002"))) {
            RSTGR = maincfitemNumber;
        }
        //核算维度
        if(auxpropertiesMap != null && auxpropertiesMap.size() > 0){
            if(StringUtils.isNotEmpty(auxpropertiesMap.get("bd_customer"))){
                KUNNR = auxpropertiesMap.get("bd_customer");   //客户
            }
            if(StringUtils.isNotEmpty(auxpropertiesMap.get("bd_supplier"))){
                LIFNR = auxpropertiesMap.get("bd_supplier");   //供应商
            }
            if(StringUtils.isNotEmpty(auxpropertiesMap.get("bos_costcenter"))){
                KOSTL = auxpropertiesMap.get("bos_costcenter");   //成本中心
            }
            if(StringUtils.isNotEmpty(auxpropertiesMap.get("bd_project"))){
                PROJK = auxpropertiesMap.get("bd_project");  //项目
            }
        }

        JSONObject ENTRYITEMINFO = new JSONObject();

        ENTRYITEMINFO.put("BKTXT", BKTXT); //上游单据编号
        ENTRYITEMINFO.put("ZUONR", ZUONR); //凭证参考号
        ENTRYITEMINFO.put("BUZEI", BUZEI); //凭证条目
        ENTRYITEMINFO.put("HKONT", HKONT); //科目
        ENTRYITEMINFO.put("PRCTR", ""); //利润中心
        ENTRYITEMINFO.put("PROJK", PROJK); //项目
        ENTRYITEMINFO.put("RSTGR", RSTGR); //现金流量项目
        ENTRYITEMINFO.put("SGTXT", SGTXT); //凭证摘要
        ENTRYITEMINFO.put("WAERS", WAERS); //币种
        ENTRYITEMINFO.put("ZZTM", ZZTM); //法定账套
        ENTRYITEMINFO.put("WRBTR", WRBTR.toString()); //原币金额
        ENTRYITEMINFO.put("DMBTR", DMBTR.toString()); //本币金额
        ENTRYITEMINFO.put("ZFBDT", ZFBDT); //到期日
        ENTRYITEMINFO.put("MWSKZ", "");    //税控
        ENTRYITEMINFO.put("KOSTL", KOSTL); //成本中心
        ENTRYITEMINFO.put("LIFNR", LIFNR); //供应商
        ENTRYITEMINFO.put("KUNNR", KUNNR); //客户
        ENTRYITEMINFO.put("ZTERM", "");    //账期
        ENTRYITEMINFO.put("BSCHL", BSCHL); //过账码
        ENTRYITEMINFO.put("XREF1", XREF1);
        ENTRYITEMINFO.put("XREF2", XREF2);
        ENTRYITEMINFO.put("XREF3", XREF3);
        ENTRYITEMINFO.put("ZZATTRI1", ZZATTRI1);
        ENTRYITEMINFO.put("ZZATTRI2", ZZATTRI2);
        ENTRYITEMINFO.put("ZZATTRI3", ZZATTRI3);
        ENTRYITEMINFO.put("VBUND", VBUND); //

        return ENTRYITEMINFO;
    }

    public static JSONObject convertCosmicVoucherToSAPForHead(DynamicObject voucher) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");

        JSONObject HEADERITEMINFO = new JSONObject();

        //账套代码
        String ZZTM = "FDZT";  //法定账套
        //公司代码
        String BUKRS = voucher.getString("org.name");
        //币制代码
        String WAERS = StringUtils.isEmpty(voucher.getString("entries.currency.number")) ? "" : voucher.getString("entries.currency.number");
        //制单人
        String USNAM = voucher.getString("submitter.number");
        //业务日期
        String BLDAT = sdf.format(voucher.getDate(GlVoucherConstantInfo.BIZDATE));
        //凭证日期
        String BUDAT = sdf.format(voucher.getDate(GlVoucherConstantInfo.BOOKEDDATE));
        //业务类型
        String BLART = StringUtils.isEmpty(voucher.getString("nckd_blart")) ? "" : voucher.getString("nckd_blart");
        String BKTXT = "";
        String sourcebill = "";
        String billtype = voucher.getString("sourcebilltype");
        if(StringUtils.isNotEmpty(billtype)) {
            sourcebill = voucher.getString("sourcebill");
            if(StringUtils.isNotEmpty(sourcebill) && !sourcebill.equals("0")) {
                //上游单据编号
                DynamicObject sourcebillDyn = BusinessDataServiceHelper.loadSingle(sourcebill, billtype);
                BKTXT = sourcebillDyn.getString("billno");
            }

        }

        String XBLNR = StringUtils.isEmpty(voucher.getString("entries.edescription")) ? "" : voucher.getString("entries.edescription"); //凭证行项目文本

        String VOUCHERID = voucher.getString("id");

        HEADERITEMINFO.put(SAPParamHelper.ZZTM, ZZTM);  //账套代码
        HEADERITEMINFO.put(SAPParamHelper.BUKRS, BUKRS); //公司名称
        HEADERITEMINFO.put(SAPParamHelper.WAERS, WAERS); //币种
        HEADERITEMINFO.put(SAPParamHelper.BLDAT, BLDAT); //业务日期
        HEADERITEMINFO.put(SAPParamHelper.BUDAT, BUDAT); //凭证日期
        HEADERITEMINFO.put(SAPParamHelper.BKTXT, BKTXT); //上游单据编号
        HEADERITEMINFO.put(SAPParamHelper.USNAM, USNAM); //创建人
        HEADERITEMINFO.put(SAPParamHelper.BLART, BLART); //业务类型
        HEADERITEMINFO.put(SAPParamHelper.XBLNR, XBLNR); //外部凭证编号
        HEADERITEMINFO.put("BILLID", sourcebill); 
        HEADERITEMINFO.put("VOUCHERID", VOUCHERID); 

        return HEADERITEMINFO;
    }

    public static  String getVoucherData(JSONObject HEADERITEMINFO,JSONArray ENTRY_ITEM) {

        JSONObject BILL = new JSONObject();

        JSONObject OT_HEADER = new JSONObject();
        JSONArray HEADER_ITEM = new JSONArray();

        JSONObject OT_ITEM = new JSONObject();
        //JSONArray ENTRY_ITEM = new JSONArray();

        OT_ITEM.put("item", ENTRY_ITEM);

        HEADER_ITEM.add(HEADERITEMINFO);
        OT_HEADER.put("item", HEADER_ITEM);

        BILL.put("OT_HEADER", OT_HEADER);
        BILL.put("OT_ITEM", OT_ITEM);

        return BILL.toJSONString();
    }

    /**
     * 获取科目核算维度，现金流量项目
     * @param voucher
     * @return  示例  {银行账户=f000003, 合作金融机构=f000011, f000003=2059435197476122624, bd_accountbanks=361604200018150008791, f000011=2050711196931206145, bd_finorginfo=FI-003314}
     */
    public static Map<String, String> getAssGrp(DynamicObject voucher)
    {
        Map<String, String> auxpropertiesMap = new HashMap<>();

        // 获取现金流量项目
        String cfitemNumber = voucher.getString("entries.maincfitem.number");
        String cfitemName = voucher.getString("entries.maincfitem.name");

        if(kd.bos.dataentity.utils.StringUtils.isNotEmpty(cfitemNumber)){
            auxpropertiesMap.put("maincfitemNumber",  cfitemNumber);
            auxpropertiesMap.put("maincfitemName",  cfitemName);
        }

        // 获取辅助属性的值
        String value = voucher.getString("entries.assgrp.value");
        if (StringUtils.isEmpty(value)) {
            return auxpropertiesMap;
        }
        JSONObject jsonObject = JSON.parseObject(value);
        Map<String, String> assgrp = new HashMap<>();
        Set<String> keys = jsonObject.keySet();
        for (String key : keys) {
            String value1 = jsonObject.getString(key);
            assgrp.put(key, value1);
        }
        System.out.println("turborao test assgrp" + assgrp.toString());

        QFilter auxpropFilter = new QFilter("flexfield", QCP.in, keys);
        DynamicObjectCollection auxproperties = QueryServiceHelper.query("bd_auxproperty", "number,name,flexfield,valuesource", auxpropFilter.toArray());

        for (DynamicObject auxproperty : auxproperties) {
            String auxName = auxproperty.getString("name");
            String flexfield = auxproperty.getString("flexfield");
            String baseEntity = auxproperty.getString("valuesource");
            if (kd.bos.dataentity.utils.StringUtils.isNotEmpty(baseEntity)) {
                String auxValue = assgrp.get(flexfield);
                auxpropertiesMap.put(flexfield, auxValue);
                if (kd.bos.dataentity.utils.StringUtils.isNotEmpty(auxValue)) {
                    QFilter baseEntityFilter = new QFilter("id", QCP.equals, Long.valueOf(auxValue));
                    DynamicObject baseEntityDyn = QueryServiceHelper.queryOne(baseEntity, "id,number,name", baseEntityFilter.toArray());
                    String baseEntityNumber = baseEntityDyn.getString("number");
                    auxpropertiesMap.put(baseEntity, baseEntityNumber);
                }
            }
            // 将 auxNumber 和 auxName 存入 Map
            auxpropertiesMap.put(auxName, flexfield);
        }


        return auxpropertiesMap;
    }

    public static String getXREF1(String accountNumber)
    {
        if ((accountNumber.startsWith("1001")) || (accountNumber.startsWith("1002")) || (accountNumber.startsWith("1012"))) {
            return "1";
        }
        return "0";
    }

    public static String getVoucherArchiveData(String companyCode,String year)
    {
        JSONObject json = new JSONObject();
        json.put("BUKRS", EmptyUtils.isNotEmpty(companyCode) ? companyCode : "");
        json.put("GJAHR", year);
        json.put("BELNR", "");
        JSONObject itemMap = new JSONObject();
        itemMap.put("BUKRS", "");
        itemMap.put("GJAHR", "");
        itemMap.put("BELNR", "");
        JSONObject etMap = new JSONObject();
        etMap.put("item", itemMap);
        json.put("ET_ITEM", etMap);
        return json.toString();
    }

    public static String getVoucherFieldForQuery() {
        StringBuilder sb = new StringBuilder();
        sb.append(GlVoucherConstantInfo.ID).append(",");  //  凭证号
        sb.append(GlVoucherConstantInfo.BILLNO).append(",");  //  凭证号
        sb.append(GlVoucherConstantInfo.BIZDATE).append(",");  //  业务日期
        sb.append(GlVoucherConstantInfo.BOOKEDDATE).append(",");  //  记账日期
        sb.append(GlVoucherConstantInfo.DESCRIPTION).append(",");  //  凭证描述
        sb.append(GlVoucherConstantInfo.VOUCHERTYPE).append(",");  //   凭证类型
        sb.append(GlVoucherConstantInfo.VOUCHERTYPE).append(".name").append(",");  //   凭证类型名称
        sb.append(GlVoucherConstantInfo.ORG).append(",");  //  公司
        sb.append(GlVoucherConstantInfo.ORG).append(".number").append(",");  //   公司编码
        sb.append(GlVoucherConstantInfo.ORG).append(".name").append(",");  //   公司名称
        sb.append(GlVoucherConstantInfo.SUBMITTER).append(",");  //   制单人
        sb.append(GlVoucherConstantInfo.SUBMITTER).append(".number").append(",");  //   制单人编码
        sb.append(GlVoucherConstantInfo.SOURCEBILLTYPE).append(",");  //   来源单据类型
        sb.append(GlVoucherConstantInfo.SOURCEBILL).append(",");  //   来源单据ID
        sb.append("nckd_blart").append(",");  //   来源单据ID
        sb.append("entries,"); //  凭证行
        sb.append("entries.id,"); //  凭证行ID
        sb.append("entries.seq,");
        sb.append("entries.nckd_detailseqid,"); //流水号
        sb.append("entries.nckd_applierv,");  //申请人工号
        sb.append("entries.nckd_documentitem,"); //  项目
        sb.append("entries.").append(GlVoucherConstantInfo.CURRENCY).append(",");  //  凭证行币种
        sb.append("entries.").append(GlVoucherConstantInfo.CURRENCY).append(".number").append(",");  //  凭证行币种
        sb.append("entries.").append(GlVoucherConstantInfo.DEBITLOCAL).append(",");  //  凭证行借方金额
        sb.append("entries.").append(GlVoucherConstantInfo.CREDITLOCAL).append(",");  //   凭证行贷方金额
        sb.append("entries.").append(GlVoucherConstantInfo.DEBITORI).append(",");  //  凭证行原币借方金额
        sb.append("entries.").append(GlVoucherConstantInfo.CREDITORI).append(",");  //   凭证行原币贷方金额
        sb.append("entries.").append(GlVoucherConstantInfo.ENTRYDC).append(","); //  凭证行方向
        sb.append("entries.").append(GlVoucherConstantInfo.ACCOUNT).append(",");  //  凭证行科目
        sb.append("entries.").append(GlVoucherConstantInfo.ACCOUNT).append(".number").append(","); //  凭证行科目编码
        sb.append("entries.").append(GlVoucherConstantInfo.EXPIREDATE).append(","); //  凭证行凭证有效期
        sb.append("entries.").append(GlVoucherConstantInfo.ASSGRP).append(",");
        sb.append("entries.").append(GlVoucherConstantInfo.ASSGRP).append(".value").append(",");
        sb.append("entries.").append(GlVoucherConstantInfo.MAINCFITEM).append(","); // 凭证行 现金流量项目
        sb.append("entries.").append(GlVoucherConstantInfo.MAINCFITEM).append(".number").append(",");  // 凭证行 现金流量项目 编码
        sb.append("entries.").append(GlVoucherConstantInfo.MAINCFITEM).append(".name").append(",");  // 凭证行 现金流量项目名称
        sb.append("entries.").append(GlVoucherConstantInfo.EDESCRIPTION);  //  凭证行描述

        return sb.toString();
    }
}
