package com.example.demo.service;

import com.example.demo.config.PayPalConfig;
import com.example.demo.model.Payment;
import com.paypal.api.payments.*;
import com.paypal.base.rest.APIContext;
import com.paypal.base.rest.PayPalRESTException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;

/**
 * PayPal支付服务
 * 处理PayPal支付创建、执行和验证
 */
@Service
public class PayPalService {
    
    private static final Logger logger = LoggerFactory.getLogger(PayPalService.class);
    
    @Autowired(required = false)
    private APIContext apiContext;
    
    @Autowired
    private PayPalConfig payPalConfig;
    
    @Autowired
    private UserErrorLogService userErrorLogService;
    
    /**
     * 创建PayPal支付
     * @param payment 支付记录
     * @return 包含支付URL的Map
     */
    public Map<String, Object> createPayment(Payment payment) {
        try {
            if (apiContext == null) {
                throw new RuntimeException("PayPal未配置或配置无效");
            }
            
            logger.info("=== 创建PayPal支付 ===");
            logger.info("订单ID: {}", payment.getOrderId());
            logger.info("原始金额: {} {}", payment.getAmount(), payment.getCurrency());
            
            // 如果是人民币，先转换为美元
            BigDecimal paypalAmount = payment.getAmount();
            String paypalCurrency = payment.getCurrency();
            
            if ("CNY".equalsIgnoreCase(payment.getCurrency())) {
                // 保存原始人民币金额
                payment.setOriginalAmount(payment.getAmount());
                payment.setOriginalCurrency("CNY");
                payment.setExchangeRate(BigDecimal.valueOf(getExchangeRate()));
                
                // 转换为美元
                paypalAmount = convertCNYtoUSD(payment.getAmount());
                paypalCurrency = "USD";
                
                // 保存转换后的金额
                payment.setConvertedAmount(paypalAmount);
                
                logger.info("PayPal支付金额: {} USD (原始: {} CNY, 汇率: {})", 
                    paypalAmount, payment.getAmount(), getExchangeRate());
            }
            
            // 创建支付金额
            Amount amount = new Amount();
            amount.setCurrency(paypalCurrency);
            amount.setTotal(formatAmount(paypalAmount));
            
            // 创建交易
            Transaction transaction = new Transaction();
            transaction.setDescription(payment.getDescription() != null ? 
                payment.getDescription() : "订单支付 - " + payment.getOrderId());
            transaction.setAmount(amount);
            
            // 可选：添加商品详情
            ItemList itemList = new ItemList();
            List<Item> items = new ArrayList<>();
            
            Item item = new Item();
            item.setName(payment.getDescription() != null ? payment.getDescription() : "订单");
            item.setCurrency(paypalCurrency);
            item.setPrice(formatAmount(paypalAmount));
            item.setQuantity("1");
            items.add(item);
            
            itemList.setItems(items);
            transaction.setItemList(itemList);
            
            List<Transaction> transactions = new ArrayList<>();
            transactions.add(transaction);
            
            // 创建支付方式
            Payer payer = new Payer();
            payer.setPaymentMethod("paypal");
            
            // 创建支付对象
            com.paypal.api.payments.Payment paypalPayment = new com.paypal.api.payments.Payment();
            paypalPayment.setIntent("sale");
            paypalPayment.setPayer(payer);
            paypalPayment.setTransactions(transactions);
            
            // 设置重定向URL
            RedirectUrls redirectUrls = new RedirectUrls();
            redirectUrls.setCancelUrl(payPalConfig.getCancelUrl() + "?paymentId=" + payment.getId());
            redirectUrls.setReturnUrl(payPalConfig.getSuccessUrl() + "?paymentId=" + payment.getId());
            paypalPayment.setRedirectUrls(redirectUrls);
            
            // 创建支付
            com.paypal.api.payments.Payment createdPayment = paypalPayment.create(apiContext);
            
            logger.info("✅ PayPal支付创建成功");
            logger.info("PayPal Payment ID: {}", createdPayment.getId());
            logger.info("State: {}", createdPayment.getState());
            
            // 获取批准URL
            String approvalUrl = null;
            for (Links link : createdPayment.getLinks()) {
                if (link.getRel().equals("approval_url")) {
                    approvalUrl = link.getHref();
                    break;
                }
            }
            
            if (approvalUrl == null) {
                throw new RuntimeException("无法获取PayPal批准URL");
            }
            
            logger.info("Approval URL: {}", approvalUrl);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("paymentUrl", approvalUrl);
            result.put("paypalPaymentId", createdPayment.getId());
            result.put("state", createdPayment.getState());
            
            return result;
            
        } catch (PayPalRESTException e) {
            logger.error("❌ 创建PayPal支付失败", e);
            logger.error("错误信息: {}", e.getMessage());
            logger.error("详细错误: {}", e.getDetails());
            logPaymentError(payment.getOrderId(), "创建PayPal支付失败: " + e.getMessage());
            throw new RuntimeException("创建PayPal支付失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("❌ 创建PayPal支付失败", e);
            logPaymentError(payment.getOrderId(), "创建PayPal支付失败: " + e.getMessage());
            throw new RuntimeException("创建PayPal支付失败: " + e.getMessage());
        }
    }
    
    /**
     * 执行PayPal支付
     * @param paymentId PayPal支付ID
     * @param payerId 支付者ID
     * @return 执行结果
     */
    public Map<String, Object> executePayment(String paymentId, String payerId) {
        try {
            if (apiContext == null) {
                throw new RuntimeException("PayPal未配置或配置无效");
            }
            
            logger.info("=== 执行PayPal支付 ===");
            logger.info("Payment ID: {}", paymentId);
            logger.info("Payer ID: {}", payerId);
            
            // 获取支付对象
            com.paypal.api.payments.Payment payment = com.paypal.api.payments.Payment.get(apiContext, paymentId);
            
            // 创建执行对象
            PaymentExecution paymentExecution = new PaymentExecution();
            paymentExecution.setPayerId(payerId);
            
            // 执行支付
            com.paypal.api.payments.Payment executedPayment = payment.execute(apiContext, paymentExecution);
            
            logger.info("✅ PayPal支付执行成功");
            logger.info("State: {}", executedPayment.getState());
            
            // 获取交易ID
            String transactionId = null;
            if (executedPayment.getTransactions() != null && !executedPayment.getTransactions().isEmpty()) {
                Transaction transaction = executedPayment.getTransactions().get(0);
                if (transaction.getRelatedResources() != null && !transaction.getRelatedResources().isEmpty()) {
                    RelatedResources relatedResource = transaction.getRelatedResources().get(0);
                    if (relatedResource.getSale() != null) {
                        transactionId = relatedResource.getSale().getId();
                    }
                }
            }
            
            logger.info("Transaction ID: {}", transactionId);
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("state", executedPayment.getState());
            result.put("paymentId", executedPayment.getId());
            result.put("transactionId", transactionId);
            result.put("success", "approved".equalsIgnoreCase(executedPayment.getState()));
            
            return result;
            
        } catch (PayPalRESTException e) {
            logger.error("❌ 执行PayPal支付失败", e);
            logger.error("错误信息: {}", e.getMessage());
            logger.error("详细错误: {}", e.getDetails());
            throw new RuntimeException("执行PayPal支付失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("❌ 执行PayPal支付失败", e);
            throw new RuntimeException("执行PayPal支付失败: " + e.getMessage());
        }
    }
    
    /**
     * 查询PayPal支付状态
     * @param paymentId PayPal支付ID
     * @return 支付状态
     */
    public Map<String, Object> getPaymentStatus(String paymentId) {
        try {
            if (apiContext == null) {
                throw new RuntimeException("PayPal未配置或配置无效");
            }
            
            logger.info("=== 查询PayPal支付状态 ===");
            logger.info("Payment ID: {}", paymentId);
            
            // 获取支付对象
            com.paypal.api.payments.Payment payment = com.paypal.api.payments.Payment.get(apiContext, paymentId);
            
            logger.info("✅ 查询成功");
            logger.info("State: {}", payment.getState());
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("state", payment.getState());
            result.put("paymentId", payment.getId());
            result.put("createTime", payment.getCreateTime());
            result.put("updateTime", payment.getUpdateTime());
            
            return result;
            
        } catch (PayPalRESTException e) {
            logger.error("❌ 查询PayPal支付状态失败", e);
            logger.error("错误信息: {}", e.getMessage());
            throw new RuntimeException("查询PayPal支付状态失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("❌ 查询PayPal支付状态失败", e);
            throw new RuntimeException("查询PayPal支付状态失败: " + e.getMessage());
        }
    }
    
    /**
     * 转换货币代码
     * PayPal不直接支持CNY，需要转换为USD
     * @param currency 原始货币代码
     * @return PayPal支持的货币代码
     */
    private String convertCurrency(String currency) {
        if ("CNY".equalsIgnoreCase(currency)) {
            logger.info("货币转换: CNY -> USD");
            return "USD";
        }
        return currency;
    }
    
    /**
     * 将人民币金额转换为美元
     * @param cnyAmount 人民币金额
     * @return 美元金额
     */
    public BigDecimal convertCNYtoUSD(BigDecimal cnyAmount) {
        if (cnyAmount == null) {
            return BigDecimal.ZERO;
        }
        double exchangeRate = payPalConfig.getExchangeRate();
        if (exchangeRate <= 0) {
            exchangeRate = 7.2; // 默认汇率
        }
        BigDecimal usdAmount = cnyAmount.divide(
            BigDecimal.valueOf(exchangeRate), 
            2, 
            RoundingMode.HALF_UP
        );
        logger.info("金额转换: ¥{} CNY -> ${} USD (汇率: {})", cnyAmount, usdAmount, exchangeRate);
        return usdAmount;
    }
    
    /**
     * 获取当前汇率
     */
    public double getExchangeRate() {
        double rate = payPalConfig.getExchangeRate();
        return rate > 0 ? rate : 7.2;
    }
    
    /**
     * 格式化金额
     * PayPal要求金额最多2位小数
     * @param amount 原始金额
     * @return 格式化后的金额字符串
     */
    private String formatAmount(BigDecimal amount) {
        if (amount == null) {
            return "0.00";
        }
        
        BigDecimal rounded = amount.setScale(2, RoundingMode.HALF_UP);
        return rounded.toString();
    }
    
    /**
     * 取消PayPal支付（退款）
     * @param saleId 交易ID
     * @return 退款结果
     */
    public Map<String, Object> refundPayment(String saleId) {
        try {
            if (apiContext == null) {
                throw new RuntimeException("PayPal未配置或配置无效");
            }
            
            logger.info("=== 退款PayPal支付 ===");
            logger.info("Sale ID: {}", saleId);
            
            // 获取Sale对象
            Sale sale = Sale.get(apiContext, saleId);
            
            // 创建退款对象
            RefundRequest refundRequest = new RefundRequest();
            
            // 执行退款
            DetailedRefund refund = sale.refund(apiContext, refundRequest);
            
            logger.info("✅ PayPal退款成功");
            logger.info("Refund ID: {}", refund.getId());
            logger.info("State: {}", refund.getState());
            
            // 返回结果
            Map<String, Object> result = new HashMap<>();
            result.put("refundId", refund.getId());
            result.put("state", refund.getState());
            result.put("success", "completed".equalsIgnoreCase(refund.getState()));
            
            return result;
            
        } catch (PayPalRESTException e) {
            logger.error("❌ PayPal退款失败", e);
            logger.error("错误信息: {}", e.getMessage());
            logPaymentError(null, "PayPal退款失败: " + e.getMessage());
            throw new RuntimeException("PayPal退款失败: " + e.getMessage());
        } catch (Exception e) {
            logger.error("❌ PayPal退款失败", e);
            logPaymentError(null, "PayPal退款失败: " + e.getMessage());
            throw new RuntimeException("PayPal退款失败: " + e.getMessage());
        }
    }

    /**
     * 记录支付错误日志
     */
    private void logPaymentError(String orderId, String errorMessage) {
        try {
            userErrorLogService.logErrorAsync(
                null,
                com.example.demo.model.UserErrorLog.ErrorType.PAYMENT_ERROR,
                errorMessage,
                "PayPalService",
                orderId,
                "PAYPAL"
            );
        } catch (Exception e) {
            logger.warn("记录支付错误日志失败: {}", e.getMessage());
        }
    }
}
