"use client";

import { useEffect, useRef, useState, useCallback } from "react";
import type { SurfaceData, ImbalanceMetrics } from "@/lib/depth-map-utils";

/**
 * Order Book Depth Map — Plotly.js 3D Surface
 *
 * Single unified surface: X = distance from mid (bps, -50 to +50),
 * Y = snapshot index (oldest → newest), Z = resting size (BTC).
 *
 * Warm amber/gold colorscale on dark background.
 * Live imbalance overlay with formula + wall detection.
 */

interface Props {
  surface: SurfaceData | null;
  metrics: ImbalanceMetrics | null;
  height?: number;
}

const COLORSCALE = [
  [0, "rgb(8,8,18)"],
  [0.2, "rgb(18,18,48)"],
  [0.4, "rgb(50,25,90)"],
  [0.6, "rgb(140,60,30)"],
  [0.75, "rgb(210,110,30)"],
  [0.88, "rgb(245,170,45)"],
  [0.96, "rgb(255,220,100)"],
  [1, "rgb(255,245,190)"],
];

export function DepthMapPlotly({ surface, metrics, height = 440 }: Props) {
  const containerRef = useRef<HTMLDivElement>(null);
  const plotlyReady = useRef(false);
  const [loaded, setLoaded] = useState(false);

  // Load Plotly CDN once
  useEffect(() => {
    if ((window as any).Plotly) {
      setLoaded(true);
      return;
    }
    const s = document.createElement("script");
    s.src = "https://cdn.plot.ly/plotly-3.0.0.min.js";
    s.async = true;
    s.onload = () => setLoaded(true);
    document.head.appendChild(s);
    return () => { s.remove(); };
  }, []);

  // Render / update chart
  useEffect(() => {
    if (!containerRef.current || !loaded || !surface) return;
    const Plotly = (window as any).Plotly;
    if (!Plotly) return;

    const cw = containerRef.current.clientWidth || 800;

    // Build trace — ensure no NaN/Infinity values
    const cleanZ = surface.z.map(row =>
      row.map(v => (isFinite(v) && v > 0 ? v : 0))
    );

    const trace = {
      type: "surface",
      x: surface.x,
      y: surface.y,
      z: cleanZ,
      colorscale: COLORSCALE,
      contours: {
        z: {
          show: true,
          usecolormap: true,
          highlightcolor: "rgba(255,255,255,0.25)",
          project: { z: true },
        },
      },
      lighting: {
        ambient: 0.5,
        diffuse: 0.7,
        specular: 0.25,
        roughness: 0.45,
        fresnel: 0.15,
      },
      lightposition: { x: 150, y: 250, z: 350 },
      showscale: true,
      colorbar: {
        title: { text: "Resting Size", font: { color: "#999", size: 10 } },
        tickfont: { color: "#777", size: 8 },
        thickness: 14,
        len: 0.65,
        x: 1.02,
      },
    };

    const layout: any = {
      title: {
        text: "ORDER BOOK IMBALANCE • BTC-USD-PERP",
        font: { size: 12, color: "#ccc", family: "Inter, sans-serif" },
        x: 0.03,
        y: 0.98,
      },
      paper_bgcolor: "rgba(0,0,0,0)",
      plot_bgcolor: "rgba(0,0,0,0)",
      scene: {
        xaxis: {
          title: { text: "Distance from Mid (bps)", font: { size: 9, color: "#666" } },
          gridcolor: "rgba(255,255,255,0.04)",
          zerolinecolor: "rgba(255,255,255,0.12)",
          tickfont: { size: 8, color: "#555" },
          range: [-55, 55],
        },
        yaxis: {
          title: { text: "Snapshot Index (oldest → newest)", font: { size: 9, color: "#666" } },
          gridcolor: "rgba(255,255,255,0.04)",
          tickfont: { size: 8, color: "#555" },
        },
        zaxis: {
          title: { text: "Size (BTC)", font: { size: 9, color: "#666" } },
          gridcolor: "rgba(255,255,255,0.04)",
          tickfont: { size: 8, color: "#555" },
        },
        camera: {
          eye: { x: 1.5, y: 1.2, z: 0.95 },
          center: { x: 0, y: 0, z: -0.08 },
        },
        aspectmode: "manual",
        aspectratio: { x: 1.5, y: 1.0, z: 0.55 },
        bgcolor: "rgba(0,0,0,0)",
      },
      margin: { l: 0, r: 30, t: 32, b: 0 },
      uirevision: "obi-surface-v2",
      autosize: true,
      font: { color: "#888" },
    };

    const config = {
      displayModeBar: true,
      modeBarButtonsToRemove: ["sendDataToCloud", "zoom2d", "pan2d", "select2d", "lasso2d", "autoScale2d"],
      displaylogo: false,
      responsive: true,
    };

    if (plotlyReady.current) {
      Plotly.react(containerRef.current, [trace], layout, config);
    } else {
      Plotly.newPlot(containerRef.current, [trace], layout, config);
      plotlyReady.current = true;
    }
  }, [surface, loaded]);

  // Resize on container width change
  useEffect(() => {
    const obs = new ResizeObserver(() => {
      const Plotly = (window as any).Plotly;
      if (containerRef.current && Plotly) {
        Plotly.Plots.resize(containerRef.current);
      }
    });
    if (containerRef.current) obs.observe(containerRef.current);
    return () => obs.disconnect();
  }, []);

  return (
    <div className="relative">
      <div ref={containerRef} style={{ width: "100%", height }} />

      {/* Imbalance Overlay */}
      {metrics && (
        <div className="absolute top-3 right-4 z-10 flex flex-col gap-2 pointer-events-none">
          <div className="bg-black/70 backdrop-blur-lg rounded-lg px-3.5 py-2.5 border border-white/10">
            <p className="text-[8px] text-muted-foreground uppercase tracking-widest mb-1">Live Imbalance</p>
            <div className="flex items-center gap-2">
              <span
                className={`text-xl font-mono font-bold ${metrics.imbalance > 0.005 ? "text-green-400" : metrics.imbalance < -0.005 ? "text-red-400" : "text-zinc-400"}`}
              >
                {metrics.imbalance > 0 ? "+" : ""}{metrics.imbalance.toFixed(3)}
              </span>
            </div>
            {metrics.wallSide !== "none" && (
              <p className={`text-[9px] mt-0.5 ${metrics.wallSide === "bid" ? "text-green-400/80" : "text-red-400/80"}`}>
                Wall: {metrics.wallSide.toUpperCase()}S ({(metrics.wallStrength ?? 0).toFixed(1)})
              </p>
            )}
            <div className="w-full h-1 bg-white/10 rounded-full mt-1.5 overflow-hidden">
              <div
                className={`h-full rounded-full ${metrics.imbalance >= 0 ? "bg-green-500" : "bg-red-500"}`}
                style={{
                  width: `${Math.min(Math.abs(metrics.imbalance) * 350, 100)}%`,
                  marginLeft: metrics.imbalance >= 0 ? "50%" : `${50 - Math.min(Math.abs(metrics.imbalance) * 350, 100) / 2}%`,
                }}
              />
            </div>
          </div>
          <div className="bg-black/70 backdrop-blur-lg rounded-lg px-3 py-1.5 border border-white/10">
            <p className="text-[8px] text-muted-foreground font-mono">
              I = (V<sub>b</sub> − V<sub>a</sub>) / (V<sub>b</sub> + V<sub>a</sub>)
            </p>
          </div>
        </div>
      )}
    </div>
  );
}
