package nc.impl.arap.dev;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.Gson;
import nc.api.arap.resource.IgnoreSslUtil;
import nc.bs.dao.BaseDAO;
import nc.bs.dao.DAOException;
import nc.bs.trade.business.HYSuperDMO;
import nc.impl.pubapp.pattern.data.vo.VOUpdate;
import nc.itf.arap.dev.IDevArapBill2R6Service;
import nc.jdbc.framework.processor.MapProcessor;
import nc.vo.arap.gathering.AggGatheringBillVO;
import nc.vo.arap.gathering.GatheringBillItemVO;
import nc.vo.bd.defdoc.DefdocVO;
import nc.vo.cmp.util.StringUtils;
import nc.vo.pub.BusinessException;
import nc.vo.pub.lang.UFDouble;
import nc.vo.pubapp.pattern.pub.MathTool;
import nc.vo.so.m30.entity.SaleOrderHVO;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.zip.GZIPInputStream;

/**
 * @Classname DevArapBill2R6Impl
 * @Description TODO
 * @Version 1.0.0
 * @Date 2025/7/26 16:08
 * @Created by ame
 */
public class DevArapBill2R6Impl implements IDevArapBill2R6Service {
    HYSuperDMO dmo = null;

    public HYSuperDMO getSuperDMO() {
        if (dmo == null) {
            dmo = new HYSuperDMO();
        }
        return dmo;
    }
    @Override
    public void updateR6Info(AggGatheringBillVO aggvo) throws Exception {
        GatheringBillItemVO[] billItemVOs = (GatheringBillItemVO[]) aggvo.getChildrenVO();
        String pk_org = (String) aggvo.getParentVO().getAttributeValue("pk_org");
        String pk_gatherbill = (String) aggvo.getParentVO().getAttributeValue("pk_gatherbill");
        JSONObject jsonObject=new JSONObject();
        JSONArray array=new JSONArray();
        List<SaleOrderHVO> saleOrderHVOList = new ArrayList<>();
        for (GatheringBillItemVO gatheringBillItemVO : billItemVOs) {
            JSONObject js_apct = afterChangeMny(gatheringBillItemVO.getSrc_billid(), pk_org, gatheringBillItemVO.getDef6(),
                    pk_gatherbill);
            if(js_apct!=null){
                SaleOrderHVO hvo = (SaleOrderHVO) js_apct.get("erphvo");
                saleOrderHVOList.add(hvo);
                js_apct.remove("erphvo");
                array.add(js_apct);
            }
        }
        if(saleOrderHVOList.isEmpty()){
            return;
        }
        SaleOrderHVO[] update = (SaleOrderHVO[]) new VOUpdate().update(saleOrderHVOList.toArray(new SaleOrderHVO[0]),new String[]{"vdef11","vdef14"});
        if(array!=null && array.size()>0){
            jsonObject.put("HTXSDD",array);
            pushBipCtOrderUpdate(jsonObject,saleOrderHVOList);
        }
    }

