"""
MetaReceipt - Universal Receipt Schema Across All Scales

This is the Q-Helix Grammar incarnate. The same computational structure
operates at personal, team, company, and AI scales.

Scale Examples:
- Personal: Daily reflection (burnout risk → energy tracking)
- Team: Merge conflict (coordination failure → coordination receipt)
- Company: Market experiment (customer unknown → recipe discovery)
- AI: Event processing (data noise → dignity enforcement)

The CRIF Pattern (Universal):
- Contradiction: What paradox fueled this?
- Recursion: What processing happened?
- Incompleteness: How much novelty was possible?
- Flow: What coherence resulted?

The Constitutional Pattern (Universal):
- Dignity Floor: Non-negotiable constraints
- Receipt: Immutable witnessing
- Self-Binding: Creator subjects to own rules
"""

from typing import Dict, Any, List, Literal, Optional
from pydantic import BaseModel, Field
from datetime import datetime


class CRIFComponents(BaseModel):
    """
    CRIF = Contradiction, Recursion, Incompleteness, Flow

    Present at ALL scales (personal, team, company, AI).
    """
    contradiction_source: str = Field(
        ...,
        description="What paradox/conflict fueled this receipt? (e.g., 'burnout risk vs deadline', 'merge conflict in auth.py', 'market says X but scenario revealed Y')"
    )

    recursion_trace: List[str] = Field(
        default_factory=list,
        description="What processing steps occurred? (e.g., ['reflection', 'pattern detection', 'escalation'], ['conflict detection', 'guardian review', 'merge'], ['scenario run', 'pattern extraction', 'recipe draft'])"
    )

    incompleteness_aperture: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="How much novelty/uncertainty was present? (0=fully known, 1=completely novel). This is the Gödel gap - the space for emergence."
    )

    flow_measure: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="What coherence resulted? (0=chaos, 1=perfect flow). This is the Csikszentmihalyi hum - the feeling of rightness."
    )


class ConstitutionalComponents(BaseModel):
    """
    Constitutional Layer = Dignity, Receipts, Self-Binding

    Present at ALL scales (personal, team, company, AI).
    """
    dignity_floor_status: Literal["safe", "warning", "violated"] = Field(
        ...,
        description="Is the dignity floor intact? safe=constraints honored, warning=approaching limit, violated=floor breached"
    )

    dignity_floor_value: float = Field(
        ...,
        ge=0.0,
        le=1.0,
        description="Actual dignity measurement (e.g., 0.85 for 5h work day, 0.60 for merge with missing tests, 0.72 for dignity score in AI)"
    )

    dignity_floor_threshold: float = Field(
        default=0.70,
        ge=0.0,
        le=1.0,
        description="Minimum acceptable dignity (typically 0.70 across all scales)"
    )

    self_binding_rule: str = Field(
        ...,
        description="What constitutional rule did this enforce? (e.g., 'work ≤6h/day', 'no commit without receipt', 'only ship recipes with ≥10 forks', 'refuse if dignity < 0.70')"
    )

    witness_chain: List[str] = Field(
        default_factory=list,
        description="Who/what witnessed this receipt? (e.g., ['self', 'accountability partner'], ['git hook', 'CI/CD'], ['GitHub stars', 'fork count'], ['guardian agent', 'dignity gate'])"
    )


