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

class OfferStatus(str, Enum):
    PENDING = "Pending"
    ACCEPTED = "Accepted"
    REJECTED = "Rejected"
    CANCELLED = "Cancelled"
    EXPIRED = "Expired"

class OfferBase(BaseModel):
    listing_id: str = Field(..., min_length=36, max_length=36)
    buyer_id: str = Field(..., min_length=36, max_length=36)
    offer_amount: Decimal = Field(..., gt=0)
    message: Optional[str] = None
    status: str
    expires_at: datetime
    responded_at: Optional[datetime] = None
    response_message: Optional[str] = None

    @field_validator("offer_amount")
    @classmethod
    def validate_offer_amount(cls, v):
        if v <= 0:
            raise ValueError("Offer amount must be positive")
        return v

class OfferCreate(BaseModel):
    listing_id: str = Field(..., min_length=36, max_length=36)
    buyer_id: str = Field(..., min_length=36, max_length=36)
    offer_amount: Decimal = Field(..., gt=0)
    message: Optional[str] = None
    expires_at: datetime

    @field_validator("offer_amount")
    @classmethod
    def validate_offer_amount(cls, v):
        if v <= 0:
            raise ValueError("Offer amount must be positive")
        return v

class OfferUpdate(BaseModel):
    listing_id: Optional[str] = Field(None, min_length=36, max_length=36)
    buyer_id: Optional[str] = Field(None, min_length=36, max_length=36)
    offer_amount: Optional[Decimal] = Field(None, gt=0)
    message: Optional[str] = None
    status: Optional[str] = None
    expires_at: Optional[datetime] = None
    responded_at: Optional[datetime] = None
    response_message: Optional[str] = None

    @field_validator("offer_amount")
    @classmethod
    def validate_offer_amount(cls, v):
        if v is not None and v <= 0:
            raise ValueError("Offer amount must be positive")
        return v

class OfferResponse(BaseModel):
    model_config = ConfigDict(from_attributes=True)

    id: str
    listing_id: str
    buyer_id: str
    offer_amount: Decimal
    message: Optional[str]
    status: str
    expires_at: datetime
    responded_at: Optional[datetime]
    response_message: Optional[str]
    created_at: datetime
    updated_at: datetime