"""Browse community skills from a hosted catalog."""

from __future__ import annotations

import json
from dataclasses import dataclass, field
from typing import Any


# Default catalog URL — can be overridden for testing
CATALOG_URL = (
    "https://raw.githubusercontent.com/alive-agent/community-skills/"
    "main/catalog.json"
)


@dataclass
class CommunitySkill:
    """A skill listed in the community catalog."""

    name: str
    description: str
    author: str = ""
    install_url: str = ""
    tags: list[str] = field(default_factory=list)
    downloads: int = 0


def browse_skills(
    *,
    search: str | None = None,
    catalog_url: str | None = None,
) -> list[CommunitySkill]:
    """Fetch and optionally filter the community skill catalog.

    Args:
        search: Optional keyword to filter skills.
        catalog_url: Override catalog URL for testing.

    Returns:
        List of CommunitySkill entries.

    Raises:
        ConnectionError: If the catalog can't be fetched.
    """
    url = catalog_url or CATALOG_URL
    data = _fetch_catalog(url)

    skills = [_parse_entry(entry) for entry in data.get("skills", [])]

    if search:
        tokens = search.lower().split()
        skills = [
            s for s in skills
            if any(
                t in s.name.lower()
                or t in s.description.lower()
                or any(t in tag.lower() for tag in s.tags)
                for t in tokens
            )
        ]

    return skills


def _fetch_catalog(url: str) -> dict[str, Any]:
    """Fetch the catalog JSON from a URL."""
    import urllib.request
    import urllib.error

    try:
        req = urllib.request.Request(
            url,
            headers={"Accept": "application/json"},
        )
        with urllib.request.urlopen(req, timeout=15) as resp:
            return json.loads(resp.read())
    except urllib.error.URLError as e:
        raise ConnectionError(
            f"Could not fetch community catalog: {e}\n"
            f"URL: {url}"
        ) from e
    except json.JSONDecodeError as e:
        raise ConnectionError(
            f"Invalid catalog format: {e}\n"
            f"URL: {url}"
        ) from e


def _parse_entry(entry: dict[str, Any]) -> CommunitySkill:
    """Parse a catalog entry into a CommunitySkill."""
    return CommunitySkill(
        name=entry.get("name", "unknown"),
        description=entry.get("description", ""),
        author=entry.get("author", ""),
        install_url=entry.get("install_url", ""),
        tags=entry.get("tags", []),
        downloads=entry.get("downloads", 0),
    )