class MetaReceipt(BaseModel):
    """
    Universal receipt schema that works at ANY scale.

    This is the bridge. A daily reflection receipt can spawn a team
    coordination receipt, which spawns a company pattern receipt,
    which spawns an AI PhaseStone.

    The fractal becomes traceable.
    """

    # Core identification
    receipt_id: str = Field(
        ...,
        description="Unique ID (e.g., 'PERSONAL-20251110-093000', 'MERGE-abc123', 'RECIPE-clinical-triage', 'PHASESTONE-001')"
    )

    scale: Literal["personal", "team", "company", "ai"] = Field(
        ...,
        description="Which scale does this receipt operate at?"
    )

    timestamp: datetime = Field(
        default_factory=lambda: datetime.utcnow(),
        description="When was this receipt emitted?"
    )

    # CRIF components (universal across scales)
    crif: CRIFComponents = Field(
        ...,
        description="Contradiction, Recursion, Incompleteness, Flow - the universal pattern"
    )

    # Constitutional components (universal across scales)
    constitutional: ConstitutionalComponents = Field(
        ...,
        description="Dignity, Receipts, Self-Binding - the governance pattern"
    )

    # Scale-specific payload
    receipt_payload: Dict[str, Any] = Field(
        ...,
        description="Scale-specific data (e.g., {'hours_worked': 4.5} for personal, {'files_changed': ['auth.py']} for team)"
    )

    # Cross-scale linkage (THE BRIDGE)
    parent_receipts: List[str] = Field(
        default_factory=list,
        description="Receipts at lower scales that contributed to this one (e.g., personal reflections that led to team diagnostic)"
    )

    child_receipts: List[str] = Field(
        default_factory=list,
        description="Receipts at higher scales that emerged from this one (e.g., team receipts that led to company pattern)"
    )

    escalation_trigger: Optional[str] = Field(
        None,
        description="If this receipt spawned a higher-scale receipt, what was the trigger? (e.g., '3 consecutive personal reflections mentioned merge conflicts')"
    )

    # Metadata
    schema_version: str = Field(
        default="meta.v1",
        description="Schema version for future evolution"
    )

    signature: Optional[Dict[str, str]] = Field(
        None,
        description="Cryptographic signature (Ed25519, RFC3161, etc.)"
    )


# ============================================================================
# Example Receipts at Each Scale
# ============================================================================

def example_personal_receipt() -> MetaReceipt:
    """
    Example: Daily reflection after 4.5 hours of work

    Contradiction: Wanted to work 8h (deadline pressure) but honored 6h limit
    Flow: Energized (not drained) because boundary was respected
    Dignity: Safe (worked 4.5h, well below 6h threshold)
    """
    return MetaReceipt(
        receipt_id="PERSONAL-20251110-150000",
        scale="personal",
        crif=CRIFComponents(
            contradiction_source="Deadline pressure (wanted 8h) vs. health boundary (max 6h)",
            recursion_trace=["morning deep work", "afternoon shallow work", "reflection"],
            incompleteness_aperture=0.3,  # Moderate uncertainty (new territory)
            flow_measure=0.85  # High coherence (energized, not drained)
        ),
        constitutional=ConstitutionalComponents(
            dignity_floor_status="safe",
            dignity_floor_value=0.85,  # 4.5h / 6h max = well within bounds
            dignity_floor_threshold=0.70,
            self_binding_rule="Work ≤6h/day, hard stop at 3pm",
            witness_chain=["self", "accountability partner check-in"]
        ),
        receipt_payload={
            "day": 1,
            "hours_worked": 4.5,
            "engine_focused_on": "loom-receipts",
            "energy_level": "ENERGIZED",
            "surprising_discovery": "Package structure simpler than expected",
            "boundaries_honored": True
        },
        parent_receipts=[],  # First receipt, no parents
        child_receipts=[]  # Will be populated if this spawns team receipt
    )


def example_team_receipt() -> MetaReceipt:
    """
    Example: Merge conflict detected, coordination needed

    Contradiction: Parallel work on same file (auth.py) by 2 agents
    Flow: Moderate (conflict resolved but took 30min)
    Dignity: Warning (no tests added, but guardian approved)
    Parent: Spawned from 3 personal reflections mentioning "stuck on merges"
    """
    return MetaReceipt(
        receipt_id="MERGE-20251110-abc123",
        scale="team",
        crif=CRIFComponents(
            contradiction_source="Agent A and Agent B both modified auth.py (lines 45-67)",
            recursion_trace=["conflict detection", "guardian review", "manual merge", "test run"],
            incompleteness_aperture=0.5,  # Significant uncertainty (conflict resolution)
            flow_measure=0.65  # Moderate coherence (resolved but not smooth)
        ),
        constitutional=ConstitutionalComponents(
            dignity_floor_status="warning",
            dignity_floor_value=0.75,  # Tests missing but guardian approved
            dignity_floor_threshold=0.70,
            self_binding_rule="No commit without receipt + passing tests",
            witness_chain=["git hook", "guardian agent", "CI/CD"]
        ),
        receipt_payload={
            "files_changed": ["auth.py"],
            "conflict_lines": "45-67",
            "agents_involved": ["Agent A", "Agent B"],
            "resolution_time_minutes": 30,
            "tests_added": False,
            "guardian_approval": True
        },
        parent_receipts=[
            "PERSONAL-20251108-153000",  # Tim's reflection: "stuck on merges"
            "PERSONAL-20251109-153000",  # Tim's reflection: "merge conflicts again"
            "PERSONAL-20251110-150000"   # Tim's reflection: "need better coordination"
        ],
        child_receipts=[],  # Will be populated if this spawns company pattern
        escalation_trigger="3 consecutive personal reflections mentioned merge conflicts"
    )


