from datetime import datetime, timedelta
from typing import Any, Dict, Optional

from health import HealthCheck, HealthStatus


def check_motion_freshness(
    conn: Any,
    max_age_days: int = 7,
    min_motions: int = 100,
) -> HealthCheck:
    try:
        result = conn.execute(
            "SELECT COUNT(*) FROM motions WHERE date >= ?",
            [datetime.now() - timedelta(days=max_age_days)],
        ).fetchone()
        count = result[0] if result else 0
    except Exception as e:
        return HealthCheck(
            name="motion_freshness",
            status=HealthStatus.CRITICAL,
            message=f"Could not query motion freshness: {e}",
            details={},
        )

    if count == 0:
        return HealthCheck(
            name="motion_freshness",
            status=HealthStatus.CRITICAL,
            message=f"No motions in last {max_age_days} days",
            details={"count": 0, "threshold": max_age_days},
        )
    if count < min_motions:
        return HealthCheck(
            name="motion_freshness",
            status=HealthStatus.WARNING,
            message=f"Only {count} motions in last {max_age_days} days (expected >= {min_motions})",
            details={"count": count, "threshold": max_age_days, "min_expected": min_motions},
        )
    return HealthCheck(
        name="motion_freshness",
        status=HealthStatus.OK,
        message=f"{count} motions in last {max_age_days} days",
        details={"count": count, "threshold": max_age_days},
    )


def check_embedding_coverage(
    conn: Any,
    min_coverage: float = 0.95,
) -> HealthCheck:
    try:
        total_result = conn.execute("SELECT COUNT(*) FROM motions").fetchone()
        total = total_result[0] if total_result else 0

        if total == 0:
            return HealthCheck(
                name="embedding_coverage",
                status=HealthStatus.CRITICAL,
                message="No motions in database",
                details={"total": 0, "with_embeddings": 0, "coverage": 0.0},
            )

        embed_result = conn.execute(
            "SELECT COUNT(DISTINCT motion_id) FROM fused_embeddings"
        ).fetchone()
        with_embeddings = embed_result[0] if embed_result else 0
        coverage = with_embeddings / total
    except Exception as e:
        return HealthCheck(
            name="embedding_coverage",
            status=HealthStatus.CRITICAL,
            message=f"Could not query embedding coverage: {e}",
            details={},
        )

    if coverage < min_coverage:
        return HealthCheck(
            name="embedding_coverage",
            status=HealthStatus.WARNING,
            message=f"Embedding coverage {coverage:.1%} (expected >= {min_coverage:.0%})",
            details={"total": total, "with_embeddings": with_embeddings, "coverage": coverage},
        )
    return HealthCheck(
        name="embedding_coverage",
        status=HealthStatus.OK,
        message=f"Embedding coverage {coverage:.1%}",
        details={"total": total, "with_embeddings": with_embeddings, "coverage": coverage},
    )


def check_llm_coverage(
    conn: Any,
    max_missing_ratio: float = 0.15,
) -> HealthCheck:
    try:
        total_result = conn.execute("SELECT COUNT(*) FROM motions").fetchone()
        total = total_result[0] if total_result else 0

        if total == 0:
            return HealthCheck(
                name="llm_coverage",
                status=HealthStatus.CRITICAL,
                message="No motions in database",
                details={"total": 0, "missing": 0, "missing_ratio": 0.0},
            )

        missing_result = conn.execute(
            "SELECT COUNT(*) FROM motions WHERE layman_explanation IS NULL OR layman_explanation = ''"
        ).fetchone()
        missing = missing_result[0] if missing_result else 0
        missing_ratio = missing / total
    except Exception as e:
        return HealthCheck(
            name="llm_coverage",
            status=HealthStatus.CRITICAL,
            message=f"Could not query LLM coverage: {e}",
            details={},
        )

    if missing_ratio > max_missing_ratio:
        return HealthCheck(
            name="llm_coverage",
            status=HealthStatus.CRITICAL,
            message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
            details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
        )
    if missing_ratio > 0.05:
        return HealthCheck(
            name="llm_coverage",
            status=HealthStatus.WARNING,
            message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
            details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
        )
    return HealthCheck(
        name="llm_coverage",
        status=HealthStatus.OK,
        message=f"{missing_ratio:.1%} missing layman explanations ({missing}/{total})",
        details={"total": total, "missing": missing, "missing_ratio": missing_ratio},
    )
