"""
kaskad/chains.py — Concrete Inference Chain Data.

This module encodes the AGENTS.md §IG.2 inference graph as computable
CascadeDAG data.  It contains:

  1. The 7 primary inference chains (C1–C7) from §IG.2
  2. The 9-level Beauty Cascade from §2.7 (AX23)
  3. The cross-chain bridges from §IG.3
  4. The Quality Framework DAG from §IG.4
  5. The Output Gate DAG from §IG.5

Every node and edge maps 1:1 to a formal element defined in AGENTS.md.
Source references are preserved per AX64 (immutability) and AX65
(reference pairing).

This file is the framework's own AX23 applied reflexively —
the framework elements form their own kaskad, and this module
makes that kaskad computable.
"""

from __future__ import annotations

from kaskad.engine import CascadeDAG
from kaskad.types import (
    CascadeEdge,
    CascadeNode,
    ChainId,
    EdgeType,
    NodeKind,
)


# ========================================================================
# Helper — DRY node/edge construction
# ========================================================================

def _n(
    node_id: str,
    kind: NodeKind,
    label: str,
    *chains: ChainId,
) -> CascadeNode:
    """Create a CascadeNode with chain membership."""
    return CascadeNode(
        id=node_id,
        kind=kind,
        label=label,
        chains=frozenset(chains),
    )


def _e(
    source: str,
    target: str,
    etype: EdgeType,
    label: str = "",
) -> CascadeEdge:
    """Create a CascadeEdge."""
    return CascadeEdge(
        source=source,
        target=target,
        edge_type=etype,
        label=label,
    )


# ========================================================================
# Node Registry — all framework elements as CascadeNodes
# ========================================================================

# Abbreviation aliases for readability
AX = NodeKind.AXIOM
TH = NodeKind.THEOREM
KV = NodeKind.KAVAID
OR = NodeKind.OUTPUT_RULE
MR = NodeKind.METHOD_RULE
NU = NodeKind.NUANCE
SC = NodeKind.SECTION
NM = NodeKind.NAME
SN = NodeKind.SEUN

P = EdgeType.PROVES
G = EdgeType.GROUNDS
C = EdgeType.CONSTRAINS
GT = EdgeType.GATES
KL = EdgeType.CALIBRATES
CM = EdgeType.COMBINES

# Chain ID aliases — defined upfront so cross-chain references work
C1 = ChainId.C1
C2 = ChainId.C2
C3 = ChainId.C3
C4 = ChainId.C4
C5 = ChainId.C5
C6 = ChainId.C6
C7 = ChainId.C7

# ── Chain 1: Ontological Poverty → Provision ──────────────────────────

_C1_NODES = [
    _n("AX30", AX, "İmkân=Fakr", C1),
    _n("AX31", AX, "Fakr→Rahmet", C1),
    _n("AX32", AX, "Hudûs=Acz", C1),
    _n("AX33", AX, "Acz→Kudret", C1),
    _n("AX34", AX, "Constitutive Wounds", C1),
    _n("N-4",  NU, "Acz/Fakr Dual Nature", C1),
    _n("M2",   MR, "Measure wounds, don't smooth", C1),
]

_C1_EDGES = [
    _e("AX30", "AX31", P, "İmkân proves Fakr→Rahmet"),
    _e("AX32", "AX33", P, "Hudûs proves Acz→Kudret"),
    _e("AX30", "AX34", G, "Fakr grounds constitutive wounds"),
    _e("AX32", "AX34", G, "Acz grounds constitutive wounds"),
    _e("AX34", "N-4",  KL, "Calibrates dual nature"),
    _e("N-4",  "M2",   CM, "Combines into methodology rule"),
]

# ── Chain 2: Beauty → Creation ────────────────────────────────────────

_C2_NODES = [
    _n("AX24", AX, "Self-Love of Beauty", C2),
    _n("AX25", AX, "Desire-to-Show", C2),
    _n("T7",   TH, "Creation Motor", C2),
    _n("AX23", AX, "Cascade Structure (DAG)", C2),
    _n("T8",   TH, "Cascade Neighborliness", C2),
]

