"""Founder dashboard routes — admin-only KPI pages and htmx drilldowns.

Routes: ``/founder/``, ``/founder/health``, ``/founder/growth``,
``/founder/corpus``.  All guarded by ``require_admin`` dependency.
"""

from __future__ import annotations

import logging
from datetime import UTC, datetime, timedelta
from typing import Any

from fastapi import APIRouter, Depends, Request
from fastapi.responses import HTMLResponse

from backend.dashboard.founder.context import (
    CorpusDrilldownContext,
    FounderDashboardContext,
    GrowthDrilldownContext,
    GrowthRowMetrics,
    HealthDrilldownContext,
    HealthRowMetrics,
    TopRowMetrics,
)
from backend.dashboard.middleware.admin_auth import require_admin

_log = logging.getLogger(__name__)

founder_router = APIRouter(
    prefix="/founder",
    tags=["founder"],
    dependencies=[Depends(require_admin)],
)

_STALE_THRESHOLD_HOURS = 48


# ---------------------------------------------------------------------------
# Helpers
# ---------------------------------------------------------------------------


async def _load_latest_metrics() -> dict[str, Any]:
    """Load the most recent founder_metrics document from Firestore."""
    from backend.shared.firestore import get_db

    db = get_db()
    today = datetime.now(UTC).strftime("%Y-%m-%d")
    doc = await db.collection("founder_metrics").document(today).get()
    if doc.exists:
        return doc.to_dict() or {}

    # Fallback: try yesterday
    yesterday = (datetime.now(UTC) - timedelta(days=1)).strftime("%Y-%m-%d")
    doc = await db.collection("founder_metrics").document(yesterday).get()
    if doc.exists:
        return doc.to_dict() or {}
    return {}


async def _load_github_issues() -> dict[str, Any]:
    """Load latest github_issues metrics document."""
    from backend.shared.firestore import get_db

    db = get_db()
    doc = await db.collection("founder_metrics").document("github_issues").get()
    if doc.exists:
        return doc.to_dict() or {}
    return {}


def _is_stale(computed_at: str | None) -> bool:
    """Return True if computed_at is more than 48 hours old."""
    if not computed_at:
        return True
    try:
        dt = datetime.fromisoformat(computed_at)
        if dt.tzinfo is None:
            dt = dt.replace(tzinfo=UTC)
        return datetime.now(UTC) - dt > timedelta(hours=_STALE_THRESHOLD_HOURS)
    except ValueError, TypeError:
        return True


def _determine_system_health(metrics: dict[str, Any]) -> str:
    """Derive system health from key indicators."""
    # Red: any critical signal
    open_p1_p2 = metrics.get("open_issues_p1_p2")
    if isinstance(open_p1_p2, int) and open_p1_p2 > 3:
        return "red"
    cost_ratio = metrics.get("cost_to_revenue_ratio")
    if isinstance(cost_ratio, (int, float)) and cost_ratio > 10:
        return "red"
    postmark_bounce = metrics.get("postmark_bounce_rate")
    if isinstance(postmark_bounce, (int, float)) and postmark_bounce > 5:
        return "red"
    # Yellow: warning signals
    if isinstance(open_p1_p2, int) and open_p1_p2 > 1:
        return "yellow"
    if isinstance(cost_ratio, (int, float)) and cost_ratio > 5:
        return "yellow"
    return "green"


def _determine_scan_trend(metrics: dict[str, Any]) -> str:
    """Derive scan frequency trend from 7d vs 30d comparison."""
    freq_7d = metrics.get("scan_frequency_7d")
    freq_30d = metrics.get("scan_frequency_30d")
    if freq_7d is None or freq_30d is None:
        return "stable"
    # Normalize 30d to weekly rate
    weekly_avg = freq_30d / 4.0 if freq_30d > 0 else 0
    if weekly_avg == 0:
        return "stable"
    if freq_7d > weekly_avg * 1.1:
        return "up"
    if freq_7d < weekly_avg * 0.9:
        return "declining"
    return "stable"


