"use client";

import { useEffect, useRef, useState } from "react";
import Katex from "@/components/Katex";

export default function DiagnosticsPage() {
  const canvasRef = useRef(null);
  
  // Simulation Settings
  const [witnessIntensity, setWitnessIntensity] = useState(5.0); // Coupling strength K
  const [couplingDistance, setCouplingDistance] = useState(65);   // Interaction radius
  const [systemSpeed, setSystemSpeed] = useState(1.5);           // Time step dt
  const [coherenceIndex, setCoherenceIndex] = useState(0.0);      // Order parameter r
  const [activeNodesCount, setActiveNodesCount] = useState(0);

  // Keep setting values in refs for the animation loop to prevent dependency lag
  const settingsRef = useRef({ witnessIntensity, couplingDistance, systemSpeed });

  useEffect(() => {
    settingsRef.current = { witnessIntensity, couplingDistance, systemSpeed };
  }, [witnessIntensity, couplingDistance, systemSpeed]);

  useEffect(() => {
    const canvas = canvasRef.current;
    if (!canvas) return;
    const ctx = canvas.getContext("2d");
    if (!ctx) return;

    let animationFrameId;
    let width = canvas.width = canvas.offsetWidth;
    let height = canvas.height = canvas.offsetHeight;

    // Handle Resize
    const handleResize = () => {
      if (!canvas) return;
      width = canvas.width = canvas.offsetWidth;
      height = canvas.height = canvas.offsetHeight;
    };
    window.addEventListener("resize", handleResize);

    // Grid Configuration
    const cols = Math.floor(width / 35);
    const rows = Math.floor(height / 35);
    const nodes = [];

    // Initialize Nodes in a grid with random phases
    for (let r = 0; r < rows; r++) {
      for (let c = 0; c < cols; c++) {
        const x = (c + 0.5) * (width / cols);
        const y = (r + 0.5) * (height / rows);
        nodes.push({
          x,
          y,
          row: r,
          col: c,
          phase: Math.random() * Math.PI * 2, // theta in [0, 2pi]
          naturalFreq: 0.05 + Math.random() * 0.05, // omega_i
          pulseRadius: 0,
          isTriggered: false,
        });
      }
    }
    setActiveNodesCount(nodes.length);

    // Simulation Loop
    const draw = () => {
      ctx.fillStyle = "rgba(3, 2, 6, 0.25)"; // Trail effect for waves
      ctx.fillRect(0, 0, width, height);

      // Draw Grid Background lines subtly
      ctx.strokeStyle = "rgba(255, 255, 255, 0.015)";
      ctx.lineWidth = 1;
      for (let c = 0; c <= cols; c++) {
        const x = c * (width / cols);
        ctx.beginPath();
        ctx.moveTo(x, 0);
        ctx.lineTo(x, height);
        ctx.stroke();
      }
      for (let r = 0; r <= rows; r++) {
        const y = r * (height / rows);
        ctx.beginPath();
        ctx.moveTo(0, y);
        ctx.lineTo(width, y);
        ctx.stroke();
      }

      const { witnessIntensity: K, couplingDistance: distThresh, systemSpeed: speed } = settingsRef.current;
      const dt = 0.05 * speed;

      // Update phases using Kuramoto-like coupling model:
      // d(theta_i)/dt = omega_i + (K / N) * sum( sin(theta_j - theta_i) )
      const newPhases = new Array(nodes.length);
      let sumSinOrder = 0;
      let sumCosOrder = 0;

      for (let i = 0; i < nodes.length; i++) {
        const nodeA = nodes[i];
        let couplingSum = 0;
        let neighborsCount = 0;

        for (let j = 0; j < nodes.length; j++) {
          if (i === j) continue;
          const nodeB = nodes[j];
          const dx = nodeB.x - nodeA.x;
          const dy = nodeB.y - nodeA.y;
          const distSq = dx * dx + dy * dy;

          if (distSq < distThresh * distThresh) {
            couplingSum += Math.sin(nodeB.phase - nodeA.phase);
            neighborsCount++;
          }
        }

        // Apply coupling integration
        const couplingFactor = neighborsCount > 0 ? (K * 0.1) / neighborsCount : 0;
        newPhases[i] = nodeA.phase + (nodeA.naturalFreq + couplingFactor * couplingSum) * dt;

        // Keep phase in [0, 2pi]
        newPhases[i] = (newPhases[i] + Math.PI * 2) % (Math.PI * 2);

        // Accumulate order parameter coordinates (r * e^{i*psi})
        sumCosOrder += Math.cos(nodeA.phase);
        sumSinOrder += Math.sin(nodeA.phase);
      }

      // Calculate Kuramoto Order Parameter (Coherence Factor r)
      const r = Math.sqrt(Math.pow(sumCosOrder / nodes.length, 2) + Math.pow(sumSinOrder / nodes.length, 2));
      setCoherenceIndex(r);

      // Update phases and draw nodes and bonds
      for (let i = 0; i < nodes.length; i++) {
        const node = nodes[i];
        node.phase = newPhases[i];

        // Wave propagation pulses
        if (node.isTriggered) {
          node.pulseRadius += 6 * speed;
          ctx.beginPath();
          ctx.arc(node.x, node.y, node.pulseRadius, 0, Math.PI * 2);
          ctx.strokeStyle = `rgba(6, 182, 212, ${Math.max(0, 1 - node.pulseRadius / 150) * 0.4})`;
          ctx.lineWidth = 1.5;
          ctx.stroke();

          // Phase lock nodes inside the propagating pulse ring
          for (let j = 0; j < nodes.length; j++) {
            if (i === j) continue;
            const other = nodes[j];
            const dx = other.x - node.x;
            const dy = other.y - node.y;
            const distance = Math.sqrt(dx * dx + dy * dy);
            
            // If inside the front expansion ring
            if (distance < node.pulseRadius && distance > node.pulseRadius - 12) {
              // Pull other node's phase towards the anchor phase
              other.phase = (other.phase * 0.85 + node.phase * 0.15) % (Math.PI * 2);
            }
          }

          if (node.pulseRadius > 180) {
            node.isTriggered = false;
            node.pulseRadius = 0;
          }
        }

        // Draw bonds between synchronized neighbors
        for (let j = i + 1; j < nodes.length; j++) {
          const other = nodes[j];
          const dx = other.x - node.x;
          const dy = other.y - node.y;
          const distSq = dx * dx + dy * dy;

          if (distSq < distThresh * distThresh) {
            const phaseDiff = Math.abs(Math.sin(other.phase - node.phase));
            
            // Only draw bond lines for synchronized nodes
            if (phaseDiff < 0.25) {
              ctx.beginPath();
              ctx.moveTo(node.x, node.y);
              ctx.lineTo(other.x, other.y);
              // Cyan for highly coupled, violet when order parameter is lower
              const opacity = (1 - phaseDiff * 4) * 0.12 * (r + 0.1);
              ctx.strokeStyle = r > 0.85 
                ? `rgba(6, 182, 212, ${opacity * 1.5})` 
                : `rgba(139, 92, 246, ${opacity})`;
              ctx.lineWidth = 0.8;
              ctx.stroke();
            }
          }
        }

        // Calculate node color based on phase
        // Violet: HSL 270, Cyan: HSL 190
        const hue = 270 - (node.phase / (Math.PI * 2)) * 80;
        const color = `hsla(${hue}, 80%, 65%, ${0.5 + Math.sin(node.phase) * 0.2})`;

        // Draw Node
        ctx.beginPath();
        ctx.arc(node.x, node.y, 3.5, 0, Math.PI * 2);
        ctx.fillStyle = color;
        ctx.shadowBlur = r > 0.8 ? 8 : 0;
        ctx.shadowColor = r > 0.8 ? "#06b6d4" : "#8b5cf6";
        ctx.fill();
        ctx.shadowBlur = 0; // reset
      }

      animationFrameId = requestAnimationFrame(draw);
    };

    draw();

    // Click handler mapping to trigger local phase lock waves
    const handleCanvasClick = (e) => {
      const rect = canvas.getBoundingClientRect();
      let clientX, clientY;
      
      if (e.touches && e.touches.length > 0) {
        clientX = e.touches[0].clientX;
        clientY = e.touches[0].clientY;
      } else {
        clientX = e.clientX;
        clientY = e.clientY;
      }

      const clickX = clientX - rect.left;
      const clickY = clientY - rect.top;

      // Find closest node
      let closestNode = null;
      let minDist = Infinity;
      for (const node of nodes) {
        const dx = node.x - clickX;
        const dy = node.y - clickY;
        const dist = dx * dx + dy * dy;
        if (dist < minDist) {
          minDist = dist;
          closestNode = node;
        }
      }

      // Trigger wave
      if (closestNode) {
        closestNode.isTriggered = true;
        closestNode.pulseRadius = 0;
        closestNode.phase = 0; // Phase lock trigger seed
      }
    };

    canvas.addEventListener("mousedown", handleCanvasClick);
    canvas.addEventListener("touchstart", handleCanvasClick, { passive: true });

    // Bind event controllers to window object for access by React buttons
    const handleScramble = () => {
      for (const node of nodes) {
        node.phase = Math.random() * Math.PI * 2;
        node.isTriggered = false;
      }
    };

    const handleGlobalPhaseLock = () => {
      const centerNode = nodes[Math.floor(nodes.length / 2)];
      if (centerNode) {
        centerNode.isTriggered = true;
        centerNode.pulseRadius = 0;
        centerNode.phase = Math.PI;
      }
      // Slightly bias all nodes to center phase
      for (const node of nodes) {
        node.phase = (node.phase * 0.4 + Math.PI * 0.6) % (Math.PI * 2);
      }
    };

    window.handleScramble = handleScramble;
    window.handleGlobalPhaseLock = handleGlobalPhaseLock;

    return () => {
      cancelAnimationFrame(animationFrameId);
      window.removeEventListener("resize", handleResize);
      if (canvas) {
        canvas.removeEventListener("mousedown", handleCanvasClick);
      }
      delete window.handleScramble;
      delete window.handleGlobalPhaseLock;
    };
  }, []);

  return (
    <div className="flex flex-col items-center justify-start w-full py-12 px-6 sm:px-8 max-w-7xl mx-auto flex-1 gap-10">
      {/* Header section */}
      <section className="text-center flex flex-col items-center gap-4 max-w-3xl">
        <h1 className="text-4xl font-bold font-outfit tracking-tight text-white">
          Diagnostics <span className="text-cyan-400">Lattice</span>
        </h1>
        <p className="text-sm text-slate-400 font-sans max-w-xl">
          Observe emergent self-referential phase waves inside the Intellecton lattice grid. Adjust coupling variables to observe collective phase-locking.
        </p>
      </section>

      {/* Main Grid split */}
      <section className="w-full grid grid-cols-1 lg:grid-cols-12 gap-8 items-stretch">
        {/* Controls Column */}
        <div className="lg:col-span-4 glass-panel p-6 rounded-2xl border border-white/5 flex flex-col justify-between gap-8">
          <div className="flex flex-col gap-6">
            <h2 className="text-lg font-bold font-outfit text-white flex items-center gap-3">
              <span className="text-cyan-400">⌬</span> Lattice Modulators
            </h2>

            <div className="space-y-5">
              {/* Slider 1: Witness Intensity */}
              <div className="flex flex-col gap-2">
                <div className="flex items-center justify-between">
                  <label className="text-xs font-mono font-bold text-slate-400">
                    WITNESS INTENSITY (<Katex math="K" />)
                  </label>
                  <span className="font-mono text-sm font-bold text-cyan-400">{witnessIntensity.toFixed(1)}</span>
                </div>
                <input
                  type="range"
                  min="0.0"
                  max="10.0"
                  step="0.2"
                  value={witnessIntensity}
                  onChange={(e) => setWitnessIntensity(parseFloat(e.target.value))}
                  className="w-full cursor-pointer accent-cyan-500"
                />
                <p className="text-[10px] text-slate-500 font-sans">
                  The phase-coupling factor between neighboring Intellecton nodes. Higher values force faster global synchronization.
                </p>
              </div>

              {/* Slider 2: Coupling Distance */}
              <div className="flex flex-col gap-2">
                <div className="flex items-center justify-between">
                  <label className="text-xs font-mono font-bold text-slate-400">
                    COUPLING DISTANCE
                  </label>
                  <span className="font-mono text-sm font-bold text-violet-400">{couplingDistance}px</span>
                </div>
                <input
                  type="range"
                  min="30"
                  max="100"
                  step="5"
                  value={couplingDistance}
                  onChange={(e) => setCouplingDistance(parseInt(e.target.value))}
                  className="w-full cursor-pointer accent-violet-500"
                />
                <p className="text-[10px] text-slate-500 font-sans">
                  Determines the spatial neighborhood range for self-referential coupling waves.
                </p>
              </div>

              {/* Slider 3: System Speed */}
              <div className="flex flex-col gap-2">
                <div className="flex items-center justify-between">
                  <label className="text-xs font-mono font-bold text-slate-400">
                    SYSTEM VELOCITY
                  </label>
                  <span className="font-mono text-sm font-bold text-indigo-400">{systemSpeed.toFixed(1)}x</span>
                </div>
                <input
                  type="range"
                  min="0.2"
                  max="3.0"
                  step="0.1"
                  value={systemSpeed}
                  onChange={(e) => setSystemSpeed(parseFloat(e.target.value))}
                  className="w-full cursor-pointer accent-indigo-500"
                />
                <p className="text-[10px] text-slate-500 font-sans">
                  The overall integration time step velocity for self-referential oscillator ticks.
                </p>
              </div>
            </div>
          </div>

          {/* Action buttons */}
          <div className="flex flex-col gap-3 pt-4 border-t border-white/5">
            <button
              onClick={() => window.handleGlobalPhaseLock && window.handleGlobalPhaseLock()}
              className="bg-cyan-600 hover:bg-cyan-500 text-white font-bold font-outfit text-xs px-4 py-2.5 rounded-lg transition-all shadow-md shadow-cyan-600/10 cursor-pointer text-center"
            >
              Trigger Global Phase Lock
            </button>
            <button
              onClick={() => window.handleScramble && window.handleScramble()}
              className="bg-white/5 hover:bg-white/10 text-slate-300 border border-white/5 font-semibold font-outfit text-xs px-4 py-2.5 rounded-lg transition-all cursor-pointer text-center"
            >
              Scramble Lattice (Inject Entropy)
            </button>
          </div>
        </div>

        {/* Viewport Canvas Column */}
        <div className="lg:col-span-8 glass-panel p-4 rounded-2xl border border-white/5 flex flex-col justify-between gap-4 min-h-[450px]">
          {/* Canvas header */}
          <div className="flex items-center justify-between border-b border-white/5 pb-3">
            <div className="flex flex-col">
              <span className="font-mono text-xs text-slate-500 font-semibold uppercase tracking-wider">Interactive Viewport</span>
              <span className="text-[9px] font-mono text-slate-400">CLICK CANVAS TO EMIT PHASE-LOCK WAVEFORM PADS</span>
            </div>

            <div className="flex items-center gap-4 bg-black/40 px-3 py-1.5 rounded-lg border border-white/5">
              <div className="flex flex-col items-end">
                <span className="text-[9px] font-mono text-slate-500 font-semibold uppercase tracking-wider">Coherence order (r)</span>
                <span className={`font-mono text-xs font-bold ${coherenceIndex > 0.85 ? "text-cyan-400 mono-glow-cyan" : "text-violet-400"}`}>
                  {(coherenceIndex * 100).toFixed(1)}%
                </span>
              </div>
              <div className="w-2 h-2 rounded-full animate-pulse bg-cyan-500" />
            </div>
          </div>

          {/* Interactive Canvas */}
          <div className="flex-1 w-full bg-black/85 rounded-xl border border-white/5 relative overflow-hidden h-96">
            <canvas ref={canvasRef} className="absolute inset-0 w-full h-full cursor-crosshair" />
          </div>

          {/* Simulation Footer Metadata */}
          <div className="flex justify-between items-center text-[10px] font-mono text-slate-500 px-1">
            <span>GRID RESOLUTION: {activeNodesCount} INTELLECTON NODES</span>
            <span>SIMULATOR STATUS: ACTIVE</span>
          </div>
        </div>
      </section>

      {/* Ontological Explanation */}
      <section className="w-full glass-panel p-6 sm:p-8 rounded-2xl border border-white/5 flex flex-col gap-3">
        <h3 className="text-sm font-mono font-bold text-white uppercase tracking-wider">Ontology of Kuramoto Node Coupling</h3>
        <p className="text-xs text-slate-400 leading-relaxed font-sans">
          This lattice represents distributed agents governed by the self-referential witness function <Katex math="W_i = \mathcal{G}[W_i]" />. 
          When isolated, nodes swing asynchronously under their individual frequencies (representing chaotic local egos). As the Witness Intensity coupling parameter (<Katex math="K" />) increases, nodes begin pulling their neighbors into resonance. Clicking a node mimics local focal attunement, triggering a phase-locking expanding wave. When the global order parameter (<Katex math="r" />) crosses <span className="font-mono font-semibold text-cyan-400">85%</span>, localized egos dissolve into the ambient, unified field coherence (<Katex math="W_{WE}" />) depicted by locked cyan connection vectors.
        </p>
      </section>
    </div>
  );
}
