package com.ruoyi.logistics.service.impl;
import com.alibaba.fastjson2.JSONObject;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.ruoyi.common.core.utils.StringUtils;
import com.ruoyi.common.redis.service.RedisIdGenerator;
import com.ruoyi.logistics.config.InvoiceConfig;
import com.ruoyi.logistics.domain.InvoiceRequest;
import com.ruoyi.logistics.domain.OrderRequest;
import com.ruoyi.logistics.domain.RptFinancialMonthSummary;
import com.ruoyi.logistics.service.IRptFinancialMonthSummaryService;
import com.ruoyi.logistics.service.InvoiceService;
import com.ruoyi.logistics.util.Base64Util;
import com.ruoyi.logistics.util.HttpUtil;
import com.ruoyi.logistics.util.SignUtil;
import com.ruoyi.logistics.util.TaxAmountCalculator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Service;
import java.math.BigDecimal;
import com.fasterxml.jackson.core.type.TypeReference;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.web.client.RestTemplate;

/**
 * 开票相关接口
 *
 * @author zxf
 * @date 2026-02-11
 */

@Service
public class InvoiceServiceImpl implements InvoiceService {
    private static final Logger logger = LoggerFactory.getLogger(InvoiceServiceImpl.class);
    @Autowired
    private RedisIdGenerator redisIdGenerator;
    @Autowired
    private InvoiceConfig invoiceConfig;
    @Autowired
    JdbcTemplate jdbcTemplate;
    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private IRptFinancialMonthSummaryService rptFinancialMonthSummaryService;

    /**
     * 电子发票专票开据
     * @param InvoiceRequest 开票相入参
     * @return 运单明细
     */

    @Override
    public Map invoiceIssuance(InvoiceRequest invoiceRequest) throws JsonProcessingException {
        logger.info("收到开票请求参数：参数{}",invoiceRequest);
        // 1. 组装正票申请的业务报文（content）
        JSONObject content = new JSONObject();
        // 必选参数
        String djbh=redisIdGenerator.generateUniqueId("BWKP");
        content.put("djbh", djbh); // 全局唯一单据编号
        content.put("kpzddm", invoiceConfig.getKpZddm());      // 开票终端代码
        content.put("fplxdm", "01");                           // 发票类型：01=专票，02=普票
        content.put("kplx", "0");                              // 开票类型：0=蓝字发票
        content.put("zsfs", "0");                              // 征收方式：0=普通征税
        content.put("khmc", invoiceRequest.getKhmc());         // 购货单位名称
        content.put("hsje", invoiceRequest.getHsje());                           // 含税金额（价税合计）
        content.put("gsdm", "3204");                           // 公司代码
        content.put("yhdm", "393e8941f3f1409e8cbc7fc981ca1774"); // 用户代码
        content.put("sjlx", "1"); // 数据类型（批发系统，由平台提供）
        content.put("sfwzzfp", "N"); // 非纸质发票（默认N）
        content.put("hsbz", "1"); // 含税标志（1=含税，默认）
        //可选参数
        content.put("khsh", invoiceRequest.getKhsh()); // 购货单位税号（专票必填）
        content.put("khdzdh", invoiceRequest.getKhdzdh()); // 购货单位地址电话
        content.put("khyhzh", invoiceRequest.getKhyhzh()); // 购货单位银行账号
        content.put("gmfMobile", invoiceRequest.getGmfMobile()); // 电子发票手机号
        content.put("gmfEmail", invoiceRequest.getGmfEmail()); // 电子发票邮箱
        content.put("bz", invoiceRequest.getBz()); // 备注
        // 商品明细（mxxx，必选）
        JSONObject goodsItem = new JSONObject();
        goodsItem.put("djhh", "1"); // 单据行号
        goodsItem.put("fphxz", "0"); // 发票行性质：0=正常行
        goodsItem.put("spmc", "*经纪代理服务*物流辅助服务代理服务费"); // 商品名称
        goodsItem.put("jldw", "月"); //计量单位
        goodsItem.put("spsl", 1.00); // 商品数量
        goodsItem.put("ssbm", "3040802010100000000"); // 19位税收编码
        goodsItem.put("hsdj", invoiceRequest.getHsje()); // 含税单价
        goodsItem.put("hsje", invoiceRequest.getHsje()); // 商品含税金额
        BigDecimal[] result =TaxAmountCalculator.calculateFromTaxIncluded(invoiceRequest.getHsje(), BigDecimal.valueOf(0.06));
        goodsItem.put("tax", 0.06); // 税率6%
        goodsItem.put("se", result[1]); // 商品税额
        content.put("mxxx", new JSONObject[]{goodsItem});
        logger.info("开票参数组装完成  参数{}",content);
        String contentBase64 = Base64Util.encode(content.toJSONString());
        // 3. 构建签名参数，生成签名值
        Map<String, String> signParams = new HashMap<>();
        signParams.put("appid", invoiceConfig.getAppId());
        signParams.put("serviceid", invoiceConfig.getServiceId());
        signParams.put("content", contentBase64);
        String signature = SignUtil.sign(invoiceConfig.getSignType(), invoiceConfig.getAppSecret(), signParams);
        // 4. 组装接口请求的公共参数
        JSONObject requestParam = new JSONObject();
        requestParam.put("appid", invoiceConfig.getAppId());
        requestParam.put("serviceid", invoiceConfig.getServiceId());
        requestParam.put("content", contentBase64);
        requestParam.put("signature", signature);
        requestParam.put("signType", invoiceConfig.getSignType());
        String responseJson = HttpUtil.doPostJson(invoiceConfig.getBaseUrl(), requestParam.toJSONString());
        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> invoiceMap = objectMapper.readValue(
                responseJson,
                new TypeReference<Map<String, Object>>() {}
        );

        if("0".equals(invoiceMap.get("code").toString())){
            //这里成功后也要将单据编号进行回传月度报表
            RptFinancialMonthSummary rptFinancialMonthSummary= new RptFinancialMonthSummary();
            rptFinancialMonthSummary.setStatus("3");
            rptFinancialMonthSummary.setBwDjbh(djbh);
            rptFinancialMonthSummary.setSummaryId(invoiceRequest.getSummaryId());
            LocalDate now = LocalDate.now();
            // 定义格式：yyyy-MM-dd
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
            // 转成字符串
            String dateStr = now.format(formatter);
            rptFinancialMonthSummary.setKprq(dateStr);
            rptFinancialMonthSummaryService.updateRptFinancialMonthSummary(rptFinancialMonthSummary);
        }

        return invoiceMap;
    }



