import logging
logger = logging.getLogger(__name__)
from fastapi import APIRouter, Request, Depends
from fastapi.responses import HTMLResponse, RedirectResponse
from fastapi.templating import Jinja2Templates
from sqlalchemy import text
from ..dependencies import get_db, get_current_user
from ..config import APP_NAME

router = APIRouter()
templates = Jinja2Templates(directory="app/templates")


@router.get("/dashboard", response_class=HTMLResponse)
async def dashboard(request: Request, db=Depends(get_db)):
    user = get_current_user(request)
    if not user:
        return RedirectResponse(url="/login")

    # Stats generales
    stats = {}
    stats["total_servers"] = db.execute(text("SELECT COUNT(*) FROM servers")).scalar()
    stats["patchable"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE patch_os_owner='secops' AND etat='Production'")).scalar()
    stats["linux"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE os_family='linux'")).scalar()
    stats["windows"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE os_family='windows'")).scalar()
    stats["decom"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='Obsolète'")).scalar()
    stats["obsolete"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE licence_support='obsolete'")).scalar()
    stats["qualys_assets"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets")).scalar()
    stats["qualys_tags"] = db.execute(text("SELECT COUNT(*) FROM qualys_tags")).scalar()
    stats["qualys_active"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%active%' AND agent_status NOT ILIKE '%inactive%'")).scalar()
    stats["qualys_inactive"] = db.execute(text("SELECT COUNT(*) FROM qualys_assets WHERE agent_status ILIKE '%inactive%'")).scalar()
    stats["qualys_no_agent"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE etat='Production' AND NOT EXISTS (SELECT 1 FROM qualys_assets qa WHERE LOWER(qa.hostname) = LOWER(servers.hostname))")).scalar()
    stats["eol"] = stats["obsolete"]
    try:
        stats["dmz"] = db.execute(text("SELECT COUNT(*) FROM servers WHERE zone_id IN (SELECT id FROM zones WHERE is_dmz=true)")).scalar() or 0
    except Exception:
        db.rollback()
        stats["dmz"] = 0
    try:
        stats["patched_history_2026"] = db.execute(text(
            "SELECT COUNT(DISTINCT server_id) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026"
        )).scalar() or 0
        stats["patch_events_2026"] = db.execute(text(
            "SELECT COUNT(*) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026"
        )).scalar() or 0
        stats["never_patched_2026"] = db.execute(text("""
            SELECT COUNT(*) FROM servers s
            WHERE s.etat='Production' AND s.patch_os_owner='secops'
              AND NOT EXISTS (SELECT 1 FROM patch_history ph
                              WHERE ph.server_id=s.id AND EXTRACT(YEAR FROM ph.date_patch)=2026)
        """)).scalar() or 0
        stats["last_patch_week"] = db.execute(text(
            "SELECT MAX(TO_CHAR(date_patch, 'IW')) FROM patch_history WHERE EXTRACT(YEAR FROM date_patch)=2026"
        )).scalar() or "-"
    except Exception:
        db.rollback()
        stats["patched_history_2026"] = 0
        stats["patch_events_2026"] = 0
        stats["never_patched_2026"] = 0
        stats["last_patch_week"] = "-"

    # Par domaine
    domains = db.execute(text("""
        SELECT d.name, d.code, COUNT(s.id) as total,
            COUNT(*) FILTER (WHERE s.etat='Production') as actifs,
            COUNT(*) FILTER (WHERE s.os_family='linux') as linux,
            COUNT(*) FILTER (WHERE s.os_family='windows') as windows
        FROM servers s
        JOIN domain_environments de ON s.domain_env_id = de.id
        JOIN domains d ON de.domain_id = d.id
        GROUP BY d.name, d.code, d.display_order
        ORDER BY d.display_order
    """)).fetchall()

    # Par tier
    tiers = db.execute(text("SELECT tier, COUNT(*) FROM servers GROUP BY tier ORDER BY tier")).fetchall()

    # ── Stats patching 2026 ──
    patch_stats = db.execute(text("""
        SELECT
            COUNT(*) as audited,
            COUNT(*) FILTER (WHERE last_patch_year = 2026) as patched_2026,
            COUNT(*) FILTER (WHERE last_patch_year = 2025) as patched_2025_only,
            COUNT(*) FILTER (WHERE last_patch_year IS NULL OR last_patch_week IS NULL) as never_patched,
            COUNT(*) FILTER (WHERE patch_count_2026 >= 1) as patched_once,
            COUNT(*) FILTER (WHERE patch_count_2026 >= 2) as patched_twice,
            COUNT(*) FILTER (WHERE patch_count_2026 >= 3) as patched_thrice,
            COUNT(*) FILTER (WHERE reboot_required = true) as needs_reboot
        FROM server_audit_full
        WHERE status IN ('ok','partial')
        AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
    """)).fetchone()

    # Frequence patching par semaine 2026
    patch_weekly = db.execute(text("""
        SELECT last_patch_week as week, COUNT(*) as cnt
        FROM server_audit_full
        WHERE status IN ('ok','partial') AND last_patch_year = 2026 AND last_patch_week IS NOT NULL
        AND id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
        GROUP BY last_patch_week ORDER BY last_patch_week
    """)).fetchall()

    # Patching par domaine
    patch_by_domain = db.execute(text("""
        SELECT d.name as domain, d.code,
            COUNT(DISTINCT saf.hostname) as total,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.last_patch_year = 2026) as patched,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.patch_count_2026 >= 2) as patched_twice,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.last_patch_year IS NULL) as never
        FROM server_audit_full saf
        JOIN servers s ON saf.server_id = s.id
        JOIN domain_environments de ON s.domain_env_id = de.id
        JOIN domains d ON de.domain_id = d.id
        WHERE saf.status IN ('ok','partial')
        AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
        GROUP BY d.name, d.code, d.display_order
        ORDER BY d.display_order
    """)).fetchall()

    # Patching par environnement
    patch_by_env = db.execute(text("""
        SELECT e.name as env,
            COUNT(DISTINCT saf.hostname) as total,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.last_patch_year = 2026) as patched
        FROM server_audit_full saf
        JOIN servers s ON saf.server_id = s.id
        JOIN domain_environments de ON s.domain_env_id = de.id
        JOIN environments e ON de.environment_id = e.id
        WHERE saf.status IN ('ok','partial')
        AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
        GROUP BY e.name ORDER BY e.name
    """)).fetchall()

    # Patching par zone (DMZ, LAN, EMV)
    patch_by_zone = db.execute(text("""
        SELECT z.name as zone,
            COUNT(DISTINCT saf.hostname) as total,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.last_patch_year = 2026) as patched,
            COUNT(DISTINCT saf.hostname) FILTER (WHERE saf.last_patch_year IS NULL) as never
        FROM server_audit_full saf
        JOIN servers s ON saf.server_id = s.id
        JOIN zones z ON s.zone_id = z.id
        WHERE saf.status IN ('ok','partial')
        AND saf.id IN (SELECT DISTINCT ON (hostname) id FROM server_audit_full WHERE status IN ('ok','partial') ORDER BY hostname, audit_date DESC)
        GROUP BY z.name ORDER BY z.name
    """)).fetchall()

    return templates.TemplateResponse("dashboard.html", {
        "request": request, "user": user, "app_name": APP_NAME,
        "stats": stats, "domains": domains, "tiers": tiers,
        "patch_stats": patch_stats, "patch_weekly": patch_weekly,
        "patch_by_domain": patch_by_domain, "patch_by_env": patch_by_env,
        "patch_by_zone": patch_by_zone,
    })
