"""Steady cloak metrics (mean flow error, recirculation zone, fluctuation suppression).

Usage:
    python steady/run_steady.py
"""
from __future__ import annotations

import json
import os
import sys

import numpy as np

_ANALYSIS = os.path.abspath(os.path.join(os.path.dirname(__file__), ".."))
if _ANALYSIS not in sys.path:
    sys.path.insert(0, _ANALYSIS)

from CCD_analysis.configs import DATA_DIR


def main():
    print("=== Steady Cloak Metrics ===\n")

    steady_dir = os.path.join(DATA_DIR, "steady_cloak", "steady_cloak")
    pinball_dir = os.path.join(DATA_DIR, "pinball", "pinball")
    empty_dir = steady_dir  # TODO: generate empty channel reference

    # Load fields
    def load_fields(d):
        p = os.path.join(d, "fields.npz")
        if not os.path.isfile(p):
            return None
        f = np.load(p)
        return f["ux"].astype(np.float64), f["uy"].astype(np.float64)

    sc = load_fields(steady_dir)
    if sc is None:
        print("ERROR: no steady cloak fields. Run scripts/collect_steady_cloak.py first.")
        return 1

    ux_s, uy_s = sc
    ux_s_mean = np.mean(ux_s, axis=0)
    uy_s_mean = np.mean(uy_s, axis=0)
    ux_s_rms = np.sqrt(np.mean((ux_s - ux_s_mean) ** 2, axis=0))
    uy_s_rms = np.sqrt(np.mean((uy_s - uy_s_mean) ** 2, axis=0))

    # 1. Fluctuation level
    total_rms = float(np.sqrt(np.mean(ux_s_rms**2 + uy_s_rms**2)))
    print(f"1. Total RMS (steady cloak): {total_rms:.6f}")

    # 2. Recirculation zone
    ny, nx = ux_s_mean.shape
    cline = ux_s_mean[ny // 2, :]
    neg = np.where(cline[400:-50] < 0)[0]
    if len(neg) > 0:
        L_r = float(neg[-1])
        print(f"2. Recirculation length L_r: {L_r:.0f} lattice units")
    else:
        L_r = 0.0
        print(f"2. Recirculation length L_r: 0 (no reverse flow)")

    # 3. Sensor mean (if available)
    sens_path = os.path.join(steady_dir, "sensors.npz")
    if os.path.isfile(sens_path):
        sd = np.load(sens_path)
        sens_mean = np.mean(sd["sensors"], axis=0)
        print(f"3. Sensor means: ux_center={sens_mean[2]:.4f}, uy_center={sens_mean[3]:.4f}")

    # 4. Compare with pinball (if available)
    pb = load_fields(pinball_dir)
    if pb is not None:
        ux_p, uy_p = pb
        ux_p_mean = np.mean(ux_p, axis=0)
        ux_p_rms = np.sqrt(np.mean((ux_p - ux_p_mean) ** 2, axis=0))
        pb_rms = float(np.sqrt(np.mean(ux_p_rms**2)))
        print(f"4. Pinball total RMS: {pb_rms:.6f}")
        print(f"   Fluctuation suppression: {(1 - total_rms / (pb_rms + 1e-12)) * 100:.1f}%")

    results = {
        "total_rms": total_rms,
        "L_r": L_r,
        "fluctuation_suppression_pct": float((1 - total_rms / (pb_rms + 1e-12)) * 100) if pb is not None else None,
    }
    out_dir = os.path.join(DATA_DIR, "steady")
    os.makedirs(out_dir, exist_ok=True)
    with open(os.path.join(out_dir, "steady_metrics.json"), "w") as f:
        json.dump(results, f, indent=2)
    print(f"\nSaved to {out_dir}/steady_metrics.json")
    return 0


if __name__ == "__main__":
    sys.exit(main())
