"""
Shared UI Component Types - Cross-Component Type Definitions

This module defines Pydantic models for types that are used across multiple
UI components. These types are extracted from the TypeScript source and
provide a single source of truth for shared data structures.

AUTO-GENERATED from TypeScript definitions - regenerate with:
    lw ui update

Source locations:
    - NavItemType: application/app-navigation/config.ts
    - SelectItemType: base/select/select.tsx
    - RadioGroupItemType: base/radio-groups/radio-group-*.tsx
    - CommandMenuGroupType: application/command-menus/command-menu.tsx
    - DateValue: react-aria-components (external)
    - ZonedEvent: application/calendar/calendar.tsx
"""

from typing import Any

from pydantic import BaseModel, ConfigDict, Field

# =============================================================================
# NAVIGATION TYPES
# =============================================================================


class NavSubItemType(BaseModel):
    """Sub-item within a navigation item."""

    label: str = Field(description="Label text for the nav item")
    href: str = Field(description="URL to navigate to")
    icon: str | None = Field(default=None, description="Icon component name")
    badge: str | dict[str, Any] | None = Field(default=None, description="Badge content")

    model_config = ConfigDict(extra="forbid")


class NavItemType(BaseModel):
    """
    Navigation item structure used across sidebar and nav components.

    TypeScript source: application/app-navigation/config.ts
    """

    label: str = Field(description="Label text for the nav item")
    href: str | None = Field(default=None, description="URL to navigate to when clicked")
    icon: str | None = Field(default=None, description="Icon component name")
    badge: str | dict[str, Any] | None = Field(default=None, description="Badge content")
    items: list[NavSubItemType] | None = Field(default=None, description="List of sub-items to display")
    divider: bool | None = Field(default=None, description="Whether this is a divider")

    model_config = ConfigDict(extra="forbid")


class NavItemDividerType(BaseModel):
    """
    Navigation divider for visual separation in nav lists.

    TypeScript source: application/app-navigation/config.ts
    """

    divider: bool = Field(default=True, description="Always true for divider type")

    model_config = ConfigDict(extra="forbid")


class HeaderNavItem(BaseModel):
    """Header navigation item (extends NavItemType pattern)."""

    label: str = Field(description="Label text")
    href: str | None = Field(default=None, description="URL to navigate to")
    icon: str | None = Field(default=None, description="Icon component name")
    items: list["HeaderNavItem"] | None = Field(default=None, description="Sub-items")

    model_config = ConfigDict(extra="forbid")


# Alias for compatibility
NavItem = NavItemType


# =============================================================================
# SELECT/DROPDOWN TYPES
# =============================================================================


class SelectItemType(BaseModel):
    """
    Dropdown/select option item structure.

    TypeScript source: base/select/select.tsx
    """

    id: str = Field(description="Unique identifier for the item")
    label: str | None = Field(default=None, description="Display label")
    avatar_url: str | None = Field(default=None, alias="avatarUrl", description="URL for avatar image")
    is_disabled: bool | None = Field(default=None, alias="isDisabled", description="Whether item is disabled")
    supporting_text: str | None = Field(default=None, alias="supportingText", description="Additional helper text")
    icon: str | None = Field(default=None, description="Icon component name")

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


# =============================================================================
# RADIO GROUP TYPES
# =============================================================================


class RadioGroupItemType(BaseModel):
    """
    Radio group option structure.

    TypeScript source: base/radio-groups/radio-group-*.tsx
    """

    value: str = Field(description="Value when selected")
    title: str = Field(description="Display title")
    description: str = Field(description="Description text")
    secondary_title: str = Field(alias="secondaryTitle", description="Secondary title")
    disabled: bool | None = Field(default=None, description="Whether item is disabled")
    icon: str | None = Field(default=None, description="Icon component name")

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


