"""
Pydantic schemas for platform.site.site.

These schemas validate JSONFields in Django models.

SST Source:
  - definitions/config/constraints/roles.yaml (auth_modes, brand_colors)
  - definitions/config/constraints/ui_options.yaml (social_platforms, nav_menu_types)
"""

from __future__ import annotations

__all__ = [
    # Navigation
    "NavItemSchema",
    "HeaderNavItemSchema",
    "FooterNavItemSchema",
    "FooterLinkGroupSchema",
    "NavigationSettingsSchema",
    # Auth
    "AuthSettingsSchema",
    # Brand
    "BrandSettingsSchema",
    # Social
    "SocialLinkSchema",
    "SocialDictSettingsSchema",
    # Legal
    "LegalSettingsSchema",
    # Theme
    "ThemeSettingsSchema",
    # Features
    "FeatureSettingsSchema",
    # SEO & Technical
    "SeoSettingsSchema",
    "ContactSettingsSchema",
    "AnalyticsSettingsSchema",
    "OrganizationSchema",
    "StructuredDataSettingsSchema",
    # Landing Page / Marketing
    "HeroSettingsSchema",
    "PhilosophySettingsSchema",
    "AudienceSettingsSchema",
    "VoiceSettingsSchema",
    # Main
    "SiteSettingsSchema",
    "SiteSchema",
]

from typing import Annotated

from pydantic import BaseModel, ConfigDict, Field

from lightwave.schema.pydantic.core.validators import FieldOptions

# =============================================================================
# NAVIGATION SCHEMAS
# =============================================================================


class NavItemSchema(BaseModel):
    """Navigation item for any menu location.

    Full-featured nav item supporting dropdowns, auth visibility, and icons.
    """

    label: str = Field(..., description="Display text")
    href: str = Field(..., description="URL path")
    icon: str | None = Field(default=None, description="Icon name")
    subtitle: str | None = Field(default=None, description="Secondary text (for mega menus)")
    badge: str | None = Field(default=None, description="Badge text (New, Beta, etc.)")
    open_in_new_tab: bool = Field(default=False, description="Open link in new tab")
    requires_auth: bool = Field(default=False, description="Only show when authenticated")
    hide_when_auth: bool = Field(default=False, description="Hide when authenticated (e.g., login link)")
    menu_type: str = Field(default="link", description="Menu type (link, dropdown, mega)")
    children: list["NavItemSchema"] = Field(default_factory=list, description="Nested items for dropdowns")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class HeaderNavItemSchema(BaseModel):
    """Navigation item for header menus.

    Simplified version of NavItemSchema for basic header links.
    """

    label: str = Field(..., description="Display text")
    href: str = Field(..., description="URL path")
    menuType: str | None = Field(default=None, description="Dropdown type (link, dropdown-simple, etc.)")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class FooterNavItemSchema(BaseModel):
    """Navigation item for footer menus."""

    label: str = Field(..., description="Display text")
    href: str = Field(..., description="URL path")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class FooterLinkGroupSchema(BaseModel):
    """Group of links for footer columns."""

    title: str = Field(..., description="Group title (e.g., 'Product', 'Company')")
    links: list[FooterNavItemSchema] = Field(default_factory=list, description="Links in this group")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class NavigationSettingsSchema(BaseModel):
    """Navigation configuration within Site.settings.

    Supports all menu locations needed by the frontend:
    - header: Main site navigation
    - footer: Footer link columns (using footer_groups for columned layout)
    - footer_groups: Footer link groups with titles (columned layout)
    - footer_legal: Legal links (Terms, Privacy, Cookies)
    - footer_social: Social media icons
    - sidebar: App navigation (when authenticated)
    - user_menu: User dropdown (Profile, Settings, Logout)
    """

    header: list[NavItemSchema] = Field(default_factory=list, description="Header navigation items")
    footer: list[NavItemSchema] = Field(default_factory=list, description="Footer navigation items")
    footer_groups: list[FooterLinkGroupSchema] = Field(
        default_factory=list, description="Footer link groups (columned layout)"
    )
    footer_legal: list[FooterNavItemSchema] = Field(default_factory=list, description="Legal links")
    footer_social: list[NavItemSchema] = Field(default_factory=list, description="Social media links")
    sidebar: list[NavItemSchema] = Field(default_factory=list, description="Sidebar navigation (app layout)")
    user_menu: list[NavItemSchema] = Field(default_factory=list, description="User dropdown menu items")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# AUTH SCHEMAS