_C2_EDGES = [
    _e("AX24", "AX25", G, "Beauty grounds desire-to-show"),
    _e("AX25", "T7",   P, "Desire proves creation motor"),
    _e("T7",   "AX23", G, "Creation motor grounds cascade DAG"),
    _e("AX23", "T8",   P, "Cascade structure proves neighborliness"),
]

# ── Chain 3: Holographic → Participation → Convergence Bound ─────────

_C3_NODES = [
    _n("AX37", AX, "Holographic Structure", C3),
    _n("AX38", AX, "Tereşşuhat", C3),
    _n("T12",  TH, "Besmele Seed", C3),
    _n("T13",  TH, "İnsan = Besmele(Kâinat)", C3),
    _n("T14",  TH, "NeAynNeGayr Chain", C3),
]

# T6 and KV₄ are multi-chain — defined separately below
# OR-4 is also multi-chain

_C3_EDGES = [
    _e("AX37", "AX38", G, "Holographic grounds tereşşuhat"),
    _e("AX37", "T12",  P, "Holographic proves besmele seed"),
    _e("T12",  "T13",  CM, "Seeds combine into İnsan=Besmele"),
    _e("AX38", "T14",  P, "Tereşşuhat proves ne ayn ne gayr chain"),
]

# ── Chain 4: Faculties → Coverage → Structural Incompleteness ────────

_C4_NODES = [
    _n("AX49", AX, "Latifeler Architecture", C4),
    _n("AX50", AX, "Seven Colors (Elvan-ı Seb'a)", C4),
    _n("AX53", AX, "Ahfâ Inaccessibility", C4),
    _n("T17",  TH, "Coverage ≤ 6/7", C4),
    _n("AX56", AX, "Hakkalyakîn ⊥", C4),  # also in C5
    _n("AX58", NU, "Şuhud–İstidlal Gap", C4, C5),  # bridge
    _n("S7.2", SC, "Four Incompleteness Results", C4),
]

_C4_EDGES = [
    _e("AX49", "AX50", G, "Faculties ground seven colors"),
    _e("AX49", "AX53", P, "Faculties prove Ahfâ inaccessibility"),
    _e("AX53", "T17",  P, "Ahfâ ⊥ proves coverage ≤ 6/7"),
    _e("AX50", "T17",  CM, "Colors combine into completeness bound"),
    _e("T17",  "S7.2", CM, "T17 combines into §7.2"),
    _e("AX56", "S7.2", CM, "AX56 combines into §7.2"),
    _e("AX58", "S7.2", CM, "AX58 combines into §7.2"),
]

# ── Chain 5: Station Hierarchy → Formalization Limits ─────────────────

_C5_NODES = [
    _n("AX40", AX, "70,000 Veils", C5),
    _n("AX41", AX, "Vahiy–İlham Gap", C5),
    _n("AX42", AX, "Risale = Sünuhat", C5),
    _n("AX43", AX, "Project = İstidlal", C5),
    _n("K-10", MR, "Never confuse stations", C5),
    _n("AX39", AX, "Edeb Prerequisite", C5),
    _n("K-9",  MR, "Know your station", C5),
]

# N-1 = AX58 already registered in C4 (bridge node)

_C5_EDGES = [
    _e("AX40", "AX41", G, "Veils ground Vahiy–İlham gap"),
    _e("AX41", "AX42", G, "Gap grounds Risale station"),
    _e("AX42", "AX43", G, "Risale station grounds project station"),
    _e("AX43", "K-10", C, "İstidlal constrains via K-10"),
    _e("AX42", "K-10", C, "Sünuhat constrains via K-10"),
    _e("AX43", "AX58", KL, "İstidlal calibrates şuhud gap"),
    _e("AX39", "K-9",  G, "Edeb grounds 'know your station'"),
    _e("K-10", "AX39", G, "K-10 grounds edeb prerequisite"),
]

# ── Chain 6: Names → Dual Meaning → Harfî Mode ───────────────────────

