"""Human-readable slug generation for conversations."""

from __future__ import annotations

import re
import secrets
from typing import TYPE_CHECKING

if TYPE_CHECKING:
    from ..db import ThreadSafeConnection

SLUG_PATTERN = re.compile(r"^[a-z0-9][a-z0-9-]*[a-z0-9]$")


def is_valid_slug(slug: str) -> bool:
    """Check if a string is a valid slug format."""
    return bool(SLUG_PATTERN.match(slug)) and len(slug) <= 100


ADJECTIVES = [
    "autumn",
    "bold",
    "bright",
    "calm",
    "clear",
    "cold",
    "cool",
    "crisp",
    "dark",
    "dawn",
    "deep",
    "dry",
    "dusk",
    "early",
    "east",
    "fair",
    "fast",
    "fine",
    "flat",
    "free",
    "fresh",
    "full",
    "glad",
    "gold",
    "grand",
    "great",
    "half",
    "hard",
    "high",
    "keen",
    "kind",
    "last",
    "late",
    "lean",
    "light",
    "live",
    "long",
    "loud",
    "main",
    "mild",
    "near",
    "neat",
    "new",
    "next",
    "north",
    "odd",
    "old",
    "open",
    "pale",
    "plain",
    "pure",
    "quick",
    "quiet",
    "rare",
    "raw",
    "rich",
    "rough",
    "round",
    "safe",
    "sharp",
    "short",
    "shy",
    "slim",
    "slow",
    "small",
    "smart",
    "soft",
    "south",
    "spare",
    "steep",
    "still",
    "strong",
    "sure",
    "sweet",
    "tall",
    "thin",
    "tiny",
    "true",
    "vast",
    "warm",
    "west",
    "wide",
    "wild",
    "wise",
    "young",
]

COLORS = [
    "amber",
    "azure",
    "black",
    "blue",
    "bronze",
    "brown",
    "coral",
    "cream",
    "crimson",
    "cyan",
    "gold",
    "green",
    "grey",
    "indigo",
    "ivory",
    "jade",
    "lemon",
    "lilac",
    "lime",
    "navy",
    "olive",
    "orange",
    "pearl",
    "peach",
    "pink",
    "plum",
    "red",
    "rose",
    "ruby",
    "sage",
    "scarlet",
    "silver",
    "teal",
    "violet",
    "white",
    "yellow",
]

NOUNS = [
    "arch",
    "bank",
    "barn",
    "bay",
    "bell",
    "bird",
    "bluff",
    "bolt",
    "book",
    "bow",
    "bridge",
    "brook",
    "cairn",
    "cape",
    "cave",
    "cedar",
    "cliff",
    "cloud",
    "coast",
    "cove",
    "crane",
    "creek",
    "crow",
    "dale",
    "dawn",
    "deer",
    "dell",
    "dock",
    "dove",
    "drum",
    "dune",
    "elm",
    "fern",
    "field",
    "finch",
    "fire",
    "flint",
    "ford",
    "forge",
    "fort",
    "fox",
    "frost",
    "gate",
    "glen",
    "grove",
    "gull",
    "hawk",
    "heath",
    "hedge",
    "heron",
    "hill",
    "isle",
    "ivy",
    "jay",
    "keep",
    "knoll",
    "lake",
    "lark",
    "leaf",
    "ledge",
    "marsh",
    "mill",
    "mint",
    "mist",
    "moon",
    "moss",
    "nest",
    "oak",
    "owl",
    "palm",
    "pass",
    "path",
    "peak",
    "pine",
    "pond",
    "quay",
    "rain",
    "reed",
    "ridge",
    "ring",
    "rock",
    "root",
    "rush",
    "sage",
    "sand",
    "seal",
    "shade",
    "shore",
    "sink",
    "slope",
    "snow",
    "spark",
    "spring",
    "star",
    "stone",
    "storm",
    "sun",
    "swan",
    "thorn",
    "tide",
    "trail",
    "tree",
    "vale",
    "vine",
    "wave",
    "well",
    "wren",
    "yard",
]

MAX_RETRIES = 5


def generate_slug(db: ThreadSafeConnection) -> str:
    """Generate a unique adjective-color-noun slug."""
    for _ in range(MAX_RETRIES):
        slug = f"{secrets.choice(ADJECTIVES)}-{secrets.choice(COLORS)}-{secrets.choice(NOUNS)}"
        existing = db.execute_fetchone("SELECT 1 FROM conversations WHERE slug = ?", (slug,))
        if not existing:
            return slug
    # Fallback: append random digits
    base = f"{secrets.choice(ADJECTIVES)}-{secrets.choice(COLORS)}-{secrets.choice(NOUNS)}"
    return f"{base}-{secrets.randbelow(900) + 100}"


def suggest_unique_slug(db: ThreadSafeConnection, desired: str) -> str | None:
    """If `desired` is taken, return the next available variant (desired-2, desired-3, ...).

    Returns None if `desired` is already available.
    """
    existing = db.execute_fetchone("SELECT 1 FROM conversations WHERE slug = ?", (desired,))
    if not existing:
        return None
    for suffix in range(2, 100):
        candidate = f"{desired}-{suffix}"
        if not db.execute_fetchone("SELECT 1 FROM conversations WHERE slug = ?", (candidate,)):
            return candidate
    return f"{desired}-{secrets.randbelow(900) + 100}"
