import json
from pathlib import Path
from typing import Optional

import pandas as pd
from fastapi import APIRouter, Depends, HTTPException, Query

from ..core.config import get_settings
from ..db_models.internal import UsuarioAdmin
from ..dependencies import get_current_admin

router = APIRouter(prefix="/predictions", tags=["Predicciones"])
settings = get_settings()

PREDS_DIR = Path(settings.models_base_path) / "predictions"
DATASETS_DIR = Path(settings.models_base_path) / "datasets"

ML_DASHBOARDS: dict[str, str] = {
    "avg_final": "dashboard_ml_avg_final.json",
    "grade_tendency": "dashboard_ml_grade_tendency.json",
    "math_final": "dashboard_ml_math_final.json",
    "math_pass": "dashboard_ml_math_pass.json",
    "models_overview": "dashboard_ml_models.json",
    "support_level": "dashboard_ml_support_level.json",
}

NLP_DATASETS: dict[str, str] = {
    "career_recommendation": "nlp_pred_career_recommendation.csv",
    "risk_alert": "nlp_pred_risk_alert.csv",
    "computer_science": "nlp_pred_computer_science.csv",
    "technical_drawing": "nlp_pred_technical_drawing.csv",
}

ML_DATASETS: dict[str, str] = {
    "math_risk": "math_risk_scores.csv",
    "support_level": "support_level_predictions.csv",
}


def _paginate(df: pd.DataFrame, page: int, page_size: int) -> dict:
    total = len(df)
    start = (page - 1) * page_size
    rows = df.iloc[start : start + page_size].fillna("").to_dict(orient="records")
    return {"total": total, "page": page, "page_size": page_size, "items": rows}


# ── ML Dashboards ───────────────────────────────────────────────────────────────

@router.get("/dashboards", summary="Lista de dashboards ML disponibles")
def list_ml_dashboards(_: UsuarioAdmin = Depends(get_current_admin)):
    return {"ml_dashboards": list(ML_DASHBOARDS.keys())}


@router.get("/dashboards/{name}", summary="Datos Plotly JSON de un dashboard de modelo ML")
def get_ml_dashboard(name: str, _: UsuarioAdmin = Depends(get_current_admin)):
    if name not in ML_DASHBOARDS:
        raise HTTPException(
            status_code=404,
            detail=f"Dashboard '{name}' no encontrado. Disponibles: {list(ML_DASHBOARDS.keys())}",
        )
    path = PREDS_DIR / ML_DASHBOARDS[name]
    return json.loads(path.read_text(encoding="utf-8"))


# ── NLP predictions ─────────────────────────────────────────────────────────────

@router.get("/nlp/{name}", summary="Predicciones NLP por dataset")
def get_nlp_predictions(
    name: str,
    student_id: Optional[str] = Query(None, description="Filtrar por student_id"),
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=500),
    _: UsuarioAdmin = Depends(get_current_admin),
):
    if name not in NLP_DATASETS:
        raise HTTPException(
            status_code=404,
            detail=f"Dataset '{name}' no encontrado. Disponibles: {list(NLP_DATASETS.keys())}",
        )
    df = pd.read_csv(DATASETS_DIR / NLP_DATASETS[name])
    if student_id:
        df = df[df["student_id"] == student_id]
    return _paginate(df, page, page_size)


# ── ML predictions ──────────────────────────────────────────────────────────────

@router.get("/ml/{name}", summary="Predicciones ML por dataset")
def get_ml_predictions(
    name: str,
    student_id: Optional[str] = Query(None, description="Filtrar por student_id"),
    risk_level: Optional[str] = Query(None, description="Filtrar por nivel de riesgo"),
    page: int = Query(1, ge=1),
    page_size: int = Query(50, ge=1, le=500),
    _: UsuarioAdmin = Depends(get_current_admin),
):
    if name not in ML_DATASETS:
        raise HTTPException(
            status_code=404,
            detail=f"Dataset '{name}' no encontrado. Disponibles: {list(ML_DATASETS.keys())}",
        )
    df = pd.read_csv(DATASETS_DIR / ML_DATASETS[name])
    if student_id:
        df = df[df["student_id"] == student_id]
    if risk_level and "risk_level" in df.columns:
        df = df[df["risk_level"].str.lower() == risk_level.lower()]
    return _paginate(df, page, page_size)


# ── Per-student aggregation ──────────────────────────────────────────────────────

@router.get("/students/{student_id}", summary="Todas las predicciones para un estudiante")
def get_student_predictions(
    student_id: str,
    _: UsuarioAdmin = Depends(get_current_admin),
):
    result: dict = {"student_id": student_id}
    all_datasets = {**NLP_DATASETS, **ML_DATASETS}
    for key, filename in all_datasets.items():
        path = DATASETS_DIR / filename
        try:
            df = pd.read_csv(path)
            rows = df[df["student_id"] == student_id]
            result[key] = rows.fillna("").to_dict(orient="records")
        except Exception:
            result[key] = []
    return result