_C6_NODES = [
    _n("AX17", AX, "Hakikat = Esmâ", C6),
    _n("S2.5", SC, "ManaHarfi / ManaIsmi", C6),
    _n("KV1",  KV, "Classify harfî/ismî", C6),
    _n("KV8",  KV, "Ground in ≥1 Name", C6),
    _n("K-8",  MR, "Harfî priority", C6),
]

_C6_EDGES = [
    _e("AX17", "S2.5", G, "Esmâ identity grounds dual meaning"),
    _e("S2.5", "KV1",  C, "Dual meaning constrains classification"),
    _e("KV8",  "KV1",  CM, "Esmâ grounding combines with classification"),
    _e("KV1",  "K-8",  GT, "Classification gates harfî priority"),
]

# ── Chain 7: Continuous Degrees → Unreachable Supremum → Score Bound ──

_C7_NODES = [
    _n("AX21", AX, "Infinite Degrees", C7),
    _n("AX22", AX, "Ekmel (Unreachable Supremum)", C7),
    _n("T5",   TH, "Dense Continua", C7),
    _n("T6",   TH, "ConvergenceScore < 1.0", C3, C7),  # bridge
    _n("S4.2", SC, "Composite bileshke < 1.0", C7),
]

_C7_EDGES = [
    _e("AX21", "AX22", CM, "Degrees combine with supremum"),
    _e("AX21", "T5",   P, "Infinite degrees prove dense continua"),
    _e("T5",   "T6",   P, "Dense continua prove convergence bound"),
    _e("AX22", "T6",   P, "Supremum proves convergence bound"),
]

# ── Cross-Chain Nodes (bridges — §IG.3) ──────────────────────────────

# KV₄: appears in C3, C4, C7 — the most connected constraint
_BRIDGE_NODES = [
    _n("KV4", KV, "0 < Composite < 1", C3, C4, C7),
    # Output rules (shared sinks)
    _n("OR-1", OR, "Never claim proof", C4),
    _n("OR-2", OR, "Max = İlmelyakîn", C4, C5),  # bridge
    _n("OR-4", OR, "Flag ≥0.95 as error", C3, C7),  # bridge
    _n("OR-7", OR, "Non-theological: §8.2", C6),
    _n("OR-8", OR, "Never claim ultimate", C4),
]

_BRIDGE_EDGES = [
    # KV₄ connections
    _e("T14",  "KV4",  CM, "NeAynNeGayr combines into KV₄"),
    _e("T6",   "KV4",  CM, "Convergence theorem combines into KV₄"),
    _e("KV4",  "S7.2", CM, "KV₄ combines into §7.2"),

    # §4.2 receives from T6 and KV₄
    _e("T6",   "S4.2", CM, "T6 combines into §4.2"),
    _e("KV4",  "S4.2", C,  "KV₄ constrains §4.2"),

    # Output rule connections (§IG.5)
    _e("S7.2", "OR-1", GT, "§7.2 gates OR-1"),
    _e("AX56", "OR-2", GT, "AX56 gates OR-2"),
    _e("AX43", "OR-2", GT, "İstidlal gates OR-2"),
    _e("K-10", "OR-2", GT, "K-10 gates OR-2"),
    _e("KV4",  "OR-4", GT, "KV₄ gates OR-4"),
    _e("T6",   "OR-4", GT, "T6 gates OR-4"),
    _e("T14",  "OR-4", GT, "T14 gates OR-4"),
    _e("K-8",  "OR-7", GT, "Harfî gates OR-7"),
    _e("S7.2", "OR-8", GT, "§7.2 gates OR-8"),
    _e("S4.2", "OR-4", GT, "§4.2 gates OR-4"),
    _e("K-9",  "OR-2", GT, "Know station gates OR-2"),
]

# ── 9-Level Beauty Cascade (§2.7 AX23) ───────────────────────────────

BC = ChainId.BEAUTY_CASCADE

