from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import Optional
from datetime import datetime
from enum import Enum
from decimal import Decimal

class PaymentMethod(str, Enum):
    CREDIT_CARD = "credit_card"
    DEBIT_CARD = "debit_card"
    UPI = "upi"
    NET_BANKING = "net_banking"
    WALLET = "wallet"

class PaymentStatus(str, Enum):
    PENDING = "pending"
    COMPLETED = "completed"
    FAILED = "failed"
    REFUNDED = "refunded"

class PaymentBase(BaseModel):
    booking_id: str
    user_id: str
    amount: Decimal
    payment_method: PaymentMethod
    payment_gateway_reference: Optional[str] = None
    transaction_datetime: datetime
    status: PaymentStatus

    @field_validator("amount")
    @classmethod
    def validate_amount_positive(cls, v: Decimal) -> Decimal:
        if v <= 0:
            raise ValueError("Payment amount must be positive")
        return v

class PaymentCreate(PaymentBase):
    pass

class PaymentUpdate(BaseModel):
    booking_id: Optional[str] = None
    user_id: Optional[str] = None
    amount: Optional[Decimal] = None
    payment_method: Optional[PaymentMethod] = None
    payment_gateway_reference: Optional[str] = None
    transaction_datetime: Optional[datetime] = None
    status: Optional[PaymentStatus] = None

    @field_validator("amount")
    @classmethod
    def validate_amount_positive(cls, v: Optional[Decimal]) -> Optional[Decimal]:
        if v is not None and v <= 0:
            raise ValueError("Payment amount must be positive")
        return v

class PaymentResponse(PaymentBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)

class PaymentInitiateRequest(BaseModel):
    reservation_id: str
    payment_method: PaymentMethod

class PaymentInitiateResponse(BaseModel):
    payment_id: str
    booking_id: str
    amount: Decimal
    payment_method: PaymentMethod
    payment_gateway_reference: Optional[str] = None
    status: PaymentStatus
    transaction_datetime: datetime

    model_config = ConfigDict(from_attributes=True)

class PaymentWebhookRequest(BaseModel):
    payment_gateway_reference: str
    status: str
    transaction_id: Optional[str] = None
    amount: Optional[Decimal] = None

class PaymentWebhookResponse(BaseModel):
    success: bool
    message: str
    payment_id: Optional[str] = None
    booking_id: Optional[str] = None