from typing import Literal

from pydantic import BaseModel, ConfigDict, Field

StarterLayer = Literal["foundation", "primitive", "composite", "adapter"]

StarterAdmission = Literal["admitted", "proposed"]

StarterState = Literal[
    "idle",
    "loading",
    "success",
    "empty",
    "error",
    "unauthorized",
    "configuration_required",
]

STARTER_CONTRACT_VERSION = 1
STARTER_CATALOG_SCHEMA_VERSION = 1

A11Y_BASELINE: tuple[str, ...] = (
    "keyboard_navigable",
    "visible_focus",
    "labeled",
    "semantic_html",
    "aria_only_when_needed",
    "contrast_safe_tokens",
    "reduced_motion",
)

A11Y_FOUNDATION: tuple[str, ...] = (
    "contrast_safe_tokens",
    "reduced_motion",
)

DATA_STATES: tuple[StarterState, ...] = (
    "idle",
    "loading",
    "success",
    "empty",
    "error",
    "unauthorized",
    "configuration_required",
)


class StarterRuntimeDependency(BaseModel):
    """Connector or capability binding that activates a hosted surface at runtime."""

    model_config = ConfigDict(extra="forbid")
    binding: str
    configuration_required: bool = False


class StarterContract(BaseModel):
    """Machine-readable Starter Library catalog entry.

    `description` is the purpose. Codegen should prefer an admitted contract
    whose `use_when` matches before generating a project-local equivalent.
    """

    model_config = ConfigDict(extra="forbid")
    id: str
    layer: StarterLayer
    description: str
    framework_agnostic: bool = True
    admission: StarterAdmission = "admitted"
    use_when: list[str] = Field(default_factory=list)
    avoid_when: list[str] = Field(default_factory=list)
    supports: list[str] = Field(default_factory=list)
    requires: list[str] = Field(default_factory=list)
    compatible_with: list[str] = Field(default_factory=list)
    states: list[StarterState] = Field(default_factory=list)
    accessibility: list[str] = Field(default_factory=list)
    fallbacks: dict[str, str] = Field(default_factory=dict)
    runtime_dependencies: list[StarterRuntimeDependency] = Field(default_factory=list)


class StarterContractRequirement(BaseModel):
    model_config = ConfigDict(extra="forbid")
    min_version: int = Field(default=STARTER_CONTRACT_VERSION, ge=1)