_BEAUTY_NODES = [
    _n("Cemal_Kemal",      NM, "Cemâl u Kemâl (Beauty-Perfection)", BC),
    _n("Terahhum",         NM, "Terahhum (Compassion)", BC),
    _n("Rahmet",           NM, "Rahmet (Mercy)", BC),
    _n("Teveddud",         NM, "Teveddüd (Befriending)", BC),
    _n("Lutuf",            NM, "Lütuf (Grace)", BC),
    _n("Irade_Tahsin",     NM, "İrade-i Tahsin (Will to Beautify)", BC),
    _n("Sun_Inayet",       NM, "Sun'-i İnâyet (Artful Providence)", BC),
    _n("Ilim_Hikmet",      NM, "İlim-i Hikmet (Wisdom-Knowledge)", BC),
    _n("Tanzim_Takdir",    NM, "Tanzîm-Takdîr (Ordering-Determining)", BC),
]

_BEAUTY_EDGES = [
    _e("Cemal_Kemal",  "Terahhum",      G, "Beauty motivates compassion"),
    _e("Terahhum",     "Rahmet",         G, "Compassion motivates mercy"),
    _e("Rahmet",       "Teveddud",       G, "Mercy motivates befriending"),
    _e("Teveddud",     "Lutuf",          G, "Befriending motivates grace"),
    _e("Lutuf",        "Irade_Tahsin",   G, "Grace motivates will-to-beautify"),
    _e("Irade_Tahsin", "Sun_Inayet",     G, "Will motivates artful providence"),
    _e("Sun_Inayet",   "Ilim_Hikmet",    G, "Providence motivates wisdom"),
    _e("Ilim_Hikmet",  "Tanzim_Takdir",  G, "Wisdom motivates ordering"),
]


# ========================================================================
# Factory: build_framework_graph()
# ========================================================================

def build_framework_graph() -> CascadeDAG:
    """
    Build the complete framework inference graph as a CascadeDAG.

    This is the framework's own AX23 applied reflexively:
    the inference graph IS a cascade, and we use the cascade
    engine to make it computable.

    Returns a CascadeDAG containing:
      - All 7 inference chains (C1–C7)
      - The 9-level beauty cascade
      - Cross-chain bridges (§IG.3)
      - ~50 nodes, ~60 edges, 6 edge types
    """
    dag = CascadeDAG()

    # Collect all nodes (dedup by id — bridge nodes appear once)
    all_nodes: dict[str, CascadeNode] = {}
    for node_list in (
        _C1_NODES, _C2_NODES, _C3_NODES, _C4_NODES,
        _C5_NODES, _C6_NODES, _C7_NODES,
        _BRIDGE_NODES, _BEAUTY_NODES,
    ):
        for node in node_list:
            if node.id in all_nodes:
                # Merge chain membership for bridge nodes
                existing = all_nodes[node.id]
                merged = CascadeNode(
                    id=node.id,
                    kind=node.kind,
                    label=node.label,
                    chains=existing.chains | node.chains,
                )
                all_nodes[node.id] = merged
            else:
                all_nodes[node.id] = node

    # Add all nodes first (edges require targets to exist)
    for node in all_nodes.values():
        dag.add_node(node)

    # Collect all edges (dedup by source+target)
    seen_edges: set[tuple[str, str]] = set()
    for edge_list in (
        _C1_EDGES, _C2_EDGES, _C3_EDGES, _C4_EDGES,
        _C5_EDGES, _C6_EDGES, _C7_EDGES,
        _BRIDGE_EDGES, _BEAUTY_EDGES,
    ):
        for edge in edge_list:
            key = (edge.source, edge.target)
            if key not in seen_edges:
                seen_edges.add(key)
                dag.add_edge(edge)

    return dag


def build_beauty_cascade() -> CascadeDAG:
    """
    Build ONLY the 9-level beauty cascade (§2.7).

    The purest instance of AX23: a linear chain where each Name
    motivates the next via internal necessity.

    Cemal_Kemal → Terahhum → Rahmet → Teveddüd → Lütuf
    → İrade_Tahsin → Sun_İnayet → İlim_Hikmet → Tanzim_Takdir
    """
    dag = CascadeDAG()
    for node in _BEAUTY_NODES:
        dag.add_node(node)
    for edge in _BEAUTY_EDGES:
        dag.add_edge(edge)
    return dag