def _build_founder_context(metrics: dict[str, Any]) -> FounderDashboardContext:
    """Build the full founder dashboard context from raw metrics."""
    computed_at = metrics.get("computed_at")

    top_row = TopRowMetrics(
        arr=metrics.get("arr"),
        mrr=metrics.get("mrr"),
        total_customers=metrics.get("total_customers"),
        system_health=_determine_system_health(metrics),
    )

    growth_row = GrowthRowMetrics(
        nrr=metrics.get("nrr"),
        logo_churn_30d=metrics.get("logo_churn_30d"),
        burn_multiple=metrics.get("burn_multiple"),
        cac_payback_days=metrics.get("cac_payback_days"),
    )

    health_row = HealthRowMetrics(
        scan_frequency_trend=_determine_scan_trend(metrics),
        open_issues_p1_p2=metrics.get("open_issues_p1_p2"),
        corpus_triples=metrics.get("corpus_triples"),
        cost_to_revenue_ratio=metrics.get("cost_to_revenue_ratio"),
    )

    return FounderDashboardContext(
        top_row=top_row,
        growth_row=growth_row,
        health_row=health_row,
        computed_at=computed_at,
        is_stale=_is_stale(computed_at),
    )


async def _render_template(
    template_name: str,
    context: dict[str, Any],
) -> HTMLResponse:
    """Render a Jinja2 template and return HTMLResponse."""
    from backend.dashboard.jinja_env import jinja_env

    template = jinja_env.get_template(template_name)
    html = await template.render_async(**context)
    return HTMLResponse(html)


# ---------------------------------------------------------------------------
# Routes
# ---------------------------------------------------------------------------


@founder_router.get("/")
async def founder_index(request: Request) -> HTMLResponse:
    """Main founder dashboard — 3 metric rows with expand drilldowns."""
    metrics = await _load_latest_metrics()
    ctx = _build_founder_context(metrics)

    template_ctx: dict[str, Any] = {
        "ctx": ctx,
        "top_row": ctx.top_row,
        "growth_row": ctx.growth_row,
        "health_row": ctx.health_row,
        "computed_at": ctx.computed_at,
        "is_stale": ctx.is_stale,
        "customer_email": getattr(request.state, "admin_email", ""),
        "tier": "admin",
        "csrf_token": "",
        "theme_preference": "light",
        "show_consent_banner": False,
        "tos_version": "",
        "privacy_version": "",
        "active_page": "founder",
        "features": [],
    }

    return await _render_template("founder/index.html", template_ctx)


@founder_router.get("/health")
async def founder_health(request: Request) -> HTMLResponse:
    """htmx partial: health drilldown."""
    metrics = await _load_latest_metrics()
    issues = await _load_github_issues()

    health_ctx = HealthDrilldownContext(
        postmark_delivery_rate=metrics.get("postmark_delivery_rate"),
        postmark_bounce_rate=metrics.get("postmark_bounce_rate"),
        postmark_spam_rate=metrics.get("postmark_spam_rate"),
        activation_at_risk_count=metrics.get("activation_at_risk_count") or 0,
        issues_by_tier=issues.get("issues_by_tier", {}),
        oldest_unresolved=issues.get("oldest_unresolved"),
    )

    return await _render_template(
        "founder/partials/health.html",
        {"health": health_ctx},
    )


@founder_router.get("/growth")
async def founder_growth(request: Request) -> HTMLResponse:
    """htmx partial: growth drilldown."""
    metrics = await _load_latest_metrics()

    growth_ctx = GrowthDrilldownContext(
        revenue_by_tier=metrics.get("revenue_by_tier") or {},
        arpu=_compute_arpu(metrics),
        mrr_growth_rate=metrics.get("mrr_growth_rate"),
        nps_score=metrics.get("nps_score"),
        scan_frequency_7d=metrics.get("scan_frequency_7d"),
        scan_frequency_30d=metrics.get("scan_frequency_30d"),
    )

    return await _render_template(
        "founder/partials/growth.html",
        {"growth": growth_ctx},
    )


@founder_router.get("/corpus")
async def founder_corpus(request: Request) -> HTMLResponse:
    """htmx partial: corpus drilldown."""
    metrics = await _load_latest_metrics()
    total = metrics.get("corpus_triples") or 0

    if total >= 500:
        readiness = "green"
    elif total >= 100:
        readiness = "yellow"
    else:
        readiness = "red"

    corpus_ctx = CorpusDrilldownContext(
        total_triples=total,
        readiness=readiness,
        resource_type_distribution=metrics.get("resource_type_distribution") or {},
    )

    return await _render_template(
        "founder/partials/corpus.html",
        {"corpus": corpus_ctx},
    )


def _compute_arpu(metrics: dict[str, Any]) -> float | None:
    """Compute ARPU from MRR and total customers."""
    mrr = metrics.get("mrr")
    total = metrics.get("total_customers")
    if mrr is None or total is None or total == 0:
        return None
    return round(mrr / total, 2)
