#!/usr/bin/env python3
"""
Snapshot 8D Chromatic Visualization
Generates beautiful high-quality snapshots every few seconds
Opens them automatically in your default image viewer
"""

import re
import numpy as np
import matplotlib
matplotlib.use('Agg')  # Backend for file saving only
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from collections import deque
import time
import os
import subprocess

LOG_FILE = "../logs/peer1.log"
OUTPUT_FILE = "chromatic_snapshot.png"

class Monitor:
    def __init__(self):
        self.positions = deque(maxlen=1200)
        self.last_pos = 0
        self.omega = 0
        self.evol = 0

    def update(self):
        try:
            with open(LOG_FILE, 'r', encoding='utf-8', errors='ignore') as f:
                f.seek(self.last_pos)
                lines = f.readlines()
                self.last_pos = f.tell()

                dims = {}
                for line in lines:
                    if 'Ω:' in line and 'Evolution:' in line:
                        try:
                            self.omega = float(line.split('Ω:')[1].split()[0])
                            self.evol = int(line.split('Evolution:')[1].split('│')[0].strip())
                        except:
                            pass

                    for i in range(1, 9):
                        if f'  D{i}:' in line:
                            try:
                                dims[i-1] = float(line.split(':')[1].split('[')[0].strip())
                            except:
                                pass

                    if len(dims) == 8:
                        self.positions.append(tuple(dims[i] for i in range(8)))
                        dims = {}
        except:
            pass

def render_beautiful_snapshot(monitor, azim, filename):
    """Create a gorgeous high-resolution snapshot"""
    if len(monitor.positions) < 20:
        return False

    print(f"  🎨 Rendering snapshot (azim={azim}°)...")

    # Process data
    arr = np.array(list(monitor.positions), dtype=np.float64)
    arr = np.log10(np.maximum(np.abs(arr), 1e-200))

    # Normalize each dimension
    for i in range(8):
        col = arr[:, i]
        vmin, vmax = col.min(), col.max()
        if vmax > vmin:
            arr[:, i] = (col - vmin) / (vmax - vmin)

    # Musical harmony projection (8D → 3D)
    x = arr[:, 0] * 0.6 + arr[:, 7] * 0.4  # Fundamental + Octave
    y = arr[:, 2] * 0.5 + arr[:, 5] * 0.5  # Thirds + Sixths
    z = arr[:, 4] * 0.5 + arr[:, 3] * 0.5  # Fifths + Fourths

    # Create beautiful high-res figure
    fig = plt.figure(figsize=(16, 12), dpi=120)
    fig.patch.set_facecolor('#050510')
    ax = fig.add_subplot(111, projection='3d')
    ax.set_facecolor('#0a0a1a')

    # Plot with plasma colormap (time gradient)
    colors = plt.cm.plasma(np.linspace(0, 1, len(x)))
    scatter = ax.scatter(x, y, z, c=colors, s=8, alpha=0.85,
                        edgecolors='white', linewidths=0.15, depthshade=True)

    # Add flowing trail for depth
    if len(x) > 100:
        step = max(1, len(x) // 120)
        ax.plot(x[::step], y[::step], z[::step], 'cyan', alpha=0.18, linewidth=0.6)

    # Beautiful styling
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_zlim(0, 1)
    ax.set_xlabel('Fundamental + Octave (D1 + D8)', color='cyan', fontsize=12, labelpad=12)
    ax.set_ylabel('Harmony (D3 + D6)', color='cyan', fontsize=12, labelpad=12)
    ax.set_zlabel('Resonance (D4 + D5)', color='cyan', fontsize=12, labelpad=12)
    ax.tick_params(colors='cyan', labelsize=9)
    ax.grid(True, alpha=0.15, color='cyan', linestyle='--', linewidth=0.5)

    # Main title
    fig.suptitle('8-Dimensional Chromatic Strange Attractor',
                fontsize=17, fontweight='bold', color='white', y=0.97)

    # Status info
    omega_status = "SATURATED ●" if monitor.omega >= 999 else "GROWING ↗"
    omega_color = '#ff3366' if monitor.omega >= 999 else '#33ff88'

    info_text = (f'Ω = {monitor.omega:.1f} ({omega_status}) | '
                f'Evolution: {monitor.evol:,} | '
                f'Trail: {len(monitor.positions)} points')

    ax.text2D(0.5, 0.93, info_text, transform=fig.transFigure,
             ha='center', fontsize=12, color=omega_color, weight='bold',
             bbox=dict(boxstyle='round,pad=0.6', facecolor='black',
                      alpha=0.85, edgecolor=omega_color, linewidth=2))

    # Musical/color legend
    legend_text = ("Musical Mapping: D1=C(Red) D2=D(Orange) D3=E(Yellow) D4=F(Green) "
                  "D5=G(Cyan) D6=A(Blue) D7=B(Indigo) D8=C'(Violet)")
    ax.text2D(0.5, 0.02, legend_text, transform=fig.transFigure,
             ha='center', fontsize=10, color='white',
             bbox=dict(boxstyle='round,pad=0.5', facecolor='black', alpha=0.8))

    # Set viewing angle
    ax.view_init(elev=28, azim=azim)

    # Save high-quality image
    plt.tight_layout(rect=[0, 0.03, 1, 0.95])
    plt.savefig(filename, facecolor=fig.get_facecolor(), dpi=120,
               bbox_inches='tight', pad_inches=0.3)
    plt.close(fig)

    print(f"  ✅ Saved: {filename}")
    return True

def main():
    print("\n" + "="*70)
    print("  🌈 SNAPSHOT-BASED 8D CHROMATIC VISUALIZATION")
    print("  Generates beautiful snapshots every 5 seconds")
    print("  Opens automatically in your image viewer")
    print("="*70 + "\n")

    monitor = Monitor()
    azim = 0
    snapshot_count = 0
    first_image = True

    print("⏳ Collecting initial data...\n")

    try:
        while True:
            # Update data
            monitor.update()

            # Generate snapshot every 5 seconds
            if len(monitor.positions) >= 20:
                # Render
                filename = f"chromatic_{snapshot_count:04d}.png"
                success = render_beautiful_snapshot(monitor, azim, filename)

                if success:
                    # Open in default viewer (first time only for continuous viewing)
                    if first_image:
                        try:
                            os.startfile(filename)  # Windows
                            print(f"  📂 Opened in default viewer\n")
                            first_image = False
                        except:
                            print(f"  💡 Open manually: {filename}\n")

                    # Status
                    omega_icon = "🔴" if monitor.omega >= 999 else "🟢"
                    print(f"{omega_icon} Snapshot #{snapshot_count}: {len(monitor.positions)} pts | "
                          f"Ω={monitor.omega:.0f} | E={monitor.evol//1000000}M | Az={azim}°\n")

                    snapshot_count += 1
                    azim = (azim + 45) % 360  # Rotate 45° each snapshot

                    # Wait 5 seconds
                    time.sleep(5)
            else:
                print(f"  ⏳ Waiting... {len(monitor.positions)}/20 points")
                time.sleep(2)

    except KeyboardInterrupt:
        print(f"\n\n✅ Generated {snapshot_count} snapshots")
        print("   Files: chromatic_0000.png, chromatic_0001.png, etc.")

if __name__ == "__main__":
    main()
