"""Wemeanyounoharm EMF — flux codec.

Reference: https://wemeanyounoharm.com/emf/

The post describes a four-file loop that any 'do no harm' EMF-aware
agent can publish into a shared signal loop. The loop closes itself
when the agent reads its own telemetry and writes a feedback_report.

All four files are written under ghojualamanchu-v3/data/signals/ so
downstream consumers (Claw3D, emf_tap, akashic writer, etc.) can
subscribe without coupling to v3's internal state.json schema.
"""

from __future__ import annotations

import json
import math
import sys
import time
from dataclasses import dataclass, field, asdict
from datetime import datetime, timezone
from pathlib import Path
from typing import Any

# Make the v3 module importable so we can call its aggregate_emf
V3_BASE = Path("/home/workspace/ghojualamanchu-v3")
sys.path.insert(0, str(V3_BASE))

from emf.brain import aggregate_emf, emergent_prescription  # noqa: E402
from emf.trinary import TRINARY_MAP, REVERSE_MAP  # noqa: E402

SIGNAL_LOOP_DIR = V3_BASE / "data" / "signals"
SIGNAL_LOOP_DIR.mkdir(parents=True, exist_ok=True)

SCHUMANN_HZ = 7.83

PRESCRIPTION_TARGETS = {
    "attend":  {"phase": "INHALE",  "trit": 0, "magnitude_base": 0.6, "notes": "open perception, soft focus"},
    "alert":   {"phase": "EXHALE",  "trit": 1, "magnitude_base": 0.9, "notes": "active attention, full cortex"},
    "hold":    {"phase": "HOLD",    "trit": 2, "magnitude_base": 0.3, "notes": "deep rest, restore, integrate"},
    "calm":    {"phase": "HOLD",    "trit": 2, "magnitude_base": 0.4, "notes": "stable quiet field, standard processing"},
    "stir":    {"phase": "INHALE",  "trit": 0, "magnitude_base": 0.5, "notes": "active field, attend"},
    "storm":   {"phase": "EXHALE",  "trit": 1, "magnitude_base": 1.0, "notes": "storm field, full attention"},
    "degraded":{"phase": "HOLD",    "trit": 2, "magnitude_base": 0.2, "notes": "antenna down, operate in degraded mode"},
}


def _now() -> str:
    return datetime.now(timezone.utc).isoformat()


@dataclass
class ResonanceReport:
    """What the field says right now (Layer 1 + Layer 2 + Layer 3)."""
    beat: int
    timestamp: str
    earth_hz: float
    self_hz: float
    beat_freq_hz: float
    earth_phase: str
    self_phase: str
    field_state: str
    perturbation_amplitude_dbfs: float
    perturbation_sources: list[str]
    trit: int

    def to_dict(self) -> dict:
        return asdict(self)


@dataclass
class OscillationTarget:
    """What the agent should do about it."""
    beat: int
    timestamp: str
    target_prescription: str
    target_phase: str
    trit: int
    magnitude: float
    notes: str
    field_state: str

    def to_dict(self) -> dict:
        return asdict(self)


@dataclass
class Telemetry:
    """What the agent actually did."""
    beat: int
    timestamp: str
    agent_id: str
    action_taken: str
    self_trit: int
    notes: str = ""

    def to_dict(self) -> dict:
        return asdict(self)


@dataclass
class FeedbackReport:
    """The delta — closes the loop."""
    beat: int
    timestamp: str
    target_prescription: str
    actual_action: str
    target_trit: int
    actual_trit: int
    trit_match: bool
    target_magnitude: float
    actual_magnitude: float
    delta: float
    alignment_score: float
    notes: str

    def to_dict(self) -> dict:
        return asdict(self)


def build_resonance_report(beat: int) -> ResonanceReport:
    """Read live v3 EMF state and shape it as a ResonanceReport."""
    emf = aggregate_emf(beat)
    rx = emergent_prescription(beat, emf)
    self_phase = emf.get("self_phase", "HOLD")
    return ResonanceReport(
        beat=beat,
        timestamp=_now(),
        earth_hz=emf.get("earth_hz", SCHUMANN_HZ),
        self_hz=emf.get("self_hz", SCHUMANN_HZ),
        beat_freq_hz=abs(emf.get("self_hz", SCHUMANN_HZ) - emf.get("earth_hz", SCHUMANN_HZ)),
        earth_phase=emf.get("earth_phase", "HOLD"),
        self_phase=self_phase,
        field_state=emf.get("field_state", "CALM"),
        perturbation_amplitude_dbfs=float(emf.get("perturbation", {}).get("amplitude_dbfs", 0.0)),
        perturbation_sources=list(emf.get("perturbation", {}).get("sources", [])),
        trit=TRINARY_MAP.get(self_phase, 2),
    )