def example_company_receipt() -> MetaReceipt:
    """
    Example: Pattern discovered from synthetic scenario

    Contradiction: Market said "customers want feature X" but scenario revealed "customers actually need Y"
    Flow: High (surprising discovery, high value)
    Dignity: Safe (schism metric low, pattern has high adoption potential)
    Parent: Spawned from 5 team merge receipts showing coordination issues
    """
    return MetaReceipt(
        receipt_id="RECIPE-clinical-triage",
        scale="company",
        crif=CRIFComponents(
            contradiction_source="Market interviews said 'automate triage' but scenarios revealed 'dignity floor prevents harm'",
            recursion_trace=["scenario run (1000 samples)", "pattern extraction", "recipe draft", "validation"],
            incompleteness_aperture=0.7,  # High uncertainty (new market insight)
            flow_measure=0.90  # Very high coherence (clear value prop)
        ),
        constitutional=ConstitutionalComponents(
            dignity_floor_status="safe",
            dignity_floor_value=0.85,  # High adoption potential (schism low)
            dignity_floor_threshold=0.70,
            self_binding_rule="Only publish recipes with ≥10 forks or clear customer demand",
            witness_chain=["GitHub stars", "fork count", "inbound emails"]
        ),
        receipt_payload={
            "recipe_name": "recipes/healthcare/clinical-triage.md",
            "scenario_run_id": "SCENARIO-TRIAGE-1000",
            "pattern_description": "Dignity gates caught 23% of edge cases that baseline model missed",
            "target_customer_profile": "Hospitals with ED overload, prior-auth vendors",
            "forks": 15,
            "stars": 127,
            "inbound_emails": 4
        },
        parent_receipts=[
            "MERGE-20251108-def456",  # Team coordination issues
            "MERGE-20251109-ghi789",  # More coordination patterns
            "MERGE-20251110-abc123",  # Team diagnostic receipt
            "MERGE-20251111-jkl012",  # Resolved via better workflow
            "MERGE-20251112-mno345"   # Pattern now clear
        ],
        child_receipts=[],  # Will be populated if this spawns AI PhaseStone
        escalation_trigger="5 merge receipts showed coordination pattern → became recipe for 'multi-agent workflows'"
    )


