package com.jeeplus.finance.invoice.util.OMS;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.jeeplus.finance.invoice.domain.OMS.InvoiceOMSImportInfo;
import com.jeeplus.finance.invoice.domain.OMS.OrderItem;
import com.jeeplus.finance.invoice.domain.OMS.fastRed.OMSAllScenarioRedInvoiceInfo;
import com.jeeplus.finance.invoice.domain.OMS.fastRed.OMSApplyItem;
import com.jeeplus.finance.invoice.domain.OMS.fastRed.OMSFastRedInvoiceInfo;
import com.jeeplus.finance.invoice.domain.OMS.fastRed.OMSRedInvoiceConfirmQueryRequest;
import com.jeeplus.finance.invoice.domain.WorkInvoiceTaxClassificationCode;
import com.jeeplus.finance.invoice.service.dto.CwFinanceInvoiceDTO;

import com.jeeplus.finance.utils.Global;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.Base64;
import java.util.List;

import static com.jeeplus.finance.invoice.config.OmsConfig.*;

@Component
public class OMSNationUtil {

    /**
     * 从Base64编码的JSON响应中提取accessToken
     */
    public static String extractAccessTokenFromBase64(String getKey, String base64Str) {
        if (base64Str == null || StringUtils.isBlank(base64Str)) {
            return "";
        }
        // 1. 解码Base64得到JSON字符串
        byte[] decodeBytes = Base64.getDecoder().decode(base64Str);
        String jsonStr = new String(decodeBytes, StandardCharsets.UTF_8);
        // 2. 解析JSON提取accessToken
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        return jsonObject.getString(getKey);
    }

    /**
     * 从Base64编码的JSON响应中提取accessToken
     */
    public static String extractFromBase64OnClassStr(String base64Str) {
        if (base64Str == null ||StringUtils.isBlank(base64Str)) {
            return "";
        }
        // 1. 解码Base64得到JSON字符串
        byte[] decodeBytes = Base64.getDecoder().decode(base64Str);
        String jsonStr = new String(decodeBytes, StandardCharsets.UTF_8);
        // 2. 解析JSON提取accessToken
        JSONObject jsonObject = JSONObject.parseObject(jsonStr);
        return jsonObject.toJSONString();
    }

    // ========== 你的原方法（无需修改，保持不变） ==========
    public static String getDownFromBase64(String base64Str) {
        if (StringUtils.isBlank(base64Str)) {
            return "";
        }
        byte[] decodeBytes = null;
        String jsonStr = null;
        try {
            decodeBytes = Base64.getDecoder().decode(base64Str);
            jsonStr = new String(decodeBytes, StandardCharsets.UTF_8);
        } catch (IllegalArgumentException e) {
            System.err.println("Base64解码失败，密文格式错误：" + e.getMessage());
            return "";
        }

        try {
            JSONArray jsonArray = JSONArray.parseArray(jsonStr);
            if (jsonArray == null || jsonArray.size() == 0) {
                System.err.println("解码后的JSON数组为空");
                return "";
            }
            JSONObject jsonObject = jsonArray.getJSONObject(0);
            if (jsonObject == null) {
                System.err.println("JSON数组第一个元素不是JSONObject对象");
                return "";
            }
            return jsonObject.toJSONString();
        } catch (Exception e) {
            System.err.println("JSON解析失败：" + e.getMessage());
            e.printStackTrace();
            return "";
        }
    }


    //private static final String appId = Global.getConfig("omsAppId");
    //private static final String appKey = Global.getConfig("omsAppKey");
    //private static final String deptCode = Global.getConfig("omsDeptCode");
    //private static final String sellerName = Global.getConfig("omsSellerName");
    //private static final String sellerTaxno = Global.getConfig("omsSellerTaxno");
    //private static final String bankName = Global.getConfig("omsBankName");
    //private static final String bankAccount = Global.getConfig("omsBankAccount");



