package com.example.demo.service;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePrecreateModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePrecreateRequest;
import com.alipay.api.response.AlipayTradePrecreateResponse;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.PaymentStatus;
import com.example.demo.repository.PaymentRepository;

@Service
public class AlipayService {
    
    private static final Logger logger = LoggerFactory.getLogger(AlipayService.class);
    
    private final PaymentRepository paymentRepository;
    
    @Value("${alipay.app-id}")
    private String appId;
    
    @Value("${alipay.private-key}")
    private String privateKey;
    
    @Value("${alipay.public-key}")
    private String publicKey;
    
    @Value("${alipay.gateway-url}")
    private String gatewayUrl;
    
    @Value("${alipay.charset}")
    private String charset;
    
    @Value("${alipay.sign-type}")
    private String signType;
    
    @Value("${alipay.notify-url}")
    private String notifyUrl;
    
    @Value("${alipay.return-url}")
    private String returnUrl;
    
    public AlipayService(PaymentRepository paymentRepository) {
        this.paymentRepository = paymentRepository;
    }
    
    /**
     * 创建支付宝支付订单并生成二维码
     */
    public Map<String, Object> createPayment(Payment payment) {
        try {
            logger.info("开始创建支付宝支付订单，订单号：{}，金额：{}", payment.getOrderId(), payment.getAmount());
            
            // 设置支付状态
            payment.setStatus(PaymentStatus.PENDING);
            payment.setPaymentMethod(PaymentMethod.ALIPAY);
            if (payment.getOrderId() == null || payment.getOrderId().isEmpty()) {
                payment.setOrderId(generateOrderId());
            }
            payment.setCallbackUrl(notifyUrl);
            payment.setReturnUrl(returnUrl);
            
            // 保存支付记录
            paymentRepository.save(payment);
            logger.info("支付记录已保存，ID：{}", payment.getId());
            
            // 调用真实的支付宝API
            return callRealAlipayAPI(payment);
            
        } catch (Exception e) {
            logger.error("创建支付订单时发生异常，订单号：{}，错误：{}", payment.getOrderId(), e.getMessage(), e);
            payment.setStatus(PaymentStatus.FAILED);
            paymentRepository.save(payment);
            throw new RuntimeException("支付服务异常：" + e.getMessage());
        }
    }
    
    /**
     * 调用真实的支付宝API
     */
    private Map<String, Object> callRealAlipayAPI(Payment payment) throws Exception {
        // 创建支付宝客户端，增加超时时间
        AlipayClient alipayClient = new DefaultAlipayClient(
            gatewayUrl, appId, privateKey, "json", charset, publicKey, signType);
        
        // 设置连接和读取超时时间（30秒）
        System.setProperty("sun.net.client.defaultConnectTimeout", "30000");
        System.setProperty("sun.net.client.defaultReadTimeout", "30000");
        
        // 使用预创建API生成二维码
        AlipayTradePrecreateRequest request = new AlipayTradePrecreateRequest();
        request.setNotifyUrl(notifyUrl);
        
        // 设置业务参数
        AlipayTradePrecreateModel model = new AlipayTradePrecreateModel();
        model.setOutTradeNo(payment.getOrderId());
        model.setTotalAmount(payment.getAmount().toString());
        model.setSubject(payment.getDescription() != null ? payment.getDescription() : "AIGC会员订阅");
        model.setBody(payment.getDescription() != null ? payment.getDescription() : "AIGC平台会员订阅服务");
        
        request.setBizModel(model);
        
        logger.info("调用支付宝预创建API，订单号：{}，金额：{}，商品名称：{}", 
            model.getOutTradeNo(), model.getTotalAmount(), model.getSubject());
        
        // 调用API，增加重试机制
        AlipayTradePrecreateResponse response = null;
        int maxRetries = 3;
        int retryCount = 0;
        
        while (retryCount < maxRetries) {
            try {
                logger.info("正在调用支付宝API... (第{}次尝试)", retryCount + 1);
                response = alipayClient.execute(request);
                break; // 成功则跳出循环
            } catch (Exception e) {
                retryCount++;
                logger.warn("支付宝API调用失败，第{}次重试，错误：{}", retryCount, e.getMessage());
                if (retryCount >= maxRetries) {
                    logger.error("支付宝API调用失败，已达到最大重试次数");
                    throw new RuntimeException("支付宝API调用失败：" + e.getMessage());
                }
                try {
                    Thread.sleep(2000); // 等待2秒后重试
                } catch (InterruptedException ie) {
                    Thread.currentThread().interrupt();
                    throw new RuntimeException("重试被中断", ie);
                }
            }
        }
        
        logger.info("支付宝API响应状态：{}", response.isSuccess());
        logger.info("支付宝API响应码：{}", response.getCode());
        logger.info("支付宝API响应消息：{}", response.getMsg());
        logger.info("支付宝API响应子码：{}", response.getSubCode());
        logger.info("支付宝API响应子消息：{}", response.getSubMsg());
        
        if (response.isSuccess()) {
            String qrCode = response.getQrCode();
            logger.info("支付宝二维码生成成功，订单号：{}，二维码：{}", payment.getOrderId(), qrCode);
            
            Map<String, Object> result = new HashMap<>();
            result.put("qrCode", qrCode);
            result.put("outTradeNo", response.getOutTradeNo());
            result.put("success", true);
            
            return result;
        } else {
            logger.error("支付宝二维码生成失败，订单号：{}，错误信息：{}，子码：{}，子消息：{}", 
                payment.getOrderId(), response.getMsg(), response.getSubCode(), response.getSubMsg());
            payment.setStatus(PaymentStatus.FAILED);
            paymentRepository.save(payment);
            throw new RuntimeException("二维码生成失败：" + response.getMsg() + " - " + response.getSubMsg());
        }
    }
    
    
    
