#!/usr/bin/env python3
"""
Fast 8D Chromatic Visualization - Optimized for Performance
No GPU overhead, just pure speed with numpy vectorization
"""

import re
import numpy as np
import matplotlib
matplotlib.use('TkAgg')
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
from matplotlib.animation import FuncAnimation
from collections import deque

LOG_FILE = "../logs/peer1.log"
TRAIL_LENGTH = 1000  # Smaller for instant responsiveness

class FastMonitor:
    def __init__(self):
        self.positions = deque(maxlen=TRAIL_LENGTH)
        self.last_position = 0
        self.current_omega = 0
        self.current_evolution = 0
        self.frame_skip = 0

    def update(self):
        """Fast log parsing - sample every 10th frame"""
        try:
            with open(LOG_FILE, 'r', encoding='utf-8', errors='ignore') as f:
                f.seek(self.last_position)
                lines = f.readlines()
                self.last_position = f.tell()

                dims = {}
                for line in lines:
                    # Quick regex matches
                    if 'Evolution:' in line:
                        parts = line.split('│')
                        if len(parts) >= 2:
                            try:
                                self.current_evolution = int(parts[0].split(':')[1].strip())
                                omega_part = parts[2].split(':')[1].strip()
                                self.current_omega = float(omega_part)
                            except:
                                pass

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

                    # Add complete snapshots (every 10th)
                    if len(dims) == 8:
                        self.frame_skip += 1
                        if self.frame_skip % 10 == 0:
                            self.positions.append(tuple(dims[i] for i in range(8)))
                        dims = {}
        except:
            pass

def get_color(idx):
    """Fast color lookup"""
    colors = ['#FF0000', '#FF8800', '#FFFF00', '#00FF00',
              '#00FFFF', '#0088FF', '#8800FF', '#FF00FF']
    return colors[idx]

def animate(frame, monitor, ax, scatter, text):
    """Ultra-fast update"""
    monitor.update()

    if len(monitor.positions) < 10:
        return scatter, text

    # Fast numpy processing - convert deque to list first
    positions_list = list(monitor.positions)
    arr = np.array(positions_list[-500:], dtype=np.float32)  # Only last 500 points

    # Fast log normalization (vectorized)
    arr = np.log10(np.abs(arr) + 1e-50)
    arr = (arr - arr.min(axis=0)) / (arr.max(axis=0) - arr.min(axis=0) + 1e-10)

    # Musical projection (pure numpy - fast!)
    x = arr[:, 0] * 0.6 + arr[:, 7] * 0.4
    y = arr[:, 2] * 0.5 + arr[:, 5] * 0.5
    z = arr[:, 4] * 0.5 + arr[:, 3] * 0.5

    # Single color gradient (faster than per-point coloring)
    colors = plt.cm.plasma(np.linspace(0, 1, len(x)))

    # Update scatter
    scatter._offsets3d = (x, y, z)
    scatter.set_color(colors)

    # Simple info
    omega_icon = "🔴" if monitor.current_omega >= 999 else "🟢"
    text.set_text(f"{omega_icon} Ω:{monitor.current_omega:.0f} | E:{monitor.current_evolution//1000000}M | Pts:{len(monitor.positions)}")

    # Slow rotation
    ax.view_init(elev=25, azim=frame * 0.5)

    return scatter, text

def main():
    print("🚀 Fast 8D Chromatic Visualization")
    print("   Optimized for instant response\n")

    monitor = FastMonitor()

    # Minimal figure setup
    fig = plt.figure(figsize=(14, 10))
    ax = fig.add_subplot(111, projection='3d')

    fig.suptitle('8D Chromatic Attractor - Fast Mode', fontsize=14, fontweight='bold', color='cyan')

    ax.set_xlabel('Fund+Oct (D1+D8)', fontsize=10, color='white')
    ax.set_ylabel('Harmony (D3+D6)', fontsize=10, color='white')
    ax.set_zlabel('Resonance (D4+D5)', fontsize=10, color='white')
    ax.set_xlim(0, 1)
    ax.set_ylim(0, 1)
    ax.set_zlim(0, 1)

    # Single scatter (no extra lines for speed)
    scatter = ax.scatter([], [], [], s=3, alpha=0.7)

    # Minimal text
    text = ax.text2D(0.02, 0.98, "", transform=ax.transAxes,
                     fontsize=9, color='cyan', va='top',
                     bbox=dict(boxstyle='round', fc='black', alpha=0.7))

    ax.grid(False)  # No grid = faster
    ax.set_facecolor('#0a0a1a')
    fig.patch.set_facecolor('#050510')
    ax.tick_params(colors='cyan', labelsize=8)

    # Fast animation (200ms = 5 FPS, but responsive)
    ani = FuncAnimation(fig, animate,
                       fargs=(monitor, ax, scatter, text),
                       interval=200,
                       blit=True,
                       cache_frame_data=False)

    try:
        plt.show()
    except KeyboardInterrupt:
        print("\nStopped.")

if __name__ == "__main__":
    main()
