"""
Perfect Cuboid — Epistemic Grading
===================================

Formal epistemic assessment applying Layer 3 (AGENTS.md §3.1–§3.4):

  AX43: Our analysis = İstidlal (rational inference)
  AX44/T15: Structural claims >> detail claims
  AX48: Target = İlmelyakîn (demonstrative certainty)
  AX56: Max grade = İlmelyakîn; Hakkalyakîn inaccessible
  T16: Single-faculty limitation — multi-lens required
"""

from __future__ import annotations

from dataclasses import dataclass
from enum import Enum
from typing import Optional


class EpistemicGrade(Enum):
    """AX56 — Epistemic degree scale.

    Hakkalyakîn is permanently inaccessible to formal instruments.
    """
    TASAVVUR = "tasavvur"       # Conceptual grasp
    TASDIK = "tasdik"           # Affirmative judgment
    ILMELYAKIN = "ilmelyakin"   # Demonstrative certainty (MAX)
    # HAKKALYAKIN is explicitly NOT defined — it is inaccessible (AX56)


class ClaimType(Enum):
    """AX44 — Külliyat vs Tafsîlât."""
    KULLIYAT = "kulliyat"       # Structural/universal claim
    TAFLISAAT = "taflisaat"     # Detail-level claim


@dataclass
class GradedClaim:
    """A claim with epistemic grading metadata.

    AX57: Every claim must disclose its grade, type, and evidence basis.
    """
    statement: str
    grade: EpistemicGrade
    claim_type: ClaimType
    evidence_basis: str
    confidence: float           # 0 < confidence < 1 (KV₄)
    lenses_used: list[str]      # Which analytical lenses contribute
    lenses_missing: list[str]   # AX57 transparency — what's NOT covered
    caveats: list[str]          # Structural limitations

    def is_valid(self) -> bool:
        """KV₄ + AX56: confidence < 1.0 and grade ≤ İlmelyakîn."""
        return (0 < self.confidence < 1.0 and
                self.grade != EpistemicGrade.ILMELYAKIN or
                self.grade in (EpistemicGrade.TASAVVUR,
                               EpistemicGrade.TASDIK,
                               EpistemicGrade.ILMELYAKIN))


