"""
pSEO Engine admin blueprint.

Operational visibility for the programmatic SEO system:
  /admin/pseo/            → dashboard (template stats, freshness, recent jobs)
  /admin/pseo/health      → HTMX partial: health issues
  /admin/pseo/gaps/<slug> → HTMX partial: content gaps for one template
  /admin/pseo/gaps/<slug>/generate → POST: enqueue gap-fill job
  /admin/pseo/jobs        → recent generation jobs
  /admin/pseo/jobs/<id>/status → HTMX polled: progress bar for one job

Registered as a standalone blueprint so admin/routes.py (already ~2,100 lines)
stays focused on its own domain.
"""
from datetime import date
from pathlib import Path

from quart import Blueprint, flash, redirect, render_template, url_for

from ..auth.routes import role_required
from ..content import discover_templates, load_template
from ..content.health import (
    get_all_health_issues,
    get_content_gaps,
    get_template_freshness,
    get_template_stats,
)
from ..core import count_where, csrf_protect, fetch_all, fetch_one

bp = Blueprint(
    "pseo",
    __name__,
    template_folder=str(Path(__file__).parent / "templates"),
    url_prefix="/admin/pseo",
)


@bp.before_request
async def _inject_sidebar_data():
    """Load unread inbox count for the admin sidebar badge."""
    from quart import g

    try:
        g.admin_unread_count = await count_where("inbound_emails WHERE is_read = 0")
    except Exception:
        g.admin_unread_count = 0


@bp.context_processor
def _admin_context():
    """Expose admin-specific variables to all pSEO templates."""
    from quart import g

    return {"unread_count": getattr(g, "admin_unread_count", 0)}


# ── Dashboard ────────────────────────────────────────────────────────────────


@bp.route("/")
@role_required("admin")
async def pseo_dashboard():
    """pSEO Engine dashboard: template stats, freshness, recent jobs."""
    templates = discover_templates()

    freshness = await get_template_freshness(templates)
    freshness_by_slug = {f["slug"]: f for f in freshness}

    template_rows = []
    for t in templates:
        stats = await get_template_stats(t["slug"])
        template_rows.append({
            "template": t,
            "stats": stats,
            "freshness": freshness_by_slug.get(t["slug"], {}),
        })

    total_articles = sum(r["stats"]["total"] for r in template_rows)
    total_published = sum(r["stats"]["published"] for r in template_rows)
    stale_count = sum(1 for f in freshness if f["status"] == "stale")

    noindex_count = await count_where("articles WHERE noindex = 1")

    # Recent generation jobs — enough for the dashboard summary.
    jobs = await fetch_all(
        "SELECT id, task_name, status, progress_current, progress_total,"
        "  error, error_log, created_at, completed_at"
        " FROM tasks WHERE task_name = 'generate_articles'"
        " ORDER BY created_at DESC LIMIT 5",
    )

    return await render_template(
        "admin/pseo_dashboard.html",
        template_rows=template_rows,
        total_articles=total_articles,
        total_published=total_published,
        total_templates=len(templates),
        stale_count=stale_count,
        noindex_count=noindex_count,
        jobs=jobs,
        admin_page="pseo",
    )


# ── Health checks (HTMX partial) ─────────────────────────────────────────────


@bp.route("/health")
@role_required("admin")
async def pseo_health():
    """HTMX partial: all health issue lists."""
    templates = discover_templates()
    health = await get_all_health_issues(templates)
    return await render_template("admin/pseo_health.html", health=health)


# ── Content gaps (HTMX partial + generate action) ────────────────────────────


@bp.route("/gaps/<slug>")
@role_required("admin")
async def pseo_gaps_template(slug: str):
    """HTMX partial: content gaps for a specific template."""
    try:
        config = load_template(slug)
    except (AssertionError, FileNotFoundError):
        return "Template not found", 404

    gaps = await get_content_gaps(
        template_slug=slug,
        data_table=config["data_table"],
        natural_key=config["natural_key"],
        languages=config["languages"],
    )
    return await render_template(
        "admin/pseo_gaps.html",
        template=config,
        gaps=gaps,
    )


@bp.route("/gaps/<slug>/generate", methods=["POST"])
@role_required("admin")
@csrf_protect
async def pseo_generate_gaps(slug: str):
    """Enqueue a generation job limited to filling gaps for this template."""
    from ..worker import enqueue

    try:
        config = load_template(slug)
    except (AssertionError, FileNotFoundError):
        await flash("Template not found.", "error")
        return redirect(url_for("pseo.pseo_dashboard"))

    gaps = await get_content_gaps(
        template_slug=slug,
        data_table=config["data_table"],
        natural_key=config["natural_key"],
        languages=config["languages"],
    )

    if not gaps:
        await flash(f"No gaps found for '{config['name']}' — nothing to generate.", "info")
        return redirect(url_for("pseo.pseo_dashboard"))

    await enqueue("generate_articles", {
        "template_slug": slug,
        "start_date": date.today().isoformat(),
        "articles_per_day": 500,
    })
    await flash(
        f"Queued generation for {len(gaps)} missing articles in '{config['name']}'.",
        "success",
    )
    return redirect(url_for("pseo.pseo_dashboard"))


# ── Generation job monitoring ─────────────────────────────────────────────────


@bp.route("/jobs")
@role_required("admin")
async def pseo_jobs():
    """Full list of recent article generation jobs."""
    jobs = await fetch_all(
        "SELECT id, task_name, status, progress_current, progress_total,"
        "  error, error_log, created_at, completed_at"
        " FROM tasks WHERE task_name = 'generate_articles'"
        " ORDER BY created_at DESC LIMIT 20",
    )
    return await render_template(
        "admin/pseo_jobs.html",
        jobs=jobs,
        admin_page="pseo",
    )


@bp.route("/jobs/<int:job_id>/status")
@role_required("admin")
async def pseo_job_status(job_id: int):
    """HTMX polled endpoint: progress bar for a running generation job."""
    job = await fetch_one(
        "SELECT id, status, progress_current, progress_total, error, error_log,"
        "  created_at, completed_at"
        " FROM tasks WHERE id = ?",
        (job_id,),
    )
    if not job:
        return "Job not found", 404
    return await render_template("admin/pseo_job_status.html", job=job)
