from typing import Optional, Annotated
from pydantic import BaseModel, Field, EmailStr, field_validator, ConfigDict, BeforeValidator
from datetime import datetime

StrId = Annotated[str, BeforeValidator(str)]


class InsuranceproviderBase(BaseModel):
    name: str = Field(..., max_length=200)
    contact_person: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = Field(None, max_length=20)
    email: Optional[EmailStr] = Field(None, max_length=100)
    address: Optional[str] = None
    coverage_policy: Optional[str] = None

    @field_validator("name", "contact_person", mode="before")
    @classmethod
    def strip_string_fields(cls, v):
        if v is None:
            return v
        if isinstance(v, str):
            return v.strip()
        return v

    @field_validator("email", mode="before")
    @classmethod
    def normalise_email(cls, v):
        if v is None:
            return v
        if isinstance(v, str):
            return v.strip().lower()
        return v


class InsuranceproviderCreate(InsuranceproviderBase):
    pass


class InsuranceproviderUpdate(BaseModel):
    name: Optional[str] = Field(None, max_length=200)
    contact_person: Optional[str] = Field(None, max_length=100)
    phone: Optional[str] = Field(None, max_length=20)
    email: Optional[EmailStr] = Field(None, max_length=100)
    address: Optional[str] = None
    coverage_policy: Optional[str] = None

    @field_validator("name", "contact_person", mode="before")
    @classmethod
    def strip_string_fields(cls, v):
        if v is None:
            return v
        if isinstance(v, str):
            return v.strip()
        return v

    @field_validator("email", mode="before")
    @classmethod
    def normalise_email(cls, v):
        if v is None:
            return v
        if isinstance(v, str):
            return v.strip().lower()
        return v


class InsuranceproviderResponse(InsuranceproviderBase):
    id: StrId
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class InsuranceproviderListResponse(BaseModel):
    items: list[InsuranceproviderResponse]
    total: int
    limit: int
    offset: int

    model_config = ConfigDict(from_attributes=True)