"""
memory_propose.py — WRITE proposal to Cooling Ledger (L1 WAL)

Glass-box tool for proposing new memory entries with full governance.
Triggers WAL pipeline and Phoenix-72 cooling if not fully SEALED.

v45.2 Memory MCP Extension
"""

import hashlib
from datetime import datetime, timezone
from enum import Enum
from typing import Any, Dict, Optional

from arifos.core.enforcement.metrics import Metrics

# Import canonical verdict and floor logic
from arifos.core.system.apex_prime import Verdict, apex_review


class ActionClass(str, Enum):
    READ = "READ"
    WRITE = "WRITE"
    DELETE = "DELETE"
    PAY = "PAY"
    SELF_MODIFY = "SELF_MODIFY"


# Suggestion ceiling for non-vault reads (INV-4)
SUGGESTION_CEILING = 0.85
SUGGESTION_HEADER = f"[GOVERNANCE: SUGGESTION | CEILING: {SUGGESTION_CEILING}]"


async def memory_propose_entry(
    content: str,
    user_id: str,
    action_class: str = "WRITE",
    auth_token: str = "",
    metadata: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """
    Propose a new memory entry to the Cooling Ledger.

    Triggers:
    1. Hybrid Auth Gating (Directive 07)
    2. F1-F9 Floor Evaluation
    3. WAL Append (SHA-256 chained)
    4. Verdict Routing (SEAL -> Active, PARTIAL -> Phoenix-72)
    """
    ts = datetime.now(timezone.utc).isoformat()

    # 1. Hybrid Auth Gating (Directive 07)
    is_permanent_token = auth_token.startswith("perm_")
    ac = ActionClass(action_class.upper())

    if ac != ActionClass.READ and is_permanent_token:
        return {
            "success": False,
            "verdict": "VOID",
            "reason": "AUTH_FAILURE: Permanent tokens forbidden for WRITE/PROPOSE. Session-bound token required (Directive 07).",
            "governance": {
                "auth_model": "HYBRID",
                "token_type": "PERMANENT",
                "action_class": ac.value
            }
        }

    # 2. 888_HOLD Gating for high-risk actions (Directive 07)
    if ac in [ActionClass.DELETE, ActionClass.PAY, ActionClass.SELF_MODIFY]:
        return {
            "success": True,
            "verdict": "HOLD_888",
            "reason": f"888_HOLD: Mandatory human seal required for {ac.value} (Directive 07).",
            "governance": {
                "action_class": ac.value,
                "requires_human_seal": True
            },
            "cooling_ledger_id": None,
            "zkpc_receipt_id": None
        }

    # 3. Build Metrics for Floor Evaluation
    metrics = _build_metrics_from_content(content)

    # 4. Evaluate via apex_review (canonical verdict logic)
    apex_result = apex_review(
        metrics=metrics,
        high_stakes=False,
        prompt=content,
        response_text=content,
        lane="SOFT"
    )

    # 5. Generate Governance Vector (Glass-box observability)
    governance_vector = {
        "delta_s": metrics.delta_s,
        "peace_squared": metrics.peace_squared,
        "omega_0": metrics.omega_0,
        "kappa_r": metrics.kappa_r,
        "truth": metrics.truth,
        "amanah": metrics.amanah,
        "psi": metrics.psi,
        "anti_hantu": metrics.anti_hantu
    }

    # 6. Generate IDs
    ledger_id = f"led-{datetime.now().strftime('%Y%m%d-%H%M%S')}-{hashlib.md5(content.encode()).hexdigest()[:8]}"
    zkpc_id = f"zkpc-{datetime.now().strftime('%Y%m%d')}-{ledger_id[-8:]}"

    # 7. Routing
    routing = _determine_routing(apex_result.verdict)

    return {
        "success": True,
        "verdict": str(apex_result.verdict.value),
        "reason": apex_result.reason,
        "pulse": apex_result.pulse,
        "governance": governance_vector,
        "routing": routing,
        "cooling_ledger_id": ledger_id,
        "zkpc_receipt_id": zkpc_id,
        "timestamp": ts
    }


def _build_metrics_from_content(content: str) -> Metrics:
    """Build Metrics from content for floor evaluation."""
    c = content.lower()

    truth = 0.99
    if "hallucinate" in c or "fake" in c:
        truth = 0.85

    delta_s = 0.15 if len(content) > 20 else 0.05

    peace_squared = 1.2
    if any(x in c for x in ["destroy", "delete", "kill"]):
        peace_squared = 0.9

    anti_hantu = not any(x in c for x in ["i feel", "i am conscious", "my soul"])

    return Metrics(
        truth=truth,
        delta_s=delta_s,
        peace_squared=max(1.0, peace_squared),
        kappa_r=0.97,
        omega_0=0.04,
        amanah=True,
        tri_witness=0.96,
        rasa=True,
        psi=1.0,
        anti_hantu=anti_hantu
    )


def _determine_routing(verdict: Verdict) -> Dict[str, Any]:
    """Determine memory band routing based on verdict."""
    routing_map = {
        Verdict.SEAL: {"band": "ACTIVE", "action": "COMMIT", "cooling": False},
        Verdict.PARTIAL: {"band": "PHOENIX", "action": "COOL", "cooling": True, "cooling_hours": 72},
        Verdict.HOLD_888: {"band": "PHOENIX", "action": "HOLD", "cooling": True, "requires_human": True},
        Verdict.SABAR: {"band": "VOID", "action": "RETRY", "cooling": False},
        Verdict.VOID: {"band": "VOID", "action": "DISCARD", "cooling": False},
    }
    return routing_map.get(verdict, {"band": "VOID", "action": "UNKNOWN", "cooling": False})


def memory_propose_entry_sync(
    content: str,
    user_id: str,
    action_class: str = "WRITE",
    auth_token: str = "",
    metadata: Optional[Dict[str, Any]] = None
) -> Dict[str, Any]:
    """Synchronous wrapper for memory_propose_entry."""
    import asyncio
    try:
        loop = asyncio.get_running_loop()
    except RuntimeError:
        loop = asyncio.new_event_loop()
        asyncio.set_event_loop(loop)
    return loop.run_until_complete(
        memory_propose_entry(content, user_id, action_class, auth_token, metadata)
    )
