from datetime import datetime
from typing import Optional, List
from uuid import UUID
from pydantic import BaseModel, Field, ConfigDict, computed_field, field_validator


class VendorSimple(BaseModel):
    """Simple vendor schema for nested responses."""
    id: UUID
    name: str
    brand_name: str
    email: str
    website_url: Optional[str] = None
    is_active: bool

    model_config = ConfigDict(from_attributes=True)


class ViolationBase(BaseModel):
    product_name: str = Field(..., min_length=1)
    msp: float = Field(..., gt=0)
    scraped_price: float = Field(..., gt=0)
    url: str = Field(..., min_length=1)
    violation_date: datetime
    vendor_id: Optional[UUID] = None
    vendor_name: Optional[str] = None
    marketplace: Optional[str] = None
    barcode_number: Optional[str] = None
    reference_id: Optional[str] = None
    source_type: str = Field(default="registered")


class ViolationCreate(ViolationBase):
    pass


class ViolationUpdate(BaseModel):
    product_name: Optional[str] = Field(None, min_length=1)
    msp: Optional[float] = Field(None, gt=0)
    scraped_price: Optional[float] = Field(None, gt=0)
    url: Optional[str] = None
    violation_date: Optional[datetime] = None
    vendor_name: Optional[str] = None
    marketplace: Optional[str] = None
    barcode_number: Optional[str] = None
    reference_id: Optional[str] = None


class ViolationResponse(BaseModel):
    """Base violation response with all required fields."""
    id: UUID
    product_name: str
    msp: float
    scraped_price: float
    url: str
    violation_date: datetime
    vendor_id: Optional[UUID] = None
    vendor_name: Optional[str] = None
    marketplace: Optional[str] = None
    barcode_number: Optional[str] = None
    reference_id: Optional[str] = None
    source_type: str
    price_difference: Optional[float] = None
    percentage_difference: Optional[float] = None
    confirmation_count: int = 1
    last_confirmed_date: Optional[datetime] = None
    notification_sent_at: Optional[datetime] = None
    created_at: datetime
    updated_at: datetime
    vendor: Optional[VendorSimple] = None
    
    @field_validator('vendor_name', mode='after')
    @classmethod
    def populate_vendor_name(cls, v, info):
        """For registered violations, get vendor_name from vendor relationship if available."""
        # If vendor_name is already set (from discovered/SERP violations), use it
        if v:
            return v
        # For registered violations, try to get vendor name from the vendor relationship
        if info.data.get('vendor') and info.data.get('vendor_id'):
            return info.data['vendor'].name
        return v
    
    @computed_field
    @property
    def status(self) -> str:
        """Return status based on notification_sent_at field."""
        return "notified" if self.notification_sent_at else "open"

    model_config = ConfigDict(from_attributes=True)


class ViolationListResponse(BaseModel):
    items: List[ViolationResponse]
    total: int
    page: int
    limit: int
