"""Phase 13: Executive Dashboard router."""

from typing import List

from fastapi import APIRouter, Depends, Query
from sqlalchemy.orm import Session

from app.database import get_db
from app.dependencies.auth import get_current_user, require_any_role
from app.schemas.executive_dashboard_schema import (
    PostureSnapshotOut,
    ExecutiveSummary,
    KpiBlock,
    CoverageByTactic,
    PostureHistoryEntry,
    ActivityEntry,
)
import app.services.executive_dashboard_service as svc

router = APIRouter(prefix="/dashboard", tags=["Executive Dashboard"])


@router.get("/executive", response_model=ExecutiveSummary)
def executive_view(
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """
    Full executive view — snapshot, 30-day trends, top risks,
    coverage by tactic, and recent activity feed.
    """
    data = svc.get_executive_summary(db)
    snap = data["snapshot"]
    return ExecutiveSummary(
        snapshot=PostureSnapshotOut.model_validate(snap),
        coverage_trend=data["coverage_trend"],
        risk_trend=data["risk_trend"],
        top_risks=data["top_risks"],
        coverage_by_tactic=data["coverage_by_tactic"],
        recent_activity=data["recent_activity"],
    )


@router.get("/kpis", response_model=KpiBlock)
def kpis(
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """Compact KPI block — live aggregation without persisting a snapshot."""
    live = svc.get_live_kpis(db)

    # Try to find today's snapshot id; fall back to None
    from datetime import date
    from app.models.executive_dashboard import PostureSnapshot
    today_snap = db.query(PostureSnapshot).filter(
        PostureSnapshot.snapshot_date == date.today()
    ).first()

    return KpiBlock(
        coverage_pct=live["coverage_pct"],
        avg_risk_score=live["avg_risk_score"],
        critical_count=live["critical_count"],
        open_queue_items=live["open_queue_items"],
        orphan_techniques=live["orphan_techniques"],
        mttd_avg_seconds=live.get("mttd_avg_seconds"),
        detection_rate_30d=live.get("detection_rate_30d"),
        playbook_count=live["playbook_count"],
        lesson_count=live["lesson_count"],
        snapshot_date=live["snapshot_date"],
        snapshot_id=today_snap.id if today_snap else None,
    )


@router.get("/coverage-by-tactic", response_model=List[CoverageByTactic])
def coverage_by_tactic(
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """Per-tactic validated / partial / not_covered breakdown."""
    return svc.get_coverage_by_tactic(db)


@router.get("/posture-history", response_model=List[PostureHistoryEntry])
def posture_history(
    days: int = Query(30, ge=1, le=365),
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """Historical posture snapshots for trend charts (default last 30 days)."""
    snaps = svc.get_posture_history(db, days=days)
    return [
        PostureHistoryEntry(
            snapshot_date=s.snapshot_date,
            coverage_pct=s.coverage_pct,
            avg_risk_score=s.avg_risk_score,
            critical_count=s.critical_count,
            open_queue_items=s.open_queue_items,
        )
        for s in snaps
    ]


@router.post("/posture-snapshot", response_model=PostureSnapshotOut, status_code=201)
def create_posture_snapshot(
    db: Session = Depends(get_db),
    user=Depends(require_any_role("admin", "red_lead", "blue_lead")),
):
    """
    Take (or refresh) today's posture snapshot — admin / leads only.
    Aggregates live data from all phases into a single PostureSnapshot row.
    """
    snap = svc.take_posture_snapshot(db, created_by=user.id)
    return PostureSnapshotOut.model_validate(snap)


@router.get("/activity", response_model=List[ActivityEntry])
def recent_activity(
    limit: int = Query(20, ge=1, le=100),
    db: Session = Depends(get_db),
    user=Depends(get_current_user),
):
    """Recent activity feed — tests, attack-path executions, OSINT signals."""
    return svc.get_recent_activity(db, limit=limit)
