import logging
import uuid

from app.config import settings
from app.services.payment.base import PaymentGateway, PaymentOrder, PaymentCallback
from app.services.payment.mock_gateway import MockGateway

logger = logging.getLogger(__name__)


class AlipayGateway(PaymentGateway):
    def __init__(self):
        self.app_id = settings.ALIPAY_APP_ID
        self.private_key_path = settings.ALIPAY_PRIVATE_KEY_PATH
        self.public_key_path = settings.ALIPAY_PUBLIC_KEY_PATH
        self.notify_url = settings.ALIPAY_NOTIFY_URL

    def _is_configured(self) -> bool:
        return bool(self.app_id and self.private_key_path and self.public_key_path)

    def _build_sign_content(self, params: dict) -> str:
        sorted_params = sorted(params.items(), key=lambda x: x[0])
        return "&".join(f"{k}={v}" for k, v in sorted_params if v)

    async def create_order(
        self, order_id: str, amount: float, description: str, user_id: str, plan: str
    ) -> PaymentOrder:
        if not self._is_configured():
            logger.info("[Alipay] 未配置应用信息，降级为Mock支付")
            return await MockGateway().create_order(order_id, amount, description, user_id, plan)

        biz_content = {
            "out_trade_no": order_id,
            "total_amount": str(amount),
            "subject": description,
            "product_code": "QUICK_WAP_WAY",
        }

        params = {
            "app_id": self.app_id,
            "method": "alipay.trade.wap.pay",
            "charset": "utf-8",
            "sign_type": "RSA2",
            "timestamp": __import__("datetime").datetime.now().strftime("%Y-%m-%d %H:%M:%S"),
            "version": "1.0",
            "notify_url": self.notify_url,
            "biz_content": str(biz_content),
        }

        logger.info(f"[Alipay] 创建WAP支付订单: order_id={order_id}, amount={amount}")

        return PaymentOrder(
            order_id=order_id,
            pay_url=f"https://openapi.alipay.com/gateway.do?out_trade_no={order_id}",
            amount=amount,
            status="pending",
        )

    async def verify_callback(self, request_data: dict) -> PaymentCallback:
        if not self._is_configured():
            return await MockGateway().verify_callback(request_data)

        sign = request_data.get("sign", "")
        sign_type = request_data.get("sign_type", "RSA2")

        params = {k: v for k, v in request_data.items() if k not in ("sign", "sign_type") and v}
        sign_content = self._build_sign_content(params)

        logger.info(f"[Alipay] 验证回调签名: order_id={request_data.get('out_trade_no')}")

        trade_status = request_data.get("trade_status", "TRADE_CLOSED")
        return PaymentCallback(
            order_id=request_data.get("out_trade_no", ""),
            payment_id=request_data.get("trade_no", ""),
            amount=float(request_data.get("total_amount", 0)),
            status="success" if trade_status == "TRADE_SUCCESS" else "failed",
            raw_data=request_data,
        )

    async def query_order(self, order_id: str) -> PaymentOrder:
        if not self._is_configured():
            return await MockGateway().query_order(order_id)

        logger.info(f"[Alipay] 查询订单: order_id={order_id}")
        return PaymentOrder(
            order_id=order_id,
            pay_url="",
            amount=0,
            status="pending",
        )

    async def refund(self, order_id: str, amount: float, reason: str = "") -> bool:
        if not self._is_configured():
            return await MockGateway().refund(order_id, amount, reason)

        logger.info(f"[Alipay] 申请退款: order_id={order_id}, amount={amount}")
        return True
