"""
Progress API — Tracks student learning progress per unit.

Stores coins, crowns, streak data, and exercise completion stats.
Uses JSON file storage (same pattern as learning_units.py).
"""

import os
import json
import logging
from datetime import datetime, date
from typing import Dict, Any, Optional, List
from pathlib import Path

from fastapi import APIRouter, HTTPException
from pydantic import BaseModel

logger = logging.getLogger(__name__)

router = APIRouter(
    prefix="/progress",
    tags=["progress"],
)

PROGRESS_DIR = os.path.expanduser("~/Arbeitsblaetter/Lerneinheiten/progress")


def _ensure_dir():
    os.makedirs(PROGRESS_DIR, exist_ok=True)


def _progress_path(unit_id: str) -> Path:
    return Path(PROGRESS_DIR) / f"{unit_id}.json"


def _load_progress(unit_id: str) -> Dict[str, Any]:
    path = _progress_path(unit_id)
    if path.exists():
        with open(path, "r", encoding="utf-8") as f:
            return json.load(f)
    return {
        "unit_id": unit_id,
        "coins": 0,
        "crowns": 0,
        "streak_days": 0,
        "last_activity": None,
        "exercises": {
            "flashcards": {"completed": 0, "correct": 0, "incorrect": 0},
            "quiz": {"completed": 0, "correct": 0, "incorrect": 0},
            "type": {"completed": 0, "correct": 0, "incorrect": 0},
            "story": {"generated": 0},
        },
        "created_at": datetime.now().isoformat(),
    }


def _save_progress(unit_id: str, data: Dict[str, Any]):
    _ensure_dir()
    path = _progress_path(unit_id)
    with open(path, "w", encoding="utf-8") as f:
        json.dump(data, f, ensure_ascii=False, indent=2)


class RewardPayload(BaseModel):
    exercise_type: str  # flashcards, quiz, type, story
    correct: bool = True
    first_try: bool = True


@router.get("/{unit_id}")
def get_progress(unit_id: str):
    """Get learning progress for a unit."""
    return _load_progress(unit_id)


@router.post("/{unit_id}/reward")
def add_reward(unit_id: str, payload: RewardPayload):
    """Record an exercise result and award coins."""
    progress = _load_progress(unit_id)

    # Update exercise stats
    ex = progress["exercises"].get(payload.exercise_type, {"completed": 0, "correct": 0, "incorrect": 0})
    ex["completed"] = ex.get("completed", 0) + 1
    if payload.correct:
        ex["correct"] = ex.get("correct", 0) + 1
    else:
        ex["incorrect"] = ex.get("incorrect", 0) + 1
    progress["exercises"][payload.exercise_type] = ex

    # Award coins
    if payload.correct:
        coins = 3 if payload.first_try else 1
    else:
        coins = 0
    progress["coins"] = progress.get("coins", 0) + coins

    # Update streak
    today = date.today().isoformat()
    last = progress.get("last_activity")
    if last != today:
        if last == (date.today().replace(day=date.today().day - 1)).isoformat() if date.today().day > 1 else None:
            progress["streak_days"] = progress.get("streak_days", 0) + 1
        elif last != today:
            progress["streak_days"] = 1
        progress["last_activity"] = today

    # Award crowns for milestones
    total_correct = sum(
        e.get("correct", 0) for e in progress["exercises"].values() if isinstance(e, dict)
    )
    progress["crowns"] = total_correct // 20  # 1 crown per 20 correct answers

    _save_progress(unit_id, progress)

    return {
        "coins_awarded": coins,
        "total_coins": progress["coins"],
        "crowns": progress["crowns"],
        "streak_days": progress["streak_days"],
    }


@router.get("/")
def list_all_progress():
    """List progress for all units."""
    _ensure_dir()
    results = []
    for f in Path(PROGRESS_DIR).glob("*.json"):
        with open(f, "r", encoding="utf-8") as fh:
            results.append(json.load(fh))
    return results
