"""In-memory fallback for spaced retrieval (no DB available).

Separated from spaced_retrieval.py for SoC compliance.
"""
from __future__ import annotations
import time
from ._fsrs_math import (
    _FSRS_INITIAL_STAB, _FSRS_INITIAL_DIFF,
    _GRADE_SUCCESS, _GRADE_FAILURE,
    _retrievability, _next_interval,
    _stability_recall, _stability_lapse, _difficulty_update,
)

_MEM_SCHEDULE: dict = {}


def _schedule_item_in_memory(item_id: str, item_type: str) -> dict:
    now_ts = time.time()
    record = {
        "item_id": item_id, "item_type": item_type,
        "interval_hours": _FSRS_INITIAL_STAB,
        "ef": 2.5,
        "difficulty": _FSRS_INITIAL_DIFF,
        "next_review_ts": now_ts + _FSRS_INITIAL_STAB * 3600,
        "last_reviewed_ts": None,
        "review_count": 0,
    }
    _MEM_SCHEDULE[item_id] = record
    return record


def _mark_recalled_in_memory(item_id: str, success: bool) -> dict:
    record = _MEM_SCHEDULE.get(item_id) or _schedule_item_in_memory(item_id, "lesson")
    now_ts     = time.time()
    stability  = record["interval_hours"]
    difficulty = record.get("difficulty", _FSRS_INITIAL_DIFF)
    last_ts    = record.get("last_reviewed_ts") or (now_ts - stability * 3600)
    elapsed    = max(0.0, (now_ts - last_ts) / 3600.0)
    R          = _retrievability(elapsed, stability)
    grade      = _GRADE_SUCCESS if success else _GRADE_FAILURE
    new_stab   = _stability_recall(stability, difficulty, R) if success else _stability_lapse(stability, difficulty)
    new_diff   = _difficulty_update(difficulty, grade)
    new_ivl    = _next_interval(new_stab)
    record.update({
        "interval_hours": new_stab, "difficulty": new_diff,
        "next_review_ts": now_ts + new_ivl * 3600,
        "last_reviewed_ts": now_ts,
        "review_count": record["review_count"] + 1,
    })
    _MEM_SCHEDULE[item_id] = record
    return record