def grade_cuboid_claims() -> list[GradedClaim]:
    """Grade all claims we can make about the Perfect Cuboid Problem.

    Applies T15: structural claims are graded higher than detail claims.
    Applies AX57: full transparency about what's covered and what's not.
    """
    claims = []

    # ---------- Structural Claims (Külliyat) — higher confidence ----------

    claims.append(GradedClaim(
        statement=(
            "The 4-equation system exhibits a convergent cascade structure: "
            "each equation constrains the next, and the space diagonal "
            "constraint is the hardest to satisfy simultaneously."
        ),
        grade=EpistemicGrade.ILMELYAKIN,
        claim_type=ClaimType.KULLIYAT,
        evidence_basis="AX23 cascade analysis + computational verification",
        confidence=0.92,
        lenses_used=["FOL", "Bayes", "Topoloji"],
        lenses_missing=["OyunTeorisi", "KategoriTeorisi"],
        caveats=["Structural claim — does not prove non-existence"],
    ))

    claims.append(GradedClaim(
        statement=(
            "Euler bricks (3/4 equations satisfied) form a discrete infinite "
            "family, demonstrating that the 'constitutive wound' (AX34) — "
            "the space diagonal gap — is a structural interface, not random."
        ),
        grade=EpistemicGrade.ILMELYAKIN,
        claim_type=ClaimType.KULLIYAT,
        evidence_basis="Euler brick existence proofs + computational search",
        confidence=0.95,  # note: at boundary — flag per KV₄
        lenses_used=["FOL", "Ontoloji", "Mereoloji"],
        lenses_missing=["OyunTeorisi"],
        caveats=[
            "Confidence at 0.95 boundary — KV₄ warning",
            "Existence of Euler bricks is proven, but their infinity "
            "is conjectured from parametric families",
        ],
    ))

    claims.append(GradedClaim(
        statement=(
            "The fidelity spectrum follows a convergent funnel pattern: "
            "triples satisfying 0/4 equations vastly outnumber those "
            "satisfying 1/4, which outnumber 2/4, etc. (AX22 funnel)."
        ),
        grade=EpistemicGrade.ILMELYAKIN,
        claim_type=ClaimType.KULLIYAT,
        evidence_basis="Computational fidelity spectrum + AX21 continuous degrees",
        confidence=0.88,
        lenses_used=["Bayes", "Topoloji"],
        lenses_missing=["KategoriTeorisi", "OyunTeorisi"],
        caveats=["Computed only for small ranges; structural pattern assumed to hold"],
    ))

    # ---------- Detail Claims (Tafsîlât) — lower confidence ----------

    claims.append(GradedClaim(
        statement=(
            "No perfect cuboid exists with all edges ≤ 10^12."
        ),
        grade=EpistemicGrade.TASDIK,
        claim_type=ClaimType.TAFLISAAT,
        evidence_basis="Literature: computational search results (multiple groups)",
        confidence=0.80,
        lenses_used=["FOL"],
        lenses_missing=["Bayes", "Ontoloji", "Mereoloji", "OyunTeorisi",
                         "KategoriTeorisi", "Topoloji"],
        caveats=[
            "Exhaustive search covers finite range only",
            "Does not address existence beyond searched range",
            "T15: detail claim, lower reliability than structural claims",
        ],
    ))

    claims.append(GradedClaim(
        statement=(
            "The 2026 preprint (Yelle, arXiv:2602.00239) claims non-existence "
            "via infinite descent. If peer review confirms it, the problem "
            "is resolved: the perfect cuboid is an unreachable supremum (AX22)."
        ),
        grade=EpistemicGrade.TASAVVUR,
        claim_type=ClaimType.TAFLISAAT,
        evidence_basis="Single unreviewed preprint (January 2026)",
        confidence=0.35,
        lenses_used=["FOL"],
        lenses_missing=["All others"],
        caveats=[
            "NOT peer-reviewed — cannot be relied upon",
            "K-10: we are at İstidlal station, cannot verify the proof's "
            "inner validity without formal peer review",
            "If confirmed, would elevate the structural claim to İlmelyakîn",
        ],
    ))

    # ---------- Meta-Claim (Framework-level) ----------

    claims.append(GradedClaim(
        statement=(
            "Whether or not a perfect cuboid exists, the problem's structure "
            "exhibits all the hallmarks of an unreachable supremum (AX22): "
            "near-misses cluster increasingly close but never reach identity."
        ),
        grade=EpistemicGrade.TASDIK,
        claim_type=ClaimType.KULLIYAT,
        evidence_basis="Near-miss analysis + fidelity funnel + T14 chain",
        confidence=0.78,
        lenses_used=["Ontoloji", "Bayes", "Topoloji"],
        lenses_missing=["OyunTeorisi", "KategoriTeorisi"],
        caveats=[
            "Pattern matching ≠ proof — the supremum could be reached",
            "AX58: formalization maps structure, not existential certainty",
        ],
    ))

    return claims


def epistemic_summary(claims: Optional[list[GradedClaim]] = None) -> dict:
    """Generate an epistemic summary of all claims.

    AX57: Mandatory transparency disclosure.
    T15: Weight structural claims above detail claims.
    """
    if claims is None:
        claims = grade_cuboid_claims()

    kulliyat = [c for c in claims if c.claim_type == ClaimType.KULLIYAT]
    taflisaat = [c for c in claims if c.claim_type == ClaimType.TAFLISAAT]

    all_lenses = set()
    missing_lenses = set()
    for c in claims:
        all_lenses.update(c.lenses_used)
        missing_lenses.update(c.lenses_missing)

    # KV₄ check: any confidence ≥ 0.95?
    kv4_warnings = [c for c in claims if c.confidence >= 0.95]

    return {
        "total_claims": len(claims),
        "structural_claims": len(kulliyat),
        "detail_claims": len(taflisaat),
        "avg_structural_confidence": (
            sum(c.confidence for c in kulliyat) / len(kulliyat)
            if kulliyat else 0
        ),
        "avg_detail_confidence": (
            sum(c.confidence for c in taflisaat) / len(taflisaat)
            if taflisaat else 0
        ),
        "t15_verified": (
            (sum(c.confidence for c in kulliyat) / len(kulliyat)
             if kulliyat else 0) >
            (sum(c.confidence for c in taflisaat) / len(taflisaat)
             if taflisaat else 0)
        ),
        "lenses_engaged": sorted(all_lenses),
        "lenses_missing": sorted(missing_lenses - all_lenses),
        "kv4_warnings": len(kv4_warnings),
        "max_grade": max((c.grade.value for c in claims),
                         key=lambda g: ["tasavvur", "tasdik", "ilmelyakin"].index(g)),
        "station": "istidlal (AX43)",
    }