    /**
     * 开蓝票
     * 整理数据明文
     * @param workInvoiceId 开票信息id，最好是将数据整体传过来
     * @Param workInvoice   需要开票的信息
     * @return
     */
    public String neatenData(String workInvoiceId, CwFinanceInvoiceDTO workInvoice, WorkInvoiceTaxClassificationCode workInvoiceTaxClassificationCode) {
        List<OrderItem> orderItems = Lists.newArrayList();

        InvoiceOMSImportInfo omsImportInfo = new InvoiceOMSImportInfo();
        omsImportInfo.setDeptCode(deptCode);
        omsImportInfo.setOrderno(workInvoiceId);
        omsImportInfo.setSellerName(sellerName);
        omsImportInfo.setSellerTaxno(sellerTaxno); //销方纳税人识别号，必填
        //生产环境
        omsImportInfo.setSellerBank(bankName); //销售方开户行名称
        omsImportInfo.setSellerBankaccount(bankAccount); //销售方开户行账号
        //* 开票类型(此处固定是蓝字票)
        //* 01:红字发票 02:蓝字发票，必填
        omsImportInfo.setInvKind("02");


        //* 发票类型
        //* 01:数电票(增值税专用发票) 02:数电票(普通发票)等
        if(workInvoice.getType().equals("1")){
            omsImportInfo.setInvType("01");
        }else{
            omsImportInfo.setInvType("02");
        }

        //添加购买方信息
        //测试环境
        //omsImportInfo.setBuyerName("深圳市爱人人餐饮服务有限公司");
        //omsImportInfo.setBuyerTaxno("500102203117204029");
        //生产环境
        omsImportInfo.setBuyerName(workInvoice.getBillingWorkplaceReal());    //购买方名称
        omsImportInfo.setBuyerTaxno(workInvoice.getTaxpayerIdentificationNo());  //购买方信用代码
        omsImportInfo.setBuyerAddr(workInvoice.getAddress()); //购买方地址
        omsImportInfo.setBuyerPhone(workInvoice.getTelPhone()); //购买方电话
        omsImportInfo.setBuyerBank(workInvoice.getOpenBank()); //购买方开户行名称
        omsImportInfo.setBuyerBankaccount(workInvoice.getBankAccount()); //购买方开户银行账号

        //omsImportInfo.setBuyerNationality(""); //购买方国籍/地区代码
        //omsImportInfo.setBuyerIdcardno(""); //购买方证件号码
        //omsImportInfo.setBuyerIdcartype(""); //购买方证件类型
        //omsImportInfo.setBuyerCellphone(""); //购买方手机号
        //omsImportInfo.setBuyerEmail(""); //购买方邮箱


        //判定是个人开票 还是企业开票
        if(workInvoice.getBillingType().equals("1")){
            omsImportInfo.setBuyerType("0"); //购买方类型(0：企业；1：自然人) 默认企业
        }else if(workInvoice.getBillingType().equals("2")){
            omsImportInfo.setBuyerType("1"); //购买方类型(0：企业；1：自然人) 默认企业
        }else{
            omsImportInfo.setBuyerType("0"); //购买方类型(0：企业；1：自然人) 默认企业
        }

        // 如果开票信息存在备注，那么将备注信息进行添加
        if (StringUtils.isNotBlank(workInvoice.getRemarks())) {
            omsImportInfo.setRemarks(workInvoice.getRemarks());
        }

        //omsImportInfo.setRemarks("zzsytdm01,xfsytdm01");


        OrderItem orderItem = new OrderItem();
        //发票行编号
        orderItem.setLineCode("1");
        //发票行性质 00(正常行)、01(折扣行)、02(被折扣行)
        orderItem.setLineType("00");
        //添加商品名称
        orderItem.setGoodsName(workInvoiceTaxClassificationCode.getGoodName());
        //商品数量
        orderItem.setQty(BigDecimal.valueOf(1));
        //orderItem.setPrice(BigDecimal.valueOf(100.00));
        //默认含税
        orderItem.setPriceTaxFlag(workInvoiceTaxClassificationCode.getPriceTax()); //含税状态 0不含税；1含税
        orderItem.setTaxrate(BigDecimal.valueOf(workInvoiceTaxClassificationCode.getTaxRate())); //税率
        //orderItem.setAmount(BigDecimal.valueOf(100.00)); //金额
        //orderItem.setTax(BigDecimal.valueOf(1.00));//税额
        orderItem.setTaxamount(new BigDecimal(workInvoice.getAccount()));//含税金额
        //orderItem.setTaxamount(BigDecimal.valueOf(workInvoice.getMoney()));//含税金额
        //orderItem.setGoodstaxno("109050901");//税收分类编码(电脑)
        orderItem.setGoodstaxno(workInvoiceTaxClassificationCode.getGoodsTaxno());//税收分类编码(餐饮)

        orderItems.add(orderItem);

        omsImportInfo.setOrderItems(orderItems);
        // 核心一行代码：Java对象 转 JSON格式字符串
        String jsonStr = JSON.toJSONString(omsImportInfo);

        // 2. 核心新增：JSON字符串 转 标准Base64编码字符串【解决你的核心问题】
        String base64Str = Base64.getEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        return base64Str;
    }



    /**
     * 开红票
     * 整理数据明文
     */
    public String neatenFastRedInvoiceData(String allEinvno) {

        OMSFastRedInvoiceInfo omsImportInfo = new OMSFastRedInvoiceInfo();
        omsImportInfo.setDeptCode(deptCode);
        omsImportInfo.setAllEinvno(allEinvno);
        omsImportInfo.setRedReason("02");

        // 核心一行代码：Java对象 转 JSON格式字符串
        String jsonStr = JSON.toJSONString(omsImportInfo);

        // 2. 核心新增：JSON字符串 转 标准Base64编码字符串【解决你的核心问题】
        String base64Str = Base64.getEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        return base64Str;
    }