# =============================================================================


class AuthSettingsSchema(BaseModel):
    """Authentication configuration within Site.settings.

    Validates against: auth_modes from roles.yaml
    """

    mode: Annotated[str, Field(description="Auth mode")] = "subscription"
    showSignup: bool = Field(default=True, description="Show signup option")
    showLogin: bool = Field(default=True, description="Show login option")
    loginUrl: str = Field(default="/login", description="Login page URL")
    signupUrl: str = Field(default="/signup", description="Signup page URL")
    profileUrl: str = Field(default="/profile", description="User profile URL")
    settingsUrl: str = Field(default="/settings", description="User settings URL")
    logoutUrl: str = Field(default="/logout", description="Logout URL")
    dashboardUrl: str = Field(default="/dashboard", description="Dashboard URL")
    social_providers: list[str] = Field(default_factory=list, description="Enabled OAuth providers")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    @classmethod
    def validate_mode(cls, v: str) -> str:
        """Validate mode against SST auth_modes."""
        return FieldOptions.validate("auth_modes", v)


# =============================================================================
# BRAND SCHEMAS
# =============================================================================


class BrandSettingsSchema(BaseModel):
    """Brand configuration within Site.settings.

    Validates against: brand_colors from roles.yaml
    """

    name: str = Field(default="", description="Brand name")
    tagline: str = Field(default="", description="Brand tagline")
    logo_url: str = Field(default="", description="Primary logo URL")
    logo_minimal_url: str = Field(default="", description="Minimal/icon logo URL")
    logo_dark_url: str = Field(default="", description="Dark mode logo URL")
    favicon_url: str = Field(default="", description="Favicon URL")
    apple_touch_icon_url: str = Field(default="", description="Apple touch icon URL")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# SOCIAL SCHEMAS
# =============================================================================


class SocialLinkSchema(BaseModel):
    """Social media link configuration.

    Validates against: social_platforms from ui_options.yaml
    """

    platform: str = Field(..., description="Platform identifier (twitter, linkedin, etc.)")
    href: str = Field(..., description="Profile/page URL")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    @classmethod
    def validate_platform(cls, v: str) -> str:
        """Validate platform against SST social_platforms."""
        return FieldOptions.validate("social_platforms", v)


# =============================================================================
# LEGAL SCHEMAS
# =============================================================================


class LegalSettingsSchema(BaseModel):
    """Legal/compliance configuration within Site.settings."""

    privacyUrl: str = Field(default="/privacy", description="Privacy policy URL")
    termsUrl: str = Field(default="/terms", description="Terms of service URL")
    copyrightText: str = Field(default="", description="Copyright notice text")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# THEME SCHEMAS
# =============================================================================


class ThemeSettingsSchema(BaseModel):
    """Theme configuration within Site.settings.

    Validates against: brand_colors from roles.yaml
    """

    brand_color: str = Field(default="blue", description="Primary brand color")
    dark_mode: bool = Field(default=False, description="Enable dark mode by default")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)

    @classmethod
    def validate_brand_color(cls, v: str) -> str:
        """Validate brand_color against SST brand_colors."""
        return FieldOptions.validate("brand_colors", v)


# =============================================================================
# FEATURES SCHEMAS
# =============================================================================


class FeatureSettingsSchema(BaseModel):
    """Feature flags configuration within Site.settings."""

    use_teams: bool = Field(default=False, description="Enable team functionality")
    use_subscriptions: bool = Field(default=False, description="Enable subscription billing")
    use_chat: bool = Field(default=False, description="Enable AI chat")
    use_shop: bool = Field(default=False, description="Enable e-commerce shop")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# SEO SCHEMAS
# =============================================================================


class SeoSettingsSchema(BaseModel):
    """Site-level SEO configuration within Site.settings."""

    title_template: str = Field(default="%s", description="Page title template (use %s for page title)")
    default_title: str = Field(default="", description="Default page title")
    default_description: str = Field(default="", description="Default meta description")
    default_og_image: str | None = Field(default=None, description="Default Open Graph image URL")
    twitter_handle: str | None = Field(default=None, description="Twitter handle (e.g., @example)")
    facebook_app_id: str | None = Field(default=None, description="Facebook App ID")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# CONTACT SCHEMAS
