from datetime import datetime
from typing import Literal

from pydantic import BaseModel, ConfigDict, EmailStr, Field, HttpUrl, field_validator

CustomerStatus = Literal["lead", "active", "inactive", "blocked", "archived"]
CustomerType = Literal["company", "private", "public_sector", "partner", "supplier"]
AddressType = Literal["billing", "shipping", "primary", "other"]


def normalize_optional_text(value: object) -> str:
    if value is None:
        return ""
    return str(value).strip()


class CustomerAddressBase(BaseModel):
    type: AddressType = "primary"
    street: str = Field(default="", max_length=255)
    postal_code: str = Field(default="", max_length=30)
    city: str = Field(default="", max_length=120)
    state: str = Field(default="", max_length=120)
    country: str = Field(default="Deutschland", max_length=120)
    is_primary: bool = False

    @field_validator("street", "postal_code", "city", "state", "country", mode="before")
    @classmethod
    def normalize_text(cls, value: object) -> str:
        return normalize_optional_text(value)


class CustomerAddressCreate(CustomerAddressBase):
    pass


class CustomerAddressUpdate(CustomerAddressBase):
    pass


class CustomerAddressResponse(CustomerAddressBase):
    id: int
    customer_id: int
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CustomerContactBase(BaseModel):
    first_name: str = Field(default="", max_length=100)
    last_name: str = Field(default="", max_length=100)
    position: str = Field(default="", max_length=120)
    email: EmailStr | None = None
    phone: str = Field(default="", max_length=80)
    mobile: str = Field(default="", max_length=80)
    is_primary: bool = False
    notes: str = ""

    @field_validator("first_name", "last_name", "position", "phone", "mobile", "notes", mode="before")
    @classmethod
    def normalize_text(cls, value: object) -> str:
        return normalize_optional_text(value)


class CustomerContactCreate(CustomerContactBase):
    pass


class CustomerContactUpdate(CustomerContactBase):
    pass


class CustomerContactResponse(CustomerContactBase):
    id: int
    customer_id: int
    email: str
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)


class CustomerBase(BaseModel):
    customer_number: str = Field(min_length=1, max_length=50)
    company_name: str = Field(min_length=1, max_length=255)
    legal_name: str = Field(default="", max_length=255)
    customer_type: CustomerType
    status: CustomerStatus
    industry: str = Field(default="", max_length=120)
    website: HttpUrl | None = None
    email: EmailStr | None = None
    phone: str = Field(default="", max_length=80)
    tax_number: str = Field(default="", max_length=120)
    vat_id: str = Field(default="", max_length=120)
    notes: str = ""

    @field_validator(
        "customer_number",
        "company_name",
        "legal_name",
        "industry",
        "phone",
        "tax_number",
        "vat_id",
        "notes",
        mode="before",
    )
    @classmethod
    def normalize_text(cls, value: object) -> str:
        return normalize_optional_text(value)


class CustomerCreate(CustomerBase):
    addresses: list[CustomerAddressCreate] = Field(default_factory=list)
    contacts: list[CustomerContactCreate] = Field(default_factory=list)


class CustomerUpdate(CustomerBase):
    addresses: list[CustomerAddressUpdate] = Field(default_factory=list)


class CustomerResponse(CustomerBase):
    id: int
    website: str
    email: str
    addresses: list[CustomerAddressResponse]
    contacts: list[CustomerContactResponse]
    created_at: datetime
    updated_at: datetime

    model_config = ConfigDict(from_attributes=True)