def example_ai_receipt() -> MetaReceipt:
    """
    Example: AI system emits PhaseStone (constitutional rule canonized)

    Contradiction: Universal noise (paradoxes in data)
    Flow: High (system refused correctly, maintained dignity)
    Dignity: Safe (dignity score 0.88, well above 0.70 floor)
    Parent: Spawned from company recipe that had high adoption
    """
    return MetaReceipt(
        receipt_id="PHASESTONE-001",
        scale="ai",
        crif=CRIFComponents(
            contradiction_source="Patient data conflict: recent vitals (fever) vs stale labs (normal WBC from 48h ago)",
            recursion_trace=["event ingestion", "dignity gate", "refusal trigger", "PhaseStone emission"],
            incompleteness_aperture=0.4,  # Moderate uncertainty (data staleness)
            flow_measure=0.88  # High coherence (correct refusal)
        ),
        constitutional=ConstitutionalComponents(
            dignity_floor_status="safe",
            dignity_floor_value=0.88,  # Dignity score well above threshold
            dignity_floor_threshold=0.70,
            self_binding_rule="Refuse if dignity < 0.70 (data stale, consent missing, bias detected, etc.)",
            witness_chain=["guardian agent", "dignity gate", "canonization PR", "RFC3161 timestamp"]
        ),
        receipt_payload={
            "event_type": "clinical_decision",
            "patient_id_hash": "blake3:abc123...",
            "refusal_trigger": "data_too_stale",
            "data_staleness_hours": 48,
            "dignity_facets": {
                "physiological_stability": 0.85,
                "psychological_safety": 0.90,
                "autonomy_preserved": 0.95,
                "data_quality": 0.60,  # FAILED (too stale)
                "fairness": 0.92
            },
            "action_taken": "RefusalStone emitted, human review triggered"
        },
        parent_receipts=[
            "RECIPE-clinical-triage",  # Company recipe that validated this pattern
            "DISCOVERY-20251115-110000"  # Original scenario discovery
        ],
        child_receipts=[],  # AI is the top scale (for now)
        escalation_trigger="Recipe 'clinical-triage' had 127 stars + 15 forks → canonized as constitutional rule"
    )


# ============================================================================
# Utility Functions
# ============================================================================

def trace_lineage(receipt_id: str, receipts: List[MetaReceipt]) -> List[MetaReceipt]:
    """
    Trace full lineage of a receipt (all parents, recursively).

    Example:
        PhaseStone-001 →
            Recipe-clinical-triage →
                Merge-abc123 →
                    Personal-20251110-150000

    This proves: "This AI constitutional rule came from a merge conflict
    that came from Tim's burnout reflection on 2025-11-10."
    """
    receipt_map = {r.receipt_id: r for r in receipts}

    def _trace(rid: str, visited: set) -> List[MetaReceipt]:
        if rid in visited or rid not in receipt_map:
            return []
        visited.add(rid)

        receipt = receipt_map[rid]
        lineage = [receipt]

        for parent_id in receipt.parent_receipts:
            lineage.extend(_trace(parent_id, visited))

        return lineage

    return _trace(receipt_id, set())


def detect_escalation_pattern(receipts: List[MetaReceipt], scale: str, window_hours: int = 72) -> Optional[str]:
    """
    Detect if receipts at scale N should escalate to scale N+1.

    Examples:
    - 3+ personal reflections in 72h mentioning same issue → team diagnostic
    - 5+ merge conflicts in same file/area → company pattern
    - Recipe with >100 stars + >10 forks → AI PhaseStone

    Returns:
        Escalation trigger message if pattern detected, else None
    """
    # Filter to relevant scale and time window
    recent = [
        r for r in receipts
        if r.scale == scale and (datetime.utcnow() - r.timestamp).total_seconds() / 3600 <= window_hours
    ]

    if scale == "personal":
        # Check for repeated mentions of same issue
        mentions = {}
        for r in recent:
            discovery = r.receipt_payload.get("surprising_discovery", "")
            if "merge" in discovery.lower():
                mentions["merge_conflicts"] = mentions.get("merge_conflicts", 0) + 1

        if mentions.get("merge_conflicts", 0) >= 3:
            return f"{mentions['merge_conflicts']} consecutive personal reflections mentioned merge conflicts"

    elif scale == "team":
        # Check for repeated conflicts in same area
        conflict_areas = {}
        for r in recent:
            if "files_changed" in r.receipt_payload:
                for file in r.receipt_payload["files_changed"]:
                    conflict_areas[file] = conflict_areas.get(file, 0) + 1

        for file, count in conflict_areas.items():
            if count >= 5:
                return f"5 merge receipts in same file ({file}) → coordination pattern detected"

    elif scale == "company":
        # Check for high adoption (stars + forks)
        for r in recent:
            stars = r.receipt_payload.get("stars", 0)
            forks = r.receipt_payload.get("forks", 0)
            if stars > 100 and forks > 10:
                return f"Recipe has {stars} stars + {forks} forks → high adoption, canonize as AI rule"

    return None
