from __future__ import annotations

from dataclasses import dataclass
from typing import Any, Literal, TypedDict


class EvidenceImport(TypedDict, total=False):
    from_path: str
    to_path: str
    import_ref: dict[str, Any]


class ModuleMetrics(TypedDict, total=False):
    file_count: int
    total_size_bytes: int
    fan_in: int
    fan_out: int
    fan_in_weight: int
    fan_out_weight: int
    is_shared_candidate: bool


class PublicInterface(TypedDict, total=False):
    symbol_id: str
    qualname: str
    name: str
    signature: str
    path: str
    span: dict[str, int]
    evidence: str


class Module(TypedDict, total=False):
    module_id: str
    name: str
    paths: list[str]
    files: list[str]
    purpose: str
    summary: str
    public_interfaces: list[PublicInterface]
    metrics: ModuleMetrics
    error: str


class ModuleEdge(TypedDict, total=False):
    from_module: str
    to_module: str
    kind: Literal["imports"]
    weight: int
    evidence: list[EvidenceImport]


class FanInOut(TypedDict, total=False):
    module_id: str
    fan_in: int
    fan_out: int
    fan_in_weight: int
    fan_out_weight: int


class SCC(TypedDict, total=False):
    scc_id: int
    modules: list[str]
    size: int


class Hotspot(TypedDict, total=False):
    kind: Literal["large_file", "high_fan_in", "high_fan_out", "high_degree"]
    path: str
    module_id: str
    score: float
    details: dict[str, Any]


class ArchitectureMetrics(TypedDict, total=False):
    sccs: list[SCC]
    fan_in_out: list[FanInOut]
    hotspots: list[Hotspot]


class SuggestedFlow(TypedDict, total=False):
    name: str
    modules: list[str]
    evidence_edges: list[dict[str, Any]]


class ArchitectureMap(TypedDict, total=False):
    meta: dict[str, Any]
    modules: list[Module]
    edges: list[ModuleEdge]
    metrics: ArchitectureMetrics
    suggested_flows: list[SuggestedFlow]


@dataclass(frozen=True)
class ModuleRecord:
    module_id: str
    name: str
    files: list[str]
    paths: list[str]