class IconCardItemType(BaseModel):
    """Icon card option for radio groups."""

    value: str = Field(description="Value when selected")
    title: str = Field(description="Display title")
    icon: str = Field(description="Icon component name")
    disabled: bool | None = Field(default=None, description="Whether item is disabled")

    model_config = ConfigDict(extra="forbid")


class PaymentCardItemType(BaseModel):
    """Payment method card option."""

    value: str = Field(description="Value when selected")
    label: str = Field(description="Display label")
    icon: str = Field(description="Payment icon component name")
    disabled: bool | None = Field(default=None, description="Whether item is disabled")

    model_config = ConfigDict(extra="forbid")


class AvatarItemType(BaseModel):
    """Avatar selection option."""

    value: str = Field(description="Value when selected")
    name: str = Field(description="Display name")
    avatar_url: str = Field(alias="avatarUrl", description="Avatar image URL")
    disabled: bool | None = Field(default=None, description="Whether item is disabled")

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


# =============================================================================
# COMMAND MENU TYPES
# =============================================================================


class CommandMenuItemType(BaseModel):
    """Individual item in a command menu."""

    id: str = Field(description="Unique identifier")
    label: str = Field(description="Display label")
    shortcut: str | None = Field(default=None, description="Keyboard shortcut")
    icon: str | None = Field(default=None, description="Icon component name")
    disabled: bool | None = Field(default=None, description="Whether item is disabled")

    model_config = ConfigDict(extra="forbid")


class CommandMenuGroupType(BaseModel):
    """
    Command palette group structure.

    TypeScript source: application/command-menus/command-menu.tsx
    """

    id: str = Field(description="Unique identifier for the group")
    title: str | None = Field(default=None, description="Group title")
    items: list[CommandMenuItemType] = Field(description="Items in this group")

    model_config = ConfigDict(extra="forbid")


# =============================================================================
# CALENDAR/DATE TYPES
# =============================================================================


class DateValue(BaseModel):
    """
    Date/time value representation for calendar components.

    Note: In TypeScript this comes from react-aria-components.
    This is a simplified Pydantic representation.
    """

    year: int = Field(description="Year")
    month: int = Field(description="Month (1-12)")
    day: int = Field(description="Day of month")
    hour: int | None = Field(default=None, description="Hour (0-23)")
    minute: int | None = Field(default=None, description="Minute (0-59)")
    second: int | None = Field(default=None, description="Second (0-59)")
    timezone: str | None = Field(default=None, description="Timezone identifier")

    model_config = ConfigDict(extra="forbid")


class ZonedEvent(BaseModel):
    """
    Calendar event with timezone information.

    TypeScript source: application/calendar/calendar.tsx
    """

    id: str = Field(description="Unique event identifier")
    title: str = Field(description="Event title")
    start: DateValue = Field(description="Start date/time")
    end: DateValue = Field(description="End date/time")
    color: str | None = Field(default=None, description="Event color")
    description: str | None = Field(default=None, description="Event description")

    model_config = ConfigDict(extra="forbid")


# =============================================================================
# MISC TYPES
# =============================================================================


class ItemProps(BaseModel):
    """Generic item props (used by calendar header and similar)."""

    id: str = Field(description="Unique identifier")
    label: str = Field(description="Display label")
    value: str | None = Field(default=None, description="Value")

    model_config = ConfigDict(extra="forbid")


# TypeScript generic placeholder - represents generic type parameter T
# In Pydantic, we use Any as the closest equivalent
T = Any


# =============================================================================
# EXPORTS
# =============================================================================

__all__ = [
    # Navigation
    "NavItemType",
    "NavSubItemType",
    "NavItemDividerType",
    "NavItem",
    "HeaderNavItem",
    # Select
    "SelectItemType",
    # Radio Groups
    "RadioGroupItemType",
    "IconCardItemType",
    "PaymentCardItemType",
    "AvatarItemType",
    # Command Menu
    "CommandMenuItemType",
    "CommandMenuGroupType",
    # Calendar/Date
    "DateValue",
    "ZonedEvent",
    # Misc
    "ItemProps",
    "T",
]