# =============================================================================


class ContactSettingsSchema(BaseModel):
    """Contact information within Site.settings."""

    email: str | None = Field(default=None, description="General contact email")
    support_email: str | None = Field(default=None, description="Support email")
    phone: str | None = Field(default=None, description="Phone number")
    address: str | None = Field(default=None, description="Physical address")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# ANALYTICS SCHEMAS
# =============================================================================


class AnalyticsSettingsSchema(BaseModel):
    """Analytics and tracking configuration within Site.settings."""

    google_analytics_id: str | None = Field(default=None, description="Google Analytics ID (G-XXXXXXXXXX)")
    google_tag_manager_id: str | None = Field(default=None, description="GTM ID (GTM-XXXXXXX)")
    facebook_pixel_id: str | None = Field(default=None, description="Facebook Pixel ID")
    hotjar_id: str | None = Field(default=None, description="Hotjar Site ID")
    sentry_dsn: str | None = Field(default=None, description="Sentry DSN")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# SOCIAL DICT SCHEMA (alternative to list)
# =============================================================================


class SocialDictSettingsSchema(BaseModel):
    """Social media links as a dictionary within Site.settings.

    Alternative to list[SocialLinkSchema] for simpler access by platform name.
    """

    twitter: str | None = Field(default=None, description="Twitter profile URL")
    linkedin: str | None = Field(default=None, description="LinkedIn profile URL")
    github: str | None = Field(default=None, description="GitHub profile URL")
    youtube: str | None = Field(default=None, description="YouTube channel URL")
    instagram: str | None = Field(default=None, description="Instagram profile URL")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# STRUCTURED DATA SCHEMAS
# =============================================================================


class OrganizationSchema(BaseModel):
    """JSON-LD Organization structured data."""

    type: str = Field(default="Organization", alias="@type", description="Schema.org type")
    name: str = Field(default="", description="Organization name")
    url: str = Field(default="", description="Organization URL")
    logo: str = Field(default="", description="Logo URL")
    sameAs: list[str] = Field(default_factory=list, description="Social profile URLs")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class StructuredDataSettingsSchema(BaseModel):
    """Structured data configuration within Site.settings."""

    organization: OrganizationSchema | None = Field(default=None, description="Organization JSON-LD")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# LANDING PAGE / MARKETING SCHEMAS
# =============================================================================


class HeroSettingsSchema(BaseModel):
    """Hero section configuration for landing pages.

    Field names align with TypeScript BaseHeroProps from hero-registry.tsx.
    Uses camelCase aliases for JSON serialization to match frontend.
    """

    eyebrow: str | None = Field(default=None, description="Small text above headline")
    headline: str | None = Field(default=None, description="Main headline text")
    headline2: str | None = Field(default=None, description="Second line of headline")
    text: str | None = Field(default=None, description="Emphasized/underlined text in headline")
    description: str | None = Field(default=None, description="Description/body text")
    primaryCtaText: str | None = Field(default=None, description="Primary CTA button text")
    primaryCtaHref: str | None = Field(default=None, description="Primary CTA link")
    secondaryCtaText: str | None = Field(default=None, description="Secondary CTA button text")
    secondaryCtaHref: str | None = Field(default=None, description="Secondary CTA link")
    backgroundPatternUrl: str | None = Field(default=None, description="Background pattern image URL")
    heroImageUrl: str | None = Field(default=None, description="Hero image URL")
    heroImageAlt: str | None = Field(default=None, description="Hero image alt text")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class PhilosophySettingsSchema(BaseModel):
    """Product philosophy/values configuration."""

    core_insight: str = Field(default="", description="Core insight that drives the product")
    product_thesis: str = Field(default="", description="Product thesis statement")
    anti_patterns: list[str] = Field(default_factory=list, description="What we explicitly avoid/reject")
    founding_principles: list[str] = Field(default_factory=list, description="References to founding principle IDs")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class AudienceSettingsSchema(BaseModel):
    """Target audience configuration."""

    for_audience: list[str] = Field(
        default_factory=list,
        description="Who this product is FOR",
        alias="for",
    )
    not_for_audience: list[str] = Field(
        default_factory=list,
        description="Who this product is NOT for (repel)",
        alias="not_for",
    )
    pain_points: list[str] = Field(default_factory=list, description="Pain points we address")
    transformation: str = Field(default="", description="The transformation promise")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


