"""Convenience functions for searching DropThe data.

    >>> import dropthe
    >>> dropthe.search("Inception")
    [{'name': 'Inception', 'slug': 'inception-2010', 'rating': '8.4', ...}]

Browse entities: https://dropthe.org
"""

from __future__ import annotations

from dropthe.datasets import movies, crypto, companies, games, universities


def search(query: str, *, type: str | None = None, limit: int = 20) -> list[dict]:
    """Search across all DropThe datasets.

    Performs a case-insensitive name search across loaded datasets.
    For large datasets (movies: 155K, universities: 27K), data is fetched
    from GitHub on first call and cached in memory.

    Args:
        query: Search term (case-insensitive substring match on 'name').
        type: Filter by dataset ('movies', 'crypto', 'companies', 'games', 'universities').
        limit: Max results (default 20).

    Returns:
        List of matching entity dicts.

    Examples:
        >>> dropthe.search("Bitcoin")
        [{'name': 'Bitcoin', 'slug': 'bitcoin', 'symbol': 'BTC', ...}]

        >>> dropthe.search("Dark Knight", type="movies")
        [{'name': 'The Dark Knight', 'slug': 'the-dark-knight-2008', ...}]
    """
    q = query.lower()
    results = []

    datasets = {
        "movies": movies,
        "crypto": crypto,
        "companies": companies,
        "games": games,
        "universities": universities,
    }

    if type and type in datasets:
        datasets = {type: datasets[type]}

    for dtype, loader in datasets.items():
        try:
            data = loader()
            for row in data:
                name = row.get("name", "")
                if name and q in name.lower():
                    row["_type"] = dtype
                    results.append(row)
                    if len(results) >= limit:
                        return results
        except Exception:
            continue

    return results[:limit]


def entity(slug: str, *, type: str | None = None) -> dict | None:
    """Get a single entity by its URL slug.

    Args:
        slug: Entity slug (e.g., 'inception-2010', 'bitcoin').
        type: Which dataset to search (faster if specified).

    Returns:
        Entity dict or None.

    Examples:
        >>> dropthe.entity("bitcoin")
        {'name': 'Bitcoin', 'slug': 'bitcoin', ...}

        >>> dropthe.entity("inception-2010", type="movies")
        {'name': 'Inception', ...}
    """
    datasets = {
        "movies": movies,
        "crypto": crypto,
        "companies": companies,
        "games": games,
        "universities": universities,
    }

    if type and type in datasets:
        datasets = {type: datasets[type]}

    for dtype, loader in datasets.items():
        try:
            data = loader()
            for row in data:
                if row.get("slug") == slug:
                    row["_type"] = dtype
                    return row
        except Exception:
            continue

    return None
