"""Skill topic registry and lookup."""

from __future__ import annotations

from dataclasses import dataclass, field
from functools import lru_cache
import importlib


@dataclass
class ParamSpec:
    """Structured parameter specification for a create/update command."""

    name: str
    type: str
    required: bool
    description: str
    default: str | None = None
    enum_values: list[str] | None = None
    condition: str | None = None


@dataclass
class SkillTopic:
    name: str
    summary: str
    commands: list[str] = field(default_factory=list)
    examples: list[str] = field(default_factory=list)
    workflows: list[dict[str, str | list[str]]] = field(default_factory=list)
    related: list[str] = field(default_factory=list)
    create_params: list[ParamSpec] = field(default_factory=list)
    notes: list[str] = field(default_factory=list)


def register_topics(*topics: SkillTopic) -> None:
    """Register topics into the global registry. Called by topics/__init__.py."""
    for t in topics:
        _TOPICS[t.name] = t


_TOPICS: dict[str, SkillTopic] = {}


@lru_cache(maxsize=1)
def _ensure_loaded() -> bool:
    """Ensure topic modules have been imported (triggers registration)."""
    if not _TOPICS:
        importlib.import_module("turumba_cli.skills.topics")
    return True


def list_topics() -> list[SkillTopic]:
    """Return all registered topics."""
    _ensure_loaded()
    return list(_TOPICS.values())


def get_topic(name: str) -> SkillTopic | None:
    """Get a topic by exact name."""
    _ensure_loaded()
    return _TOPICS.get(name)


def search(query: str) -> list[tuple[SkillTopic, int]]:
    """Score topics by keyword overlap with query. Returns (topic, score) sorted descending."""
    _ensure_loaded()
    keywords = {w.lower() for w in query.split() if len(w) > 1}
    if not keywords:
        return []

    scored: list[tuple[SkillTopic, int]] = []
    for topic in _TOPICS.values():
        searchable = " ".join(
            [
                topic.name,
                topic.summary,
                " ".join(topic.commands),
                " ".join(topic.examples),
            ]
        ).lower()
        score = sum(1 for kw in keywords if kw in searchable)
        if score > 0:
            scored.append((topic, score))

    scored.sort(key=lambda x: x[1], reverse=True)
    return scored
