
import logging
from typing import Any, Dict, List

from app.agent.router import PERSONAL_FIELDS

logger = logging.getLogger(__name__)


# #local_fallback_student_data

_MOCK_STUDENTS: Dict[str, Dict[str, Any]] = {
    # keyed by student_id; "default" is used when an id is unknown
    "default": {
        "name": "Maya Johnson",
        "grades": [
            {"course": "College Algebra (MATH 1314)", "grade": "C-", "trend": "slipping"},
            {"course": "English Composition (ENGL 1301)", "grade": "B", "trend": "steady"},
            {"course": "Intro to Biology (BIOL 1306)", "grade": "C", "trend": "slipping"},
            {"course": "US History (HIST 1301)", "grade": "B+", "trend": "steady"},
        ],
        "gpa": {"overall": 2.7, "current_term": 2.4, "trend": "declining"},
        "credits": {"earned": 36, "pending": 12, "required_for_degree": 60},
        "financial_aid": {
            "fafsa_status": "Verification item pending",
            "award": "$3,200 Pell Grant (estimated)",
            "hold_on_aid": True,
            "note": "One document due Friday to release aid.",
        },
        "holds": [
            {"type": "Financial aid document", "status": "pending", "due": "Friday"},
        ],
        "deadlines": [
            {"item": "Fall 2026 registration", "date": "2026-05-16"},
            {"item": "FAFSA verification item", "date": "2026-05-23"},
            {"item": "Tuition payment", "date": "2026-06-01"},
        ],
        "attendance": {"missed_classes_last_30d": 4, "flag": "attendance concern in Biology"},
    },
}


def _load_student_record(student_id: str) -> Dict[str, Any]:
    """
    Load student data from local fallback.
    
    This loads from the local fallback data structure.
    In production, replace with read-only fetch from the warehouse (SQLAlchemy SELECT)
    or app.student_api, returning a dict with the same keys as the local data.
    """
    rec = _MOCK_STUDENTS.get(student_id)
    if rec is None:
        logger.debug("personal_data: id '%s' not in fallback set — using 'default'.", student_id)
        rec = _MOCK_STUDENTS["default"]
    return rec


def get_personal_data(student_id: str, fields: List[str]) -> Dict[str, Any]:
    """
    Return ONLY the requested personal-data fields for the given (logged-in)
    student.

    Parameters
    ----------
    student_id : the AUTHENTICATED student's id (from the session, never chat)
    fields     : list of field names (subset of PERSONAL_FIELDS)

    Returns
    -------
    dict containing just the requested fields, e.g.
        {"gpa": {...}, "grades": [...]}
    Unknown field names are ignored. Never raises.
    """
    if not student_id:
        logger.warning("get_personal_data called without a student_id — refusing.")
        return {}

    record = _load_student_record(student_id)
    wanted = [f for f in (fields or []) if f in PERSONAL_FIELDS]
    if not wanted:
        return {}

    out: Dict[str, Any] = {}
    for f in wanted:
        if f in record:
            out[f] = record[f]
    return out


def format_personal_data(data: Dict[str, Any]) -> str:
    """
    Turn the personal-data dict into a plain-text block the LLM can read and
    blend into its answer. Returns a friendly 'none' note if empty.
    """
    if not data:
        return "No personal data was retrieved for this question."

    lines: List[str] = []

    if "gpa" in data:
        g = data["gpa"]
        lines.append(
            f"GPA — overall {g.get('overall')}, current term {g.get('current_term')} "
            f"(trend: {g.get('trend')})."
        )
    if "grades" in data:
        lines.append("Current grades:")
        for c in data["grades"]:
            lines.append(f"  - {c.get('course')}: {c.get('grade')} ({c.get('trend')})")
    if "credits" in data:
        c = data["credits"]
        lines.append(
            f"Credits — {c.get('earned')} earned, {c.get('pending')} pending, "
            f"{c.get('required_for_degree')} required for degree."
        )
    if "financial_aid" in data:
        fa = data["financial_aid"]
        lines.append(
            f"Financial aid — FAFSA: {fa.get('fafsa_status')}; award: {fa.get('award')}; "
            f"hold on aid: {'yes' if fa.get('hold_on_aid') else 'no'}. {fa.get('note', '')}".strip()
        )
    if "holds" in data:
        if data["holds"]:
            lines.append("Holds:")
            for h in data["holds"]:
                lines.append(f"  - {h.get('type')} ({h.get('status')}, due {h.get('due')})")
        else:
            lines.append("Holds: none.")
    if "deadlines" in data:
        lines.append("Upcoming personal deadlines:")
        for d in data["deadlines"]:
            lines.append(f"  - {d.get('item')}: {d.get('date')}")
    if "attendance" in data:
        a = data["attendance"]
        lines.append(
            f"Attendance — {a.get('missed_classes_last_30d')} missed in last 30 days "
            f"({a.get('flag')})."
        )

    return "\n".join(lines)