    /**
     * 开红票（全类型）
     * 整理数据明文
     * @param workInvoiceId 开票的id
     * @param originalInvno 原蓝票发票号码（数电票号码）
     * @param workInvoice 红冲发票信息
     * @param workInvoiceRelevancy 原蓝票被红冲发票信息
     * @param workInvoiceTaxClassificationCode 红冲数据的税收分类编码
     * @param relevancyBillingContentDetail 被红冲蓝票数据的税收分类编码
     * @return
     */
    public String neatenAllScenarioRedInvoiceData(String workInvoiceId, String originalInvno, CwFinanceInvoiceDTO workInvoice, CwFinanceInvoiceDTO workInvoiceRelevancy, WorkInvoiceTaxClassificationCode workInvoiceTaxClassificationCode, WorkInvoiceTaxClassificationCode relevancyBillingContentDetail) {
        List<OMSApplyItem> orderItems = Lists.newArrayList();

        OMSAllScenarioRedInvoiceInfo omsAllScenarioRedInvoiceInfo = new OMSAllScenarioRedInvoiceInfo();
        omsAllScenarioRedInvoiceInfo.setDeptCode(deptCode);
        omsAllScenarioRedInvoiceInfo.setApplyNo(workInvoiceId);   //红字发票申请单号 即 开票的id
        omsAllScenarioRedInvoiceInfo.setApplyIdentity("0");
        omsAllScenarioRedInvoiceInfo.setSellerTaxno(sellerTaxno);
        omsAllScenarioRedInvoiceInfo.setSellerName(sellerName);
        //添加购买方信息
        //测试环境
        //omsAllScenarioRedInvoiceInfo.setBuyerName("深圳市爱人人餐饮服务有限公司");
        //omsAllScenarioRedInvoiceInfo.setBuyerTaxno("500102203117204029");
        //生产环境
        omsAllScenarioRedInvoiceInfo.setBuyerName(workInvoice.getBillingWorkplaceReal());    //购买方名称
        omsAllScenarioRedInvoiceInfo.setBuyerTaxno(workInvoice.getTaxpayerIdentificationNo());  //购买方信用代码

        //原蓝票发票号码
        omsAllScenarioRedInvoiceInfo.setOriginalInvno(originalInvno);
        //原蓝票发票类型
        //* 01:数电票(增值税专用发票) 02:数电票(普通发票)等
        if(workInvoiceRelevancy.getType().equals("1")){
            omsAllScenarioRedInvoiceInfo.setOriginalInvType("01");
        }else{
            omsAllScenarioRedInvoiceInfo.setOriginalInvType("02");
        }

        //此处用来计算红冲的蓝票的税额

        // 1. 获取含税金额（价税合计）- 从workInvoice中取值
        BigDecimal blueTaxIncludedAmount = new BigDecimal(workInvoiceRelevancy.getAccount());
        //获取税率
        BigDecimal blueTaxRate;
        if (relevancyBillingContentDetail.getTaxRate() != null) {
            blueTaxRate = BigDecimal.valueOf(relevancyBillingContentDetail.getTaxRate());
            // 税率格式兼容：6（整数）转0.06，0.06直接用（保留4位小数，四舍五入）
            blueTaxRate = blueTaxRate.compareTo(BigDecimal.ONE) > 0
                    ? blueTaxRate.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP)
                    : blueTaxRate;
        } else {
            // 默认税率6%（用字符串构造避免浮点精度丢失）
            blueTaxRate = new BigDecimal("0.06");
        }

        // 3. 计算不含税金额：含税金额 ÷ (1+税率)，保留2位小数（四舍五入）
        BigDecimal blueTaxExcludedAmount = blueTaxIncludedAmount
                .divide(BigDecimal.ONE.add(blueTaxRate), 2, BigDecimal.ROUND_HALF_UP);

        // 4. 计算税额：含税金额 - 不含税金额（保证无尾差，适配正负值）
        BigDecimal blueTaxAmount = blueTaxIncludedAmount.subtract(blueTaxExcludedAmount);

        //原蓝票金额
        omsAllScenarioRedInvoiceInfo.setOriginalInvAmount(blueTaxExcludedAmount.toString());

        //原蓝票税额
        omsAllScenarioRedInvoiceInfo.setOriginalInvTax(blueTaxAmount.toString());


        //此处用来处理红冲对应的金额汇总
        // 1. 获取含税金额（价税合计）- 从workInvoice中取值
        BigDecimal taxIncludedAmount =  new BigDecimal(workInvoice.getAccount());

