package com.example.demo.service;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.domain.AlipayTradePagePayModel;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.alipay.api.response.AlipayTradePagePayResponse;
import com.example.demo.model.Payment;
import com.example.demo.model.PaymentMethod;
import com.example.demo.model.PaymentStatus;
import com.example.demo.repository.PaymentRepository;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.UUID;

@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 String createPayment(Payment payment) {
        try {
            // 设置支付状态
            payment.setStatus(PaymentStatus.PENDING);
            payment.setPaymentMethod(PaymentMethod.ALIPAY);
            payment.setOrderId(generateOrderId());
            payment.setCallbackUrl(notifyUrl);
            payment.setReturnUrl(returnUrl);
            
            // 保存支付记录
            paymentRepository.save(payment);
            
            // 创建支付宝客户端
            AlipayClient alipayClient = new DefaultAlipayClient(
                gatewayUrl, appId, privateKey, "json", charset, publicKey, signType);
            
            // 设置请求参数
            AlipayTradePagePayRequest request = new AlipayTradePagePayRequest();
            request.setReturnUrl(returnUrl);
            request.setNotifyUrl(notifyUrl);
            
            // 设置业务参数
            AlipayTradePagePayModel model = new AlipayTradePagePayModel();
            model.setOutTradeNo(payment.getOrderId());
            model.setTotalAmount(payment.getAmount().toString());
            model.setSubject(payment.getDescription() != null ? payment.getDescription() : "商品支付");
            model.setBody(payment.getDescription());
            model.setProductCode("FAST_INSTANT_TRADE_PAY");
            
            request.setBizModel(model);
            
            // 调用API
            AlipayTradePagePayResponse response = alipayClient.pageExecute(request);
            
            if (response.isSuccess()) {
                logger.info("支付宝支付订单创建成功，订单号：{}", payment.getOrderId());
                // 返回支付URL，前端可以跳转到这个URL进行支付
                String paymentUrl = gatewayUrl + "?" + response.getBody();
                return paymentUrl;
            } else {
                logger.error("支付宝支付订单创建失败：{}", response.getMsg());
                payment.setStatus(PaymentStatus.FAILED);
                paymentRepository.save(payment);
                throw new RuntimeException("支付订单创建失败：" + response.getMsg());
            }
            
        } catch (AlipayApiException e) {
            logger.error("支付宝API调用异常：", e);
            payment.setStatus(PaymentStatus.FAILED);
            paymentRepository.save(payment);
            throw new RuntimeException("支付服务异常：" + e.getMessage());
        }
    }
    
    /**
     * 处理支付宝异步通知
     */
    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();
    }
}

