from pydantic import BaseModel, Field, field_validator, ConfigDict
from typing import Optional
from datetime import date, datetime


# Gradingservice schemas
class GradingserviceBase(BaseModel):
    name: str = Field(..., min_length=1, max_length=255)
    abbreviation: str = Field(..., min_length=1, max_length=50)
    website_url: Optional[str] = Field(None, max_length=500)
    description: Optional[str] = Field(None, max_length=1000)

    @field_validator("name", "abbreviation")
    @classmethod
    def validate_not_empty(cls, v: str) -> str:
        if not v or not v.strip():
            raise ValueError("Field cannot be empty or whitespace")
        return v.strip()

    @field_validator("website_url")
    @classmethod
    def validate_url(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and v.strip():
            v = v.strip()
            if not (v.startswith("http://") or v.startswith("https://")):
                raise ValueError("URL must start with http:// or https://")
            return v
        return None


class GradingserviceCreate(GradingserviceBase):
    pass


class GradingserviceUpdate(BaseModel):
    name: Optional[str] = Field(None, min_length=1, max_length=255)
    abbreviation: Optional[str] = Field(None, min_length=1, max_length=50)
    website_url: Optional[str] = Field(None, max_length=500)
    description: Optional[str] = Field(None, max_length=1000)

    @field_validator("name", "abbreviation")
    @classmethod
    def validate_not_empty(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v or not v.strip():
                raise ValueError("Field cannot be empty or whitespace")
            return v.strip()
        return None

    @field_validator("website_url")
    @classmethod
    def validate_url(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and v.strip():
            v = v.strip()
            if not (v.startswith("http://") or v.startswith("https://")):
                raise ValueError("URL must start with http:// or https://")
            return v
        return None


class GradingserviceResponse(GradingserviceBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


# Gradedcard schemas
class GradedcardBase(BaseModel):
    listing_id: str = Field(..., min_length=36, max_length=36)
    grading_service_id: str = Field(..., min_length=36, max_length=36)
    grade: str = Field(..., min_length=1, max_length=50)
    certification_number: Optional[str] = Field(None, max_length=255)
    grading_date: Optional[date] = None
    population_count: Optional[int] = Field(None, ge=0)

    @field_validator("grade")
    @classmethod
    def validate_grade(cls, v: str) -> str:
        if not v or not v.strip():
            raise ValueError("Grade cannot be empty or whitespace")
        return v.strip()

    @field_validator("certification_number")
    @classmethod
    def validate_certification_number(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and v.strip():
            return v.strip()
        return None

    @field_validator("grading_date")
    @classmethod
    def validate_grading_date(cls, v: Optional[date]) -> Optional[date]:
        if v is not None:
            if v > date.today():
                raise ValueError("Grading date cannot be in the future")
        return v


class GradedcardCreate(GradedcardBase):
    pass


class GradedcardUpdate(BaseModel):
    listing_id: Optional[str] = Field(None, min_length=36, max_length=36)
    grading_service_id: Optional[str] = Field(None, min_length=36, max_length=36)
    grade: Optional[str] = Field(None, min_length=1, max_length=50)
    certification_number: Optional[str] = Field(None, max_length=255)
    grading_date: Optional[date] = None
    population_count: Optional[int] = Field(None, ge=0)

    @field_validator("grade")
    @classmethod
    def validate_grade(cls, v: Optional[str]) -> Optional[str]:
        if v is not None:
            if not v or not v.strip():
                raise ValueError("Grade cannot be empty or whitespace")
            return v.strip()
        return None

    @field_validator("certification_number")
    @classmethod
    def validate_certification_number(cls, v: Optional[str]) -> Optional[str]:
        if v is not None and v.strip():
            return v.strip()
        return None

    @field_validator("grading_date")
    @classmethod
    def validate_grading_date(cls, v: Optional[date]) -> Optional[date]:
        if v is not None:
            if v > date.today():
                raise ValueError("Grading date cannot be in the future")
        return v
        return None


class GradedcardResponse(GradedcardBase):
    id: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


# Detail response schemas
class GradedcardDetailResponse(BaseModel):
    id: str
    listing_id: str
    grading_service_id: str
    grade: str
    certification_number: Optional[str]
    grading_date: Optional[date]
    population_count: Optional[int]
    created_at: datetime
    updated_at: datetime
    grading_service: GradingserviceResponse

    model_config = ConfigDict(from_attributes=True)