    @Override
    public void updateR6(AggGatheringBillVO aggvo) throws Exception {
        String id = aggvo.getHeadVO().getDef20();
        pushBipUpdate(id);
    }
    private void pushBipUpdate(String id) throws BusinessException {
        String baseUrl = "";
        Map<String, String> bipParamMap = checkBipParam();
        if (bipParamMap.isEmpty()) {
            return ;
        }
        baseUrl = bipParamMap.get("baseUrl");
        String contractSaleOrderUrl = bipParamMap.get("updateGatheringbill");// 开票申请单回传
        if (StringUtils.isEmpty(contractSaleOrderUrl)) {
            return ;
        }
        Gson gson = new Gson();
        try {
            String accessToken = getAccessToken(baseUrl, bipParamMap);
            JSONObject jsonObject=new JSONObject();
            jsonObject.put("id", id);
            jsonObject.put("generateStatus", "1");
            if (accessToken != "") {
                Map<String, String> tokenParam = new HashMap<>();
                tokenParam.put("access_token", accessToken);
                Map<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json");
                String custUpdateUrl = baseUrl + contractSaleOrderUrl;
                String resultString = doSendHttp(custUpdateUrl, "POST", tokenParam, "", headers,jsonObject.toString()
                        );
                Map updateMap = gson.fromJson(resultString, Map.class);
                if ("200".equals(updateMap.get("code"))) {// 保存更新成功后需要更新日志表
//                    getSuperDMO().updateArray(saleOrderHVOList.toArray(new SaleOrderHVO[0]));
                } else {
                    throw new BusinessException("合同销售订单同步plm失败【"+updateMap.get("message")+"】");
                }
            }
        } catch (Exception e) {
            throw new BusinessException("合同销售订单同步plm失败【"+e.getMessage()+"】");
        }
    }
    private JSONObject afterChangeMny(String csaleorderid, String pk_org, String ctid, String pk_gatherid) throws BusinessException {
        try {
            // 合同id
            if (StringUtils.isEmpty(ctid)) {
                return null;
            }
            if (StringUtils.isEmpty(csaleorderid)) {
                return null;
            }
            // 获取销售订单表头
            SaleOrderHVO hvo = (SaleOrderHVO) getSuperDMO().queryByPrimaryKey(SaleOrderHVO.class, csaleorderid);
            if (hvo == null) {
                return null;
            }
            String vdef9 = hvo.getVdef9();// BIP 合同销售订单id
            if (StringUtils.isEmpty(vdef9)) {// 为空，不是从bip 生成的
                return null;
            }
            // 合同金额vdef17
            UFDouble ctmny = new UFDouble(hvo.getVdef17() == null ? "0" : hvo.getVdef17());
            // 预收比例vdef15
            UFDouble yfrate = new UFDouble(hvo.getVdef15() == null ? "0" : hvo.getVdef15());
            UFDouble temp_yf_mny = ctmny.multiply(yfrate);
            // 发货比例vdef16
            UFDouble fhrate = new UFDouble(hvo.getVdef16() == null ? "0" : hvo.getVdef16());
            UFDouble temp_fh_mny = ctmny.multiply(fhrate);
            // vdef14 预付款标识
            String vdef14 = "01";// 01无约定预付款
            // vdef11 发货款标识
            String vdef11 = "fhk03";// fhk03无约定发货款
            UFDouble total_mny = UFDouble.ZERO_DBL;// 当前组织下本合同所有收款单金额累计
            String sum_sql = "select sum(money_cr) as money_cr from ar_gatheritem where def6 not in ('~') and dr=0   and def6='"
                    + ctid + "'";
            Map map = (Map) new BaseDAO().executeQuery(sum_sql, new MapProcessor());
            if (map != null) {
                 total_mny = map.get("money_cr")==null ? UFDouble.ZERO_DBL:new UFDouble(String.valueOf(map.get("money_cr")));
//                total_mny = new UFDouble(String.valueOf(map.get("money_cr")));
            }
            if ((MathTool.compareTo(yfrate, UFDouble.ZERO_DBL) == 0)) {

            } else {
                if (MathTool.compareTo(total_mny, temp_yf_mny) >= 0) {// 累计收款金额≥合同金额*预收比例
                    vdef14 = "02"; // 02有约定已收到预付款
                } else {
                    vdef14 = "03";// 03 有约定未收到款
                }
            }
            if ((MathTool.compareTo(fhrate, UFDouble.ZERO_DBL) == 0)) {

            } else {
                if (MathTool.compareTo(total_mny, temp_fh_mny) >= 0) {// 累计收款金额≥合同金额*发货比例
                    vdef11 = "fhk01";// fhk01有约定已收到发货款
                } else {
                    vdef11 = "fhk02";// fhk02有约定未收到发货款
                }
            }
            DefdocVO[] defdocVOs = (DefdocVO[]) getSuperDMO().queryByWhereClause(DefdocVO.class,
                    " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='xsdd' ) and code='" + vdef14
                            + "' and dr=0 ");
            if (defdocVOs != null && defdocVOs.length > 0) {
                hvo.setVdef14(defdocVOs[0].getPrimaryKey());
//                hvo.setVdef14(null);
                hvo.setStatus(1);
            }

            defdocVOs = (DefdocVO[]) getSuperDMO().queryByWhereClause(DefdocVO.class,
                    " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='FHK' ) and code='" + vdef11
                            + "' and dr=0 ");
            if (defdocVOs != null && defdocVOs.length > 0) {
                hvo.setVdef11(defdocVOs[0].getPrimaryKey());
//                hvo.setVdef11(null);
                hvo.setStatus(1);
            }

            JSONObject js_apct = new JSONObject();
            js_apct.put("id", hvo.getVdef9());
            js_apct.put("isShipRecdAmt", vdef11);
            js_apct.put("isPreRecv", vdef14);
            js_apct.put("actRecvAmt", hvo.getNreceivedmny().floatValue());
            js_apct.put("actPreRecvAmt", hvo.getNpreceivemny().floatValue());
            js_apct.put("erphvo",hvo);
            return js_apct;
        } catch (Exception e) {
            throw new BusinessException(e.getMessage());
        }
    }
    private void pushBipCtOrderUpdate(JSONObject array, List<SaleOrderHVO> saleOrderHVOList) throws BusinessException {
        String baseUrl = "";
        Map<String, String> bipParamMap = checkBipParam();
        if (bipParamMap.isEmpty()) {
            return ;
        }
        baseUrl = bipParamMap.get("baseUrl");
        String contractSaleOrderUrl = bipParamMap.get("contractSaleOrder");// 开票申请单回传
        if (StringUtils.isEmpty(contractSaleOrderUrl)) {
            return ;
        }
        Gson gson = new Gson();
        try {
            String accessToken = getAccessToken(baseUrl, bipParamMap);
            if (accessToken != "") {
                Map<String, String> tokenParam = new HashMap<>();
                tokenParam.put("access_token", accessToken);
                Map<String, String> headers = new HashMap<String, String>();
                headers.put("Content-Type", "application/json");
                String custUpdateUrl = baseUrl + contractSaleOrderUrl;
                String resultString = doSendHttp(custUpdateUrl, "POST", tokenParam, "", headers,
                        array.toJSONString());
                Map updateMap = gson.fromJson(resultString, Map.class);
                if ("200".equals(updateMap.get("code"))) {// 保存更新成功后需要更新日志表
//                    getSuperDMO().updateArray(saleOrderHVOList.toArray(new SaleOrderHVO[0]));
                } else {
                    throw new BusinessException("合同销售订单更新失败【"+updateMap.get("message")+"】");
                }
            }
        } catch (Exception e) {
            throw new BusinessException("合同销售订单更新失败【"+e.getMessage()+"】");
        }
    }
    private Map<String, String> checkBipParam() {
        Map<String, String> map = new HashMap<String, String>();
        String strWhere = " pk_defdoclist in (select pk_defdoclist from bd_defdoclist where code='BIP-sq' and dr=0 )  and dr=0";
        try {
            DefdocVO[] defdocVOs = (DefdocVO[]) getSuperDMO().queryByWhereClause(DefdocVO.class, strWhere);
            if (defdocVOs != null && defdocVOs.length > 0) {
                for (DefdocVO defdocVO : defdocVOs) {
                    map.put(defdocVO.getCode().trim(), defdocVO.getName());
                }
            }
        } catch (DAOException e) {
            e.printStackTrace();
        }
        return map;
    }