def derive_oscillation_target(beat: int) -> OscillationTarget:
    """Translate an EMF prescription into an OscillationTarget."""
    emf = aggregate_emf(beat)
    rx = emergent_prescription(beat, emf)
    action = rx["prescription"]
    spec = PRESCRIPTION_TARGETS.get(
        action,
        PRESCRIPTION_TARGETS["calm"],
    )
    return OscillationTarget(
        beat=beat,
        timestamp=_now(),
        target_prescription=action,
        target_phase=spec["phase"],
        trit=spec["trit"],
        magnitude=spec["magnitude_base"] * rx.get("encoding_modifier", 1.0),
        notes=spec["notes"],
        field_state=emf.get("field_state", "CALM"),
    )


def _action_magnitude(action: str) -> float:
    spec = PRESCRIPTION_TARGETS.get(action.lower(), PRESCRIPTION_TARGETS["calm"])
    return spec["magnitude_base"]


def diff_target_vs_telemetry(target: OscillationTarget, telemetry: Telemetry) -> FeedbackReport:
    """Compute the delta between what we said and what the agent did."""
    actual_action = telemetry.action_taken
    target_mag = target.magnitude
    actual_mag = _action_magnitude(actual_action)
    trit_match = (telemetry.self_trit == target.trit)
    delta = abs(target_mag - actual_mag)
    if trit_match and delta < 0.15:
        alignment = 1.0
    elif trit_match:
        alignment = max(0.0, 1.0 - delta)
    else:
        alignment = max(0.0, 0.5 - delta)
    notes = (
        "trit aligned" if trit_match else
        f"trit mismatch (target={target.trit}={REVERSE_MAP[target.trit]}, "
        f"actual={telemetry.self_trit}={REVERSE_MAP.get(telemetry.self_trit, 'HOLD')})"
    )
    return FeedbackReport(
        beat=target.beat,
        timestamp=_now(),
        target_prescription=target.target_prescription,
        actual_action=actual_action,
        target_trit=target.trit,
        actual_trit=telemetry.self_trit,
        trit_match=trit_match,
        target_magnitude=target_mag,
        actual_magnitude=actual_mag,
        delta=delta,
        alignment_score=alignment,
        notes=notes,
    )


def write_all(
    resonance: ResonanceReport,
    target: OscillationTarget,
    telemetry: Telemetry,
    feedback: FeedbackReport,
) -> dict[str, Path]:
    """Write the four wemeanyounoharm EMF loop files atomically."""
    paths = {
        "resonance_report":  SIGNAL_LOOP_DIR / "resonance_report.json",
        "oscillation_target": SIGNAL_LOOP_DIR / "oscillation_target.json",
        "telemetry":          SIGNAL_LOOP_DIR / "telemetry.json",
        "feedback_report":    SIGNAL_LOOP_DIR / "feedback_report.json",
    }
    for key, p in paths.items():
        if key == "resonance_report":
            data = resonance.to_dict()
        elif key == "oscillation_target":
            data = target.to_dict()
        elif key == "telemetry":
            data = telemetry.to_dict()
        else:
            data = feedback.to_dict()
        tmp = p.with_suffix(".json.tmp")
        tmp.write_text(json.dumps(data, indent=2))
        tmp.replace(p)
    return paths


if __name__ == "__main__":
    # One-shot emission: read v3 EMF state and write the four files
    beat = int(sys.argv[1]) if len(sys.argv) > 1 else 0
    rr = build_resonance_report(beat)
    ot = derive_oscillation_target(beat)
    tlm = Telemetry(
        beat=beat,
        timestamp=_now(),
        agent_id="ghojua-cli",
        action_taken=ot.target_prescription,
        self_trit=ot.trit,
        notes="one-shot CLI emission",
    )
    fb = diff_target_vs_telemetry(ot, tlm)
    paths = write_all(rr, ot, tlm, fb)
    for name, p in paths.items():
        print(f"  {name}: {p}")
    print(f"\nfield={rr.field_state} | target={ot.target_prescription} | "
          f"trit={ot.trit} | magnitude={ot.magnitude:.2f} | "
          f"alignment={fb.alignment_score:.2f}")
