from __future__ import annotations

from .curated import get_all_curated, get_curated
from .renderer import render_meme
from .templates import get_all_templates, get_template, search_templates


def list_memes(query: str | None = None) -> list[dict]:
    """List available meme templates, optionally filtered by query."""
    if query:
        from_templates = search_templates(query)

        # Also search curated tags
        query_lower = query.lower()
        curated_matches = set()
        for meme_id, info in get_all_curated().items():
            tags_str = " ".join(info["tags"])
            if query_lower in tags_str or query_lower in info["description"].lower():
                curated_matches.add(meme_id)

        # Merge results
        seen = {t.id for t in from_templates}
        for meme_id in curated_matches:
            if meme_id not in seen:
                t = get_template(meme_id)
                if t:
                    from_templates.append(t)

        templates = from_templates
    else:
        templates = list(get_all_templates().values())

    results = []
    for t in templates:
        entry: dict = {
            "id": t.id,
            "name": t.name,
            "lines": len(t.lines),
            "keywords": t.keywords,
        }
        if t.example:
            entry["example"] = t.example
        results.append(entry)

    return results


def get_meme(template_id: str) -> dict:
    """Get detailed info about a meme template."""
    t = get_template(template_id)
    if t is None:
        return {"error": f"Template '{template_id}' not found"}

    result: dict = {
        "id": t.id,
        "name": t.name,
        "lines_count": len(t.lines),
        "example": t.example,
        "keywords": t.keywords,
        "source": t.source,
    }

    curated = get_curated(template_id)
    if curated:
        result["description"] = curated["description"]
        result["humor"] = curated["humor"]
        result["when_to_use"] = curated["when_to_use"]
        result["line_descriptions"] = curated["lines"]
        result["tips"] = curated["tips"]
    else:
        result["description"] = f"Meme template: {t.name}"
        line_descs = {}
        for i in range(len(t.lines)):
            line_descs[str(i + 1)] = f"Text line {i + 1}"
        result["line_descriptions"] = line_descs

    return result


def gen_meme(
    template_id: str,
    text: dict[str, str],
    *,
    font: str | None = None,
    style: str | None = None,
    max_width: int = 800,
    max_height: int = 800,
    extension: str = "png",
) -> bytes:
    """Generate a meme image and return the image bytes."""
    # Normalize text dict to ordered lines list
    # Support both {"1": ..., "2": ...} and {"top": ..., "bottom": ...} formats
    if any(k in text for k in ("top", "bottom")):
        lines = [text.get("top", ""), text.get("bottom", "")]
    else:
        max_key = max(int(k) for k in text if k.isdigit()) if text else 0
        lines = []
        for i in range(1, max_key + 1):
            lines.append(text.get(str(i), ""))

    return render_meme(
        template_id,
        lines,
        font_name=font or "",
        style=style or "default",
        max_width=max_width,
        max_height=max_height,
        extension=extension,
    )
