from __future__ import annotations

from decimal import Decimal
from typing import Annotated
from uuid import UUID

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

# ---------------------------------------------------------------------------
# Type aliases with DB-aligned length constraints
# ---------------------------------------------------------------------------

# phone col is VARCHAR(50) in DB
_Phone = Annotated[str, Field(min_length=1, max_length=50)]
# office / hours / email cols are VARCHAR(255)
_Text255 = Annotated[str, Field(min_length=1, max_length=255)]
# linkedin / twitter cols are VARCHAR(500)
_Url500 = Annotated[str, Field(min_length=1, max_length=500)]

# Each feature item must fit in a reasonable display label
_FeatureItem = Annotated[str, Field(min_length=1, max_length=200)]

# Price guard: positive and capped at a sane maximum (Numeric(10,2) = up to
# 99,999,999.99 in DB, but no plan should realistically exceed $99,999/mo)
_PriceCad = Annotated[Decimal, Field(gt=Decimal("0"), le=Decimal("99999.99"))]


class PlanResponse(BaseModel):
    id: UUID
    slug: str
    display_name: str
    price_cad: Decimal
    features: list[str]
    is_popular: bool
    sort_order: int

    model_config = ConfigDict(from_attributes=True)


class UpdatePlanRequest(BaseModel):
    price_cad: _PriceCad
    # Cap the list at 50 items to prevent oversized JSONB payloads
    features: Annotated[list[_FeatureItem], Field(min_length=1, max_length=50)]

    @field_validator("features")
    @classmethod
    def features_not_empty(cls, v: list[str]) -> list[str]:
        v = [f.strip() for f in v]
        if not v:
            raise ValueError("At least one feature is required")
        if any(not f for f in v):
            raise ValueError("Feature strings cannot be empty")
        return v


class UpdateSettingsRequest(BaseModel):
    email: Annotated[EmailStr, Field(max_length=255)]
    phone: _Phone
    office: _Text255
    hours: _Text255
    linkedin: _Url500
    twitter: _Url500

    @field_validator("phone", "office", "hours")
    @classmethod
    def required_fields(cls, v: str) -> str:
        if not v.strip():
            raise ValueError("This field is required")
        return v

    @field_validator("linkedin", "twitter")
    @classmethod
    def https_url(cls, v: str) -> str:
        v = v.strip()
        if not v:
            raise ValueError("This field is required")
        if not v.startswith("https://"):
            raise ValueError("URL must start with https://")
        return v
