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.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import com.alipay.api.internal.util.AlipaySignature;
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;
    
    @Autowired
    private LuluPayService luluPayService;
    
    @Autowired(required = false)
    private UserErrorLogService userErrorLogService;
    
    @Value("${alipay.public-key}")
    private String publicKey;
    
    @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, String clientIp) {
        try {
            logger.info("开始创建支付订单（使用噜噜支付），订单号：{}，金额：{}，客户端IP：{}", payment.getOrderId(), payment.getAmount(), clientIp);
            
            // 调用噜噜支付创建支付宝订单
            return luluPayService.createPayment(payment, "alipay", clientIp);
            
        } catch (Exception e) {
            logger.error("创建支付订单时发生异常，订单号：{}，错误：{}", payment.getOrderId(), e.getMessage(), e);
            payment.setStatus(PaymentStatus.FAILED);
            paymentRepository.save(payment);
            
            // 记录支付错误
            try {
                if (userErrorLogService != null) {
                    userErrorLogService.logErrorAsync(
                        null,
                        com.example.demo.model.UserErrorLog.ErrorType.PAYMENT_ERROR,
                        "支付创建失败: " + e.getMessage(),
                        "AlipayService",
                        payment.getOrderId(),
                        "ALIPAY"
                    );
                }
            } catch (Exception logEx) {
                logger.warn("记录支付错误日志失败: {}", logEx.getMessage());
            }
            throw new RuntimeException("支付服务异常：" + e.getMessage());
        }
    }
    
    
    
    /**
     * 处理支付宝异步通知（保留兼容旧的支付宝直连回调）
     * 新的支付会走噜噜支付回调 /api/payments/lulupay/notify
     */
    public boolean handleNotify(Map<String, String> params) {
        try {
            // 尝试验证支付宝签名（兼容旧订单）
            boolean signVerified = false;
            try {
                signVerified = AlipaySignature.rsaCheckV1(
                    params, publicKey, charset, signType);
            } catch (Exception e) {
                logger.warn("支付宝签名验证异常，可能是噜噜支付回调: {}", e.getMessage());
            }
            
            if (!signVerified) {
                logger.warn("支付宝异步通知签名验证失败，尝试作为噜噜支付处理");
                // 可能是噜噜支付的回调，交给LuluPayService处理
                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));
            
            // 更新支付状态（不在这里处理订单和积分，由 AlipayCallbackController 统一处理）
            switch (tradeStatus) {
                case "TRADE_SUCCESS":
                case "TRADE_FINISHED":
                    payment.setStatus(PaymentStatus.SUCCESS);
                    payment.setExternalTransactionId(tradeNo);
                    payment.setPaidAt(LocalDateTime.now());
                    paymentRepository.save(payment);
                    logger.info("支付状态更新为SUCCESS: orderId={}", outTradeNo);
                    break;
                case "TRADE_CLOSED":
                    payment.setStatus(PaymentStatus.CANCELLED);
                    paymentRepository.save(payment);
                    break;
                default:
                    payment.setStatus(PaymentStatus.PROCESSING);
                    paymentRepository.save(payment);
                    break;
            }
            
            logger.info("支付状态更新成功，订单号：{}，状态：{}", outTradeNo, payment.getStatus());
            
            return true;
            
        } catch (Exception e) {
            logger.error("处理支付宝异步通知异常：", e);
            return false;
        }
    }
    
    /**
     * 处理支付宝同步返回
     */
    public boolean handleReturn(Map<String, String> params) {
        try {
            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();
    }
}