class VoiceSettingsSchema(BaseModel):
    """Brand voice configuration for copy."""

    primary: str = Field(default="", description="Primary voice model")
    secondary: str = Field(default="", description="Secondary voice model")
    emotional_target: str = Field(default="", description="Target emotional response")
    tone_attributes: list[str] = Field(default_factory=list, description="Tone attributes (e.g., 'warm', 'direct')")

    model_config = ConfigDict(extra="forbid", populate_by_name=True)


# =============================================================================
# MAIN SCHEMAS
# =============================================================================


class SiteSettingsSchema(BaseModel):
    """Complete Site.settings JSONField schema.

    This is the main schema that validates the entire settings object.
    Supports all fields required by the frontend-backend contract.

    Example:
        site.settings = {
            "brand": {"name": "LightWave", "tagline": "...", "logo_url": "..."},
            "navigation": {"header": [...], "footer": [...], "user_menu": [...]},
            "auth": {"mode": "subscription", "showSignup": True},
            "social": {"twitter": "https://...", "github": "https://..."},
            "legal": {"privacyUrl": "/privacy", "termsUrl": "/terms"},
            "theme": {"brand_color": "blue"},
            "features": {"use_teams": True},
            "seo": {"title_template": "%s | LightWave", "default_description": "..."},
            "contact": {"email": "hello@...", "support_email": "support@..."},
            "analytics": {"google_analytics_id": "G-XXXXXX"},
            "structured_data": {"organization": {...}}
        }
    """

    # Core configuration
    brand: BrandSettingsSchema = Field(default_factory=BrandSettingsSchema, description="Brand configuration")
    navigation: NavigationSettingsSchema = Field(
        default_factory=NavigationSettingsSchema, description="Navigation configuration"
    )
    auth: AuthSettingsSchema = Field(default_factory=AuthSettingsSchema, description="Auth configuration")

    # Social can be either dict (new) or list (legacy) format
    social: SocialDictSettingsSchema | list[SocialLinkSchema] = Field(
        default_factory=SocialDictSettingsSchema, description="Social media links"
    )

    legal: LegalSettingsSchema = Field(default_factory=LegalSettingsSchema, description="Legal configuration")
    theme: ThemeSettingsSchema = Field(default_factory=ThemeSettingsSchema, description="Theme configuration")
    features: FeatureSettingsSchema = Field(default_factory=FeatureSettingsSchema, description="Feature flags")

    # SEO and technical
    seo: SeoSettingsSchema = Field(default_factory=SeoSettingsSchema, description="SEO configuration")
    contact: ContactSettingsSchema = Field(default_factory=ContactSettingsSchema, description="Contact information")
    analytics: AnalyticsSettingsSchema = Field(default_factory=AnalyticsSettingsSchema, description="Analytics config")
    structured_data: StructuredDataSettingsSchema = Field(
        default_factory=StructuredDataSettingsSchema, description="JSON-LD structured data"
    )

    # Landing page / marketing sections
    hero: HeroSettingsSchema = Field(default_factory=HeroSettingsSchema, description="Hero section configuration")
    philosophy: PhilosophySettingsSchema = Field(
        default_factory=PhilosophySettingsSchema, description="Product philosophy"
    )
    audience: AudienceSettingsSchema = Field(default_factory=AudienceSettingsSchema, description="Target audience")
    voice: VoiceSettingsSchema = Field(default_factory=VoiceSettingsSchema, description="Brand voice")

    model_config = ConfigDict(
        extra="forbid",
        populate_by_name=True,
    )


class SiteSchema(BaseModel):
    """Schema for Site model core fields.

    This validates the Site model's non-JSONField properties.
    For settings JSONField, use SiteSettingsSchema.
    """

    domain: str = Field(..., description="Primary domain")
    name: str = Field(..., description="Site display name")
    is_active: bool = Field(default=True, description="Whether site is active")

    model_config = ConfigDict(
        extra="forbid",
        populate_by_name=True,
    )