    /**
     * 电子发票正票擦汗寻
     * @param InvoiceRequest 开票相入参
     * @return 运单明细
     */

    @Override
    public void updateInvoice() throws JsonProcessingException {

        //查询所有未开票的
        List<Map<String,Object>> invoiceList= jdbcTemplate.queryForList("SELECT bw_djbh FROM `rpt_financial_month_summary` where bw_djbh is  not null  and  bw_dzfp_pdf_url  is null");
        for(int i=0;i<invoiceList.size();i++){
            // 1.组装查询的报文
            JSONObject content = new JSONObject();
            String djbh=invoiceList.get(i).get("bw_djbh").toString();
            content.put("djbh",djbh);
            String contentBase64 = Base64Util.encode(content.toJSONString());
            // 3. 构建签名参数，生成签名值
            Map<String, String> signParams = new HashMap<>();
            signParams.put("appid", invoiceConfig.getAppId());
            signParams.put("serviceid", invoiceConfig.getServiceSelect());
            signParams.put("content", contentBase64);
            String signature = SignUtil.sign("3", invoiceConfig.getAppSecret(), signParams);

            JSONObject requestParam = new JSONObject();
            requestParam.put("appid", invoiceConfig.getAppId());
            requestParam.put("serviceid", invoiceConfig.getServiceSelect());
            requestParam.put("content", contentBase64);
            requestParam.put("signature", signature);
            requestParam.put("signType","3");
            String responseJson = HttpUtil.doPostJson(invoiceConfig.getBaseUrl(), requestParam.toJSONString());
            ObjectMapper objectMapper = new ObjectMapper();
            Map<String, Object> invoiceMap = objectMapper.readValue(
                    responseJson,
                    new TypeReference<Map<String, Object>>() {}
            );
            Map<String, Object> dataMap= new HashMap<>();
            if(StringUtils.isNotBlank(invoiceMap.get("data").toString())){
                dataMap = objectMapper.readValue(
                        Base64Util.decode(invoiceMap.get("data").toString()),
                        new TypeReference<Map<String, Object>>() {}
                );

            }
            //这里  需要将查询到的信息进行回写月度报表里面
            if("0".equals(invoiceMap.get("code").toString())){
                RptFinancialMonthSummary rptFinancialMonthSummary= new RptFinancialMonthSummary();
                rptFinancialMonthSummary.setBwDjbh(djbh);
                rptFinancialMonthSummary.setBwDzfpPdfUrl(dataMap.get("ofd").toString());
                rptFinancialMonthSummary.setBwDzfpOfdUrl(dataMap.get("pdf").toString());
                rptFinancialMonthSummary.setBwDzfpXmlUrl(dataMap.get("xml").toString());
                rptFinancialMonthSummaryService.updateRptFinancialMonthSummaryByInvoice(rptFinancialMonthSummary);
            }
        }

    }