    /**
     * 处理支付宝异步通知
     */
    public boolean handleNotify(Map<String, String> params) {
        try {
            // 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                params, publicKey, charset, signType);
            
            if (!signVerified) {
                logger.warn("支付宝异步通知签名验证失败");
                return false;
            }
            
            String tradeStatus = params.get("trade_status");
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            
            logger.info("收到支付宝异步通知，订单号：{}，交易状态：{}", outTradeNo, tradeStatus);
            
            // 查找支付记录
            Payment payment = paymentRepository.findByOrderId(outTradeNo)
                .orElseThrow(() -> new RuntimeException("支付记录不存在：" + outTradeNo));
            
            // 更新支付状态
            switch (tradeStatus) {
                case "TRADE_SUCCESS":
                case "TRADE_FINISHED":
                    payment.setStatus(PaymentStatus.SUCCESS);
                    payment.setExternalTransactionId(tradeNo);
                    payment.setPaidAt(LocalDateTime.now());
                    break;
                case "TRADE_CLOSED":
                    payment.setStatus(PaymentStatus.CANCELLED);
                    break;
                default:
                    payment.setStatus(PaymentStatus.PROCESSING);
                    break;
            }
            
            paymentRepository.save(payment);
            logger.info("支付状态更新成功，订单号：{}，状态：{}", outTradeNo, payment.getStatus());
            
            return true;
            
        } catch (Exception e) {
            logger.error("处理支付宝异步通知异常：", e);
            return false;
        }
    }
    
    /**
     * 处理支付宝同步返回
     */
    public boolean handleReturn(Map<String, String> params) {
        try {
            // 验证签名
            boolean signVerified = AlipaySignature.rsaCheckV1(
                params, publicKey, charset, signType);
            
            if (!signVerified) {
                logger.warn("支付宝同步返回签名验证失败");
                return false;
            }
            
            String outTradeNo = params.get("out_trade_no");
            String tradeNo = params.get("trade_no");
            
            logger.info("收到支付宝同步返回，订单号：{}，交易号：{}", outTradeNo, tradeNo);
            
            // 查找支付记录
            Payment payment = paymentRepository.findByOrderId(outTradeNo)
                .orElseThrow(() -> new RuntimeException("支付记录不存在：" + outTradeNo));
            
            // 如果状态还是待支付，更新为处理中
            if (payment.getStatus() == PaymentStatus.PENDING) {
                payment.setStatus(PaymentStatus.PROCESSING);
                payment.setExternalTransactionId(tradeNo);
                paymentRepository.save(payment);
            }
            
            return true;
            
        } catch (Exception e) {
            logger.error("处理支付宝同步返回异常：", e);
            return false;
        }
    }
    
    /**
     * 生成订单号
     */
    private String generateOrderId() {
        return "ALI" + System.currentTimeMillis() + UUID.randomUUID().toString().substring(0, 8).toUpperCase();
    }
}