        // 2. 处理税率：优先用动态值，为空则默认6%（兼容6/0.06两种格式）
        BigDecimal taxRate;
        if (workInvoiceTaxClassificationCode.getTaxRate() != null) {
            taxRate = BigDecimal.valueOf(workInvoiceTaxClassificationCode.getTaxRate());
            // 税率格式兼容：6（整数）转0.06，0.06直接用（保留4位小数，四舍五入）
            taxRate = taxRate.compareTo(BigDecimal.ONE) > 0
                    ? taxRate.divide(new BigDecimal("100"), 4, BigDecimal.ROUND_HALF_UP)
                    : taxRate;
        } else {
            // 默认税率6%（用字符串构造避免浮点精度丢失）
            taxRate = new BigDecimal("0.06");
        }

        // 3. 计算不含税金额：含税金额 ÷ (1+税率)，保留2位小数（四舍五入）
        BigDecimal taxExcludedAmount = taxIncludedAmount
                .divide(BigDecimal.ONE.add(taxRate), 2, BigDecimal.ROUND_HALF_UP);

        // 4. 计算税额：含税金额 - 不含税金额（保证无尾差，适配正负值）
        BigDecimal taxAmount = taxIncludedAmount.subtract(taxExcludedAmount);


        //合计金额（不含税）
        omsAllScenarioRedInvoiceInfo.setTotalAmount(taxExcludedAmount.toString());
        //合计税额
        omsAllScenarioRedInvoiceInfo.setTotalTax(taxAmount.toString());
        //价税合计
        omsAllScenarioRedInvoiceInfo.setTotalTaxamount(taxIncludedAmount.setScale(2, BigDecimal.ROUND_HALF_UP).toString());

        //* 冲红原因（必填）
        //* 01:开票有误 02:销货退回 03:服务中止 04:销售折让
        if(StringUtils.isBlank(workInvoice.getRedFlushReason())){
            //如果蓝票开票额 + 红票开票额 大于零，则表示此处是部分红冲，那么红冲原因就是04
            if (blueTaxIncludedAmount.add(taxIncludedAmount).compareTo(BigDecimal.ZERO) > 0) {
                omsAllScenarioRedInvoiceInfo.setRedReason("04");
            }else{
                omsAllScenarioRedInvoiceInfo.setRedReason("01");
            }
        }else{
            omsAllScenarioRedInvoiceInfo.setRedReason(workInvoice.getRedFlushReason());
        }
        //是否自动开票
        omsAllScenarioRedInvoiceInfo.setAutoMakeInv("Y");


        OMSApplyItem orderItem = new OMSApplyItem();
        orderItem.setLineCode("1");
        //添加商品名称
        orderItem.setGoodsName(workInvoiceTaxClassificationCode.getGoodName());

        //orderItem.setQty(BigDecimal.valueOf(1));
        //orderItem.setPrice(BigDecimal.valueOf(100.00));



        orderItem.setAmount(taxExcludedAmount); //金额
        orderItem.setTax(taxAmount);//税额
        orderItem.setTaxrate(BigDecimal.valueOf(workInvoiceTaxClassificationCode.getTaxRate())); //税率
        orderItem.setTaxamount( new BigDecimal(workInvoice.getAccount()));//含税金额
        orderItem.setGoodstaxno(workInvoiceTaxClassificationCode.getGoodsTaxno());//税收分类编码
        orderItem.setOriLineCode("1");//对应蓝票明细序号

        orderItems.add(orderItem);
        omsAllScenarioRedInvoiceInfo.setApplyItems(orderItems);

        // 核心一行代码：Java对象 转 JSON格式字符串
        String jsonStr = JSON.toJSONString(omsAllScenarioRedInvoiceInfo);

        // 2. 核心新增：JSON字符串 转 标准Base64编码字符串【解决你的核心问题】
        String base64Str = Base64.getEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        return base64Str;
    }


    /**
     * 查询红字确认单查询接口结果的参数
     * @param applyNo
     * @return
     */
    public String neatenAllScenarioRedInvoiceConfirmQueryData(String applyNo) {

        OMSRedInvoiceConfirmQueryRequest omsImportInfo = new OMSRedInvoiceConfirmQueryRequest();
        omsImportInfo.setDeptCode(deptCode);
        omsImportInfo.setApplyNo(applyNo);
        omsImportInfo.setApplyIdentity("0");


        // 核心一行代码：Java对象 转 JSON格式字符串
        String jsonStr = JSON.toJSONString(omsImportInfo);

        // 2. 核心新增：JSON字符串 转 标准Base64编码字符串【解决你的核心问题】
        String base64Str = Base64.getEncoder().encodeToString(jsonStr.getBytes(StandardCharsets.UTF_8));

        return base64Str;
    }

}
