"""학습 패턴 분류 (Phase 1).

attempts 시간 순 리스트 → pattern_state 7 분류:
  unattempted / unsure / chronic_wrong / regressed / recovered / stable / unstable

윈도우 = 최근 3회 attempts + 과거 correct/wrong 존재 여부.
recent3 만으로는 regressed/recovered 판정 불가능 — 과거 이력 함께 필요.

우선순위 (위→아래, 첫 매칭 박힘):
  1. unattempted (attempts == 0)
  2. unsure (latest == 'unsure')
  3. chronic_wrong (recent3 wrong ≥ 2)
  4. regressed (latest wrong + 이전 correct 이력)
  5. recovered (latest 2 연속 correct + 이전 wrong 이력)
  6. stable (recent3 모두 correct, 3회 충족)
  7. unstable (그 외)

UI 라벨 (가칭):
  unattempted="미학습" / unsure="모르겠음" / chronic_wrong="반복 오답 경향"
  regressed="퇴행" / recovered="회복" / stable="안정" / unstable="불안정"

chronic_wrong 은 [wrong,wrong,correct] 같이 latest correct 케이스도 잡힘.
"지금 틀림" 의미 X, "최근 3회 오답 비중 높음" 의미 — UI 라벨 주의.
"""

from __future__ import annotations

from dataclasses import dataclass

PATTERN_UNATTEMPTED = "unattempted"
PATTERN_UNSURE = "unsure"
PATTERN_CHRONIC_WRONG = "chronic_wrong"
PATTERN_REGRESSED = "regressed"
PATTERN_RECOVERED = "recovered"
PATTERN_STABLE = "stable"
PATTERN_UNSTABLE = "unstable"

WINDOW_SIZE = 3


@dataclass
class _AttemptOutcome:
    """compute_pattern_state 입력용 가벼운 dataclass. 시간 순 (oldest → newest)."""
    outcome: str  # correct / wrong / unsure / skipped


def compute_pattern_state(attempts: list[_AttemptOutcome]) -> tuple[str, int]:
    """attempts (oldest → newest) → (pattern_state, window_size).

    window_size = min(WINDOW_SIZE, len(attempts)).
    """
    if not attempts:
        return PATTERN_UNATTEMPTED, 0

    latest = attempts[-1].outcome
    if latest == "unsure":
        return PATTERN_UNSURE, min(WINDOW_SIZE, len(attempts))

    recent_window = attempts[-WINDOW_SIZE:]
    wrong_in_window = sum(1 for a in recent_window if a.outcome == "wrong")

    # chronic_wrong: 최근 3회 중 wrong ≥ 2 (또는 attempts 가 2회뿐이고 둘 다 wrong)
    if wrong_in_window >= 2:
        return PATTERN_CHRONIC_WRONG, len(recent_window)

    # regressed: latest wrong + 이전 correct 이력 1건 이상
    if latest == "wrong" and any(a.outcome == "correct" for a in attempts[:-1]):
        return PATTERN_REGRESSED, len(recent_window)

    # recovered: latest 2 연속 correct + 그 이전 wrong 이력
    if (
        len(attempts) >= 3
        and attempts[-1].outcome == "correct"
        and attempts[-2].outcome == "correct"
        and any(a.outcome == "wrong" for a in attempts[:-2])
    ):
        return PATTERN_RECOVERED, len(recent_window)

    # stable: 최근 3회 모두 correct (3회 충족)
    if len(recent_window) >= WINDOW_SIZE and all(a.outcome == "correct" for a in recent_window):
        return PATTERN_STABLE, WINDOW_SIZE

    # 그 외: unstable (1~2회 correct, wrong 1회 + correct 이력 없음, 등)
    return PATTERN_UNSTABLE, len(recent_window)


def attempts_from_rows(rows) -> list[_AttemptOutcome]:
    """SQL row (outcome 컬럼) → _AttemptOutcome 리스트. 호출자가 정렬은 미리.

    rows 는 oldest → newest 정렬되어 들어와야 함 (answered_at asc).
    """
    return [_AttemptOutcome(outcome=r.outcome) for r in rows]
