from datetime import datetime
from decimal import Decimal
from typing import Literal

from pydantic import BaseModel, field_validator


class RechargeCreateRequest(BaseModel):
    amount: Decimal  # 元，前端传入
    payment_plugin: str | None = None

    @field_validator("amount")
    @classmethod
    def validate_amount(cls, v: Decimal) -> Decimal:
        if v <= 0:
            raise ValueError("充值金额必须大于 0")
        # 最多两位小数
        if v.as_tuple().exponent < -2:
            raise ValueError("金额最多保留两位小数")
        return v.quantize(Decimal("0.01"))


class RechargeCreateResponse(BaseModel):
    out_trade_no: str
    amount: Decimal
    payment_plugin: str | None = None
    payment_method: str | None = None
    payment_name: str | None = None
    payurl: str | None = None
    qrcode: str | None = None   # 二维码内容（非 URL，前端需渲染成图片）
    urlscheme: str | None = None
    trade_no: str | None = None


class RechargePendingPayment(BaseModel):
    out_trade_no: str
    amount: Decimal
    payment_plugin: str | None = None
    payment_method: str | None = None
    payment_name: str | None = None
    payurl: str | None = None
    qrcode: str | None = None
    urlscheme: str | None = None
    trade_no: str | None = None
    expires_at: datetime


class RechargeOrderItem(BaseModel):
    id: int
    user_id: int
    out_trade_no: str
    trade_no: str | None
    channel: str
    payment_plugin: str | None = None
    payment_method: str | None = None
    amount: Decimal
    amount_cents: int
    status: str
    remark: str | None
    created_at: datetime
    updated_at: datetime

    model_config = {"from_attributes": True}


class RechargeStatusResponse(BaseModel):
    out_trade_no: str
    status: str          # pending / paid / expired / closed
    paid: bool


class RechargeQueryResult(BaseModel):
    """轮询时返回给前端的简化结果。"""
    out_trade_no: str
    status: Literal["pending", "paid", "expired", "closed", "refunded"]
    paid: bool
    balance: int | None = None   # 支付成功时返回最新余额（分）


class RechargePaymentOption(BaseModel):
    id: str
    name: str
    description: str = ""
    method: str
    method_label: str
    capabilities: list[str] = []
