"""
Technical Debt Heatmap — surfaces the most dangerous areas of the codebase.

Formula:
  debt_score = commit_frequency * dependents_count

Logic:
  - High commit_frequency → the file changes often (instability)
  - High dependents_count → many modules rely on it (blast radius)
  - Together they signal: "this changes a lot AND breaking it is catastrophic"

Risk levels (debt_score):
  0       → NONE
  1–9     → LOW
  10–29   → MEDIUM
  30–59   → HIGH
  60+     → CRITICAL
"""

from __future__ import annotations

from dataclasses import dataclass
from pathlib import Path

from ..memory.store import KodaraIndex


@dataclass
class DebtItem:
    file: str                   # absolute path
    module_name: str            # stem name
    commit_count: int           # total commits (proxy for churn)
    dependents_count: int       # how many modules depend on this file
    debt_score: int             # commit_count * dependents_count
    risk_level: str             # NONE / LOW / MEDIUM / HIGH / CRITICAL


def _risk_level(debt_score: int) -> str:
    if debt_score >= 60:
        return "CRITICAL"
    if debt_score >= 30:
        return "HIGH"
    if debt_score >= 10:
        return "MEDIUM"
    if debt_score >= 1:
        return "LOW"
    return "NONE"


def get_debt(index: KodaraIndex, top_n: int = 15) -> list[DebtItem]:
    """
    Compute a technical debt heatmap for the indexed project.

    Returns the top_n highest debt_score items, sorted descending.
    Empty index → empty list.
    """
    if not index.modules:
        return []

    items: list[DebtItem] = []

    for path, mod in index.modules.items():
        git = mod.get("git", {})
        commit_count = git.get("commit_count", 0)
        dep_list = mod.get("dependents", [])
        dependents_count = len(dep_list)

        debt_score = commit_count * dependents_count
        level = _risk_level(debt_score)

        items.append(DebtItem(
            file=path,
            module_name=mod.get("module_name", Path(path).stem),
            commit_count=commit_count,
            dependents_count=dependents_count,
            debt_score=debt_score,
            risk_level=level,
        ))

    # Sort by debt_score descending
    items.sort(key=lambda d: -d.debt_score)

    return items[:top_n]