    private static String doGet(String path, Map<String, String> params) throws IOException {
        HttpURLConnection conn = null;
        InputStream is = null;
        BufferedReader br = null;
        StringBuilder result = new StringBuilder();
        try {
            if (params != null) {
                String paramStr = "";
                for (String key : params.keySet()) {
                    if (!paramStr.isEmpty()) {
                        paramStr += '&';
                    }
                    paramStr += key + '=' + params.get(key);
                }

                if (path.indexOf('?') > 0) {
                    path += '&' + paramStr;
                } else {
                    path += '?' + paramStr;
                }
            }
            // 创建远程url连接对象
            URL url = new URL(path);
            if ("https".equalsIgnoreCase(url.getProtocol())) {// 判定网址是否信任，不信任则调用忽略信任工具类SslUtil
                IgnoreSslUtil.ignoreSsl();
            }
            // 通过远程url连接对象打开一个连接，强转成HTTPURLConnection类
            conn = (HttpURLConnection) url.openConnection();
            conn.setRequestMethod("GET");
            // 设置连接超时时间和读取超时时间
            conn.setConnectTimeout(120000);
            conn.setReadTimeout(120000);
            conn.setRequestProperty("Accept", "application/json");
            // 发送请求
            conn.connect();
            // 通过conn取得输入流，并使用Reader读取
            if (200 == conn.getResponseCode()) {
                is = conn.getInputStream();
                br = new BufferedReader(new InputStreamReader(is, "UTF-8"));
                String line;
                while ((line = br.readLine()) != null) {
                    result.append(line);
                    System.out.println(line);
                }
            } else {
                System.out.println("ResponseCode is an error code:" + conn.getResponseCode());
            }
        } catch (MalformedURLException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result.toString();
    }

    private String getAccessToken(String baseUrl, Map<String, String> bipParamMap)
            throws NoSuchAlgorithmException, InvalidKeyException, IOException {
        String tokenUrl = baseUrl + "/iuap-api-auth/open-auth/selfAppAuth/getAccessToken";
//				String appKey = "f10c4bf17b1d4e1fb08eb82bf8540eab";
        String appKey = bipParamMap.get("appKey");

//				String appSecret = "71dc2a58ca378c1a1143231a62e73e75a60e9236";
        String appSecret = bipParamMap.get("appSecret");
        String accessToken = "";
        Map<String, String> params = new HashMap<>();

        params.put("appKey", appKey);
        String timestamp = String.valueOf(System.currentTimeMillis());
        params.put("timestamp", timestamp);
        // 计算签名
        Map<String, String> treeMap;
        if (params instanceof TreeMap) {
            treeMap = params;
        } else {
            treeMap = new TreeMap<>(params);
        }
        StringBuilder stringBuilder = new StringBuilder();
        for (Map.Entry<String, String> entry : treeMap.entrySet()) {
            stringBuilder.append(entry.getKey()).append(entry.getValue());
        }
        Mac mac = Mac.getInstance("HmacSHA256");

        mac.init(new SecretKeySpec(appSecret.getBytes(StandardCharsets.UTF_8), "HmacSHA256"));
        byte[] signData = mac.doFinal(stringBuilder.toString().getBytes(StandardCharsets.UTF_8));
        String base64String = Base64.getEncoder().encodeToString(signData);
        String signature = URLEncoder.encode(base64String, "UTF-8");
        params.put("signature", signature);

        String responseString = doGet(tokenUrl, params);

        Gson gson = new Gson();
        Map result = gson.fromJson(responseString, Map.class);
        if ("00000".equals(result.get("code"))) {
            Map<String, Object> tokenInfo = (Map<String, Object>) result.get("data");
            accessToken = (String) tokenInfo.get("access_token");

        }

        return accessToken;
    }

    public static String doSendHttp(String baseUrl, String method, Map<String, String> paramMap, String mediaType,
                                    Map<String, String> headers, String json) {
        HttpURLConnection urlConnection = null;
        InputStream in = null;
        OutputStream out = null;
        BufferedReader bufferedReader = null;
        String result = null;
        try {
            StringBuffer sb = new StringBuffer();
            sb.append(baseUrl);
            if (paramMap != null) {
                sb.append("?");
                for (Map.Entry<String, String> entry : paramMap.entrySet()) {
                    String key = entry.getKey();
                    String value = entry.getValue();
                    sb.append(key + "=" + value).append("&");
                    baseUrl = sb.toString().substring(0, sb.toString().length() - 1);
                }
            }
            URL urlobj = new URL(baseUrl);
            if ("https".equalsIgnoreCase(urlobj.getProtocol())) {// 判定网址是否信任，不信任则调用忽略信任工具类SslUtil
                IgnoreSslUtil.ignoreSsl();
            }
            urlConnection = (HttpURLConnection) urlobj.openConnection();
            urlConnection.setConnectTimeout(50000);
            urlConnection.setRequestMethod(method);
            urlConnection.setDoInput(true);
            urlConnection.setUseCaches(false);
            // 如果设置了自定义头，则打印它们
            if (headers != null && !headers.isEmpty()) {
                for (Map.Entry<String, String> entry : headers.entrySet()) {
                    urlConnection.addRequestProperty(entry.getKey(), entry.getValue());
                }
            }
            if (json != null && json.length() > 0) {
                urlConnection.setDoInput(true);
                urlConnection.setDoOutput(true);
                out = urlConnection.getOutputStream();
                out.write(json.getBytes("utf-8"));
                out.flush();
            }
            int resCode = urlConnection.getResponseCode();
            String ecod = urlConnection.getContentEncoding();
            if (resCode == HttpURLConnection.HTTP_OK || resCode == HttpURLConnection.HTTP_CREATED
                    || resCode == HttpURLConnection.HTTP_ACCEPTED) {
                if (!StringUtils.isEmpty(ecod) && ecod.equals("gzip")) {
                    in = new GZIPInputStream(urlConnection.getInputStream());
                } else {
                    in = urlConnection.getInputStream();
                }
            } else {
                in = urlConnection.getErrorStream();
            }
            bufferedReader = new BufferedReader(new InputStreamReader(in, "utf-8"));
            StringBuffer temp = new StringBuffer();
            String line = bufferedReader.readLine();
            while (line != null) {
                temp.append(line).append("\r\n");
                line = bufferedReader.readLine();
            }
            if (ecod == null || ecod.equals("gzip")) {
                ecod = Charset.forName("utf-8").name();
            }
            result = new String(temp.toString().getBytes("utf-8"), ecod);
        } catch (Exception e) {
            JSONObject js = new JSONObject();
            js.put("", -1);
            js.put("message", "调用外系统接口失败：" + e.getMessage());
            result = js.toString();
            e.printStackTrace();
        } finally {
            if (null != bufferedReader) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != out) {
                try {
                    out.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (null != in) {
                try {
                    in.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            urlConnection.disconnect();
        }
        return result;
    }
}