    @Override
    public Map returnShop( InvoiceRequest invoiceRequest) throws JsonProcessingException {
        //找到月度账单中已开票的单据
        List<Map<String,Object>> invoiceList= jdbcTemplate.queryForList(" SELECT summary_id,payable_amount ,bw_djbh,kprq,dept_name,invoice_name,dept_code,leader FROM rpt_financial_month_summary a left join  sys_dept b  on  a.dept_id=b.dept_id where  a.summary_id=?  ",invoiceRequest.getSummaryId());
        if(invoiceList.size()==0){
            return null;
        }
        Map map=invoiceList.get(0);
        String url = invoiceConfig.getShopUrl();
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);
        BigDecimal free= new BigDecimal(map.get("payable_amount").toString());
        OrderRequest request = new OrderRequest();
        request.setOrderNumber(map.get("bw_djbh").toString());
        request.setSkuId("787");
        request.setGzTime(map.get("kprq").toString());
        request.setOutCode("3204");
        request.setUserId(map.get("leader").toString());
        request.setUserCompanyName(map.get("invoice_name").toString());
        request.setSapCode(map.get("dept_code").toString());
        request.setShopName(map.get("dept_name").toString());
        request.setPayType(1);
        request.setProdName("快递服务");
        request.setProdCount("1");
        request.setBuyMoney(free);   //销售金额  含税
        request.setBuyPrice(free);  //采购单价  含税
        request.setSaleMoney(free); // 销售金额  含税
        request.setPurchaseRate(BigDecimal.valueOf(0.06));    //进项税率
        request.setPrice(free);       //销售单价    含税
        BigDecimal[] result =TaxAmountCalculator.calculateFromTaxIncluded(free, BigDecimal.valueOf(0.06));
        request.setBuyMoneyNoTax(result[0]);   // 采购金额（不含税）
        request.setJxse(result[1]);           //进项税额
        BigDecimal[] result1 =TaxAmountCalculator.calculateFromTaxIncluded(free, BigDecimal.valueOf(0.06));
        request.setOutputRate(BigDecimal.valueOf(0.06));      // 销项税率
        request.setXxse(result1[1]);            //销项税额
        HttpEntity<OrderRequest> entity = new HttpEntity<>(request, headers);
        // ✅ postForEntity
        ResponseEntity<String> response = restTemplate.postForEntity(url, entity, String.class);


        ObjectMapper objectMapper = new ObjectMapper();
        Map<String, Object> shopMap = objectMapper.readValue(
                response.getBody(),
                new TypeReference<Map<String, Object>>() {}
        );
        if("0".equals(shopMap.get("code").toString())){
            //这里成功后也要将单据编号进行回传月度报表
            RptFinancialMonthSummary rptFinancialMonthSummary= new RptFinancialMonthSummary();
            rptFinancialMonthSummary.setStatus("4");
            rptFinancialMonthSummary.setSummaryId(invoiceRequest.getSummaryId());
            rptFinancialMonthSummaryService.updateRptFinancialMonthSummary(rptFinancialMonthSummary);
        }
        return shopMap;
    }



}
