package com.jeesharp.business.modules.pay.tlinx.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.jeesharp.business.modules.pay.tlinx.core.TLinx2Config;
import com.jeesharp.business.modules.pay.tlinx.dto.*;
import com.jeesharp.business.modules.pay.tlinx.service.TLinx2PayService;
import com.jeesharp.business.modules.pay.tlinx.utils.TLinx2Util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import java.util.TreeMap;

/**
 * 银行支付核心服务实现
 * 
 * @author wangmeng
 * @since 2026-03-16
 */
@Service
public class TLinx2PayServiceImpl implements TLinx2PayService {
    
    private static final Logger logger = LoggerFactory.getLogger(TLinx2PayServiceImpl.class);
    
    @Override
    public TLinx2PayOrderResponse createOrder(TLinx2PayOrderRequest request) {
        logger.info("银行统一下单请求: {}", request);
        
        try {
            // 初始化参数
            String timestamp = TLinx2Util.getCurrentTimestamp();
            
            // 固定参数
            TreeMap<String, String> postMap = new TreeMap<>();
            postMap.put("open_id", TLinx2Config.OPEN_ID);
            postMap.put("timestamp", timestamp);
            
            // data参数
            TreeMap<String, Object> dataMap = new TreeMap<>();
            dataMap.put("out_no", request.getOutNo());
            dataMap.put("pmt_tag", request.getPmtTag());
            dataMap.put("pmt_name", request.getPmtName());
            dataMap.put("ord_name", request.getOrdName());
            dataMap.put("original_amount", request.getOriginalAmount().toString());
            
            if (request.getDiscountAmount() != null) {
                dataMap.put("discount_amount", request.getDiscountAmount().toString());
            }
            if (request.getIgnoreAmount() != null) {
                dataMap.put("ignore_amount", request.getIgnoreAmount().toString());
            }
            
            dataMap.put("trade_amount", request.getTradeAmount().toString());
            dataMap.put("trade_account", request.getTradeAccount());
            dataMap.put("trade_no", request.getTradeNo());
            dataMap.put("trade_result", request.getTradeResult());
            dataMap.put("remark", request.getRemark());
            
            if (request.getTag() != null && !request.getTag().isEmpty()) {
                dataMap.put("tag", request.getTag());
            }
            if (request.getNotifyUrl() != null && !request.getNotifyUrl().isEmpty()) {
                dataMap.put("notify_url", request.getNotifyUrl());
            }
            if (request.getCurrency() != null && !request.getCurrency().isEmpty()) {
                dataMap.put("currency", request.getCurrency());
            }
            
            // 条码支付特殊参数
            if (request.getAuthCode() != null && !request.getAuthCode().isEmpty()) {
                dataMap.put("auth_code", request.getAuthCode());
            }
            
            // 公众号/服务窗支付特殊参数
            if (request.getJumpUrl() != null && !request.getJumpUrl().isEmpty()) {
                dataMap.put("jump_url", request.getJumpUrl());
            }
            
            // 1. data字段内容进行AES加密
            TLinx2Util.handleEncrypt(dataMap, postMap);
            
            // 2. 请求参数签名
            TLinx2Util.handleSign(postMap);
            
            // 3. 发送请求
            String responseStr = TLinx2Util.handlePost(postMap, TLinx2Config.PAY_ORDER);
            logger.info("银行统一下单响应: {}", responseStr);
            
            // 4. 解析响应
            return parseResponse(responseStr);
            
        } catch (Exception e) {
            logger.error("银行统一下单异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("系统异常: " + e.getMessage());
            return response;
        }
    }

    @Override
    public TLinx2PayOrderResponse queryPayStatus(TLinx2PayStatusRequest request) {
        logger.info("银行查询支付状态请求: {}", request);

        try {
            String timestamp = TLinx2Util.getCurrentTimestamp();

            TreeMap<String, String> postMap = new TreeMap<>();
            postMap.put("open_id", TLinx2Config.OPEN_ID);
            postMap.put("timestamp", timestamp);

            TreeMap<String, String> dataMap = new TreeMap<>();
            if (request.getOutNo() != null && !request.getOutNo().isEmpty()) {
                dataMap.put("out_no", request.getOutNo());
            }
            if (request.getOrdNo() != null && !request.getOrdNo().isEmpty()) {
                dataMap.put("ord_no", request.getOrdNo());
            }
            if (request.getHistorydb() != null && !request.getHistorydb().isEmpty()) {
                dataMap.put("historydb", request.getHistorydb());
            }

            // 加密和签名
            TLinx2Util.handleEncrypt(dataMap, postMap);
            TLinx2Util.handleSign(postMap);

            // 发送请求
            String responseStr = TLinx2Util.handlePost(postMap, TLinx2Config.QUERY_PAY_STATUS);
            logger.info("银行查询支付状态响应: {}", responseStr);

            return parseResponse(responseStr);

        } catch (Exception e) {
            logger.error("银行查询支付状态异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("系统异常: " + e.getMessage());
            return response;
        }
    }

    @Override
    public TLinx2PayOrderResponse refund(TLinx2RefundRequest request) {
        logger.info("银行退款请求: {}", request);

        try {
            String timestamp = TLinx2Util.getCurrentTimestamp();

            TreeMap<String, String> postMap = new TreeMap<>();
            postMap.put("open_id", TLinx2Config.OPEN_ID);
            postMap.put("timestamp", timestamp);

            TreeMap<String, String> dataMap = new TreeMap<>();
            dataMap.put("out_no", request.getOutNo());
            dataMap.put("refund_out_no", request.getRefundOutNo());
            dataMap.put("refund_ord_name", request.getRefundOrdName());
            dataMap.put("refund_amount", request.getRefundAmount().toString());
            dataMap.put("remark", request.getRemark());
            dataMap.put("shop_pass", request.getShopPass());

            // 加密和签名
            TLinx2Util.handleEncrypt(dataMap, postMap);
            TLinx2Util.handleSign(postMap);

            // 发送请求
            String responseStr = TLinx2Util.handlePost(postMap, TLinx2Config.PAY_REFUND);
            logger.info("银行退款响应: {}", responseStr);

            return parseResponse(responseStr);

        } catch (Exception e) {
            logger.error("银行退款异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("系统异常: " + e.getMessage());
            return response;
        }
    }

    @Override
    public TLinx2PayOrderResponse cancelOrder(String outNo) {
        logger.info("银行取消订单请求, outNo: {}", outNo);

        try {
            String timestamp = TLinx2Util.getCurrentTimestamp();

            TreeMap<String, String> postMap = new TreeMap<>();
            postMap.put("open_id", TLinx2Config.OPEN_ID);
            postMap.put("timestamp", timestamp);

            TreeMap<String, String> dataMap = new TreeMap<>();
            dataMap.put("out_no", outNo);

            // 加密和签名
            TLinx2Util.handleEncrypt(dataMap, postMap);
            TLinx2Util.handleSign(postMap);

            // 发送请求
            String responseStr = TLinx2Util.handlePost(postMap, TLinx2Config.PAY_CANCEL);
            logger.info("银行取消订单响应: {}", responseStr);

            return parseResponse(responseStr);

        } catch (Exception e) {
            logger.error("银行取消订单异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("系统异常: " + e.getMessage());
            return response;
        }
    }

    @Override
    public TLinx2PayOrderResponse queryOrderDetail(String outNo) {
        logger.info("银行查询订单详情请求, outNo: {}", outNo);

        try {
            String timestamp = TLinx2Util.getCurrentTimestamp();

            TreeMap<String, String> postMap = new TreeMap<>();
            postMap.put("open_id", TLinx2Config.OPEN_ID);
            postMap.put("timestamp", timestamp);

            TreeMap<String, String> dataMap = new TreeMap<>();
            dataMap.put("out_no", outNo);

            // 加密和签名
            TLinx2Util.handleEncrypt(dataMap, postMap);
            TLinx2Util.handleSign(postMap);

            // 发送请求
            String responseStr = TLinx2Util.handlePost(postMap, TLinx2Config.ORDER_VIEW);
            logger.info("银行查询订单详情响应: {}", responseStr);

            return parseResponse(responseStr);

        } catch (Exception e) {
            logger.error("银行查询订单详情异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("系统异常: " + e.getMessage());
            return response;
        }
    }

    @Override
    public boolean verifyNotifySignature(String notifyData) {
        try {
            JSONObject respObject = JSONObject.parseObject(notifyData);
            return TLinx2Util.verifySign(respObject);
        } catch (Exception e) {
            logger.error("验证回调签名异常", e);
            return false;
        }
    }

    @Override
    public String decryptNotifyData(String encryptedData) {
        try {
            return TLinx2Util.decrypt(encryptedData, TLinx2Config.OPEN_KEY);
        } catch (Exception e) {
            logger.error("解密回调数据异常", e);
            return null;
        }
    }

    /**
     * 解析响应数据
     *
     * @param responseStr 响应字符串
     * @return 解析后的响应对象
     */
    private TLinx2PayOrderResponse parseResponse(String responseStr) {
        try {
            JSONObject respObject = JSONObject.parseObject(responseStr);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();

            response.setErrcode(respObject.getString("errcode"));
            response.setMsg(respObject.getString("msg"));

            Object dataStr = respObject.get("data");
            if (dataStr != null && TLinx2Util.verifySign(respObject)) {
                String respData = TLinx2Util.decrypt(dataStr.toString(), TLinx2Config.OPEN_KEY);
                logger.debug("解密后的响应data内容: {}", respData);

                JSONObject dataObject = JSONObject.parseObject(respData);
                response.setTradeQrcode(dataObject.getString("trade_qrcode"));
                response.setTradeResult(dataObject.getString("trade_result"));
                response.setOrdNo(dataObject.getString("ord_no"));
                response.setOutNo(dataObject.getString("out_no"));
                response.setTradeStatus(dataObject.getString("trade_status"));
                response.setPayTime(dataObject.getString("pay_time"));

                if (dataObject.containsKey("trade_amount")) {
                    response.setTradeAmount(dataObject.getInteger("trade_amount"));
                }
            }

            return response;
        } catch (Exception e) {
            logger.error("解析响应数据异常", e);
            TLinx2PayOrderResponse response = new TLinx2PayOrderResponse();
            response.setErrcode("-1");
            response.setMsg("解析响应数据失败: " + e.getMessage());
            return response;
        }
    }
}