from abc import ABC, abstractmethod
from typing import Optional

from pydantic import BaseModel


class PaymentOrder(BaseModel):
    order_id: str
    pay_url: str
    amount: float
    currency: str = "CNY"
    status: str = "pending"


class PaymentCallback(BaseModel):
    order_id: str
    payment_id: str
    amount: float
    status: str
    raw_data: dict = {}


class PaymentGateway(ABC):
    @abstractmethod
    async def create_order(
        self, order_id: str, amount: float, description: str, user_id: str, plan: str
    ) -> PaymentOrder:
        pass

    @abstractmethod
    async def verify_callback(self, request_data: dict) -> PaymentCallback:
        pass

    @abstractmethod
    async def query_order(self, order_id: str) -> PaymentOrder:
        pass

    @abstractmethod
    async def refund(self, order_id: str, amount: float, reason: str = "") -> bool:
        pass
