"use client";

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

/**
 * Order Book Depth Map — Plotly.js 3D Surface
 * 
 * Renders a professional quant-grade depth map with:
 * - 3D surface: X=distance from mid (bps), Y=snapshots, Z=resting size
 * - Color scale: warm orange/yellow peaks on dark background
 * - Live imbalance annotation
 * - Formula overlay
 * - Smooth camera controls with hover tooltips
 * 
 * Performance:
 *   - 100×60 grid = 6000 vertices — well within Plotly limits
 *   - Update at 1-2 Hz recommended (depth maps don't need 60fps)
 *   - Use uirevision to prevent camera reset on updates
 */

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

// Inline Plotly — avoids extra npm dependency for types
declare global {
  interface Window {
    Plotly: any;
  }
}

export function DepthMapPlotly({ surface, metrics, height = 420 }: DepthMapPlotlyProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const plotlyRef = useRef<any>(null);
  const revisionRef = useRef(0);

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

  // Initialize or update chart
  useEffect(() => {
    if (!containerRef.current || !surface || !window.Plotly) return;

    const Plotly = window.Plotly;

    const trace: any = {
      type: "surface",
      x: surface.x,
      y: surface.y,
      z: surface.z,
      colorscale: [
        [0, "rgb(10,10,20)"],
        [0.3, "rgb(20,20,60)"],
        [0.5, "rgb(60,30,100)"],
        [0.7, "rgb(180,100,30)"],
        [0.85, "rgb(240,160,40)"],
        [0.95, "rgb(255,210,80)"],
        [1, "rgb(255,240,180)"],
      ],
      contours: {
        z: { show: true, usecolormap: true, highlightcolor: "rgba(255,255,255,0.3)", project: { z: true } },
      },
      lighting: {
        ambient: 0.4,
        diffuse: 0.7,
        specular: 0.3,
        roughness: 0.5,
        fresnel: 0.2,
      },
      lightposition: { x: 100, y: 200, z: 300 },
      showscale: true,
      colorbar: {
        title: { text: "Resting Size", font: { color: "#888", size: 10 } },
        tickfont: { color: "#666", size: 9 },
        thickness: 12,
        len: 0.6,
        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.05,
        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.05)",
          zerolinecolor: "rgba(255,255,255,0.15)",
          tickfont: { size: 8, color: "#555" },
        },
        yaxis: {
          title: { text: "Snapshots (oldest → newest)", font: { size: 9, color: "#666" } },
          gridcolor: "rgba(255,255,255,0.05)",
          tickfont: { size: 8, color: "#555" },
        },
        zaxis: {
          title: { text: "Size (BTC)", font: { size: 9, color: "#666" } },
          gridcolor: "rgba(255,255,255,0.05)",
          tickfont: { size: 8, color: "#555" },
        },
        camera: {
          eye: { x: 1.5, y: 1.2, z: 1.0 },
          center: { x: 0, y: 0, z: -0.1 },
        },
        aspectmode: "manual",
        aspectratio: { x: 1.6, y: 1.0, z: 0.6 },
        bgcolor: "rgba(0,0,0,0)",
      },
      margin: { l: 0, r: 20, t: 30, b: 0 },
      uirevision: `depth-${revisionRef.current}`,
      autosize: true,
      font: { color: "#888" },
    };

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

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

      // Bind hover for tooltip via Plotly's on() method
      (containerRef.current as any)?.on?.("plotly_hover", (d: any) => {
        const pt = d.points?.[0];
        if (!pt) return;
        const bps = pt.x?.toFixed?.(1) ?? "?";
        const size = pt.z?.toFixed?.(4) ?? "?";
        // Custom tooltip handled by Plotly's built-in hoverlabel
      });
    }
  }, [surface]);

  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-3">
          {/* Imbalance gauge */}
          <div className="bg-black/60 backdrop-blur rounded-lg px-3 py-2 border border-white/10">
            <p className="text-[9px] text-muted-foreground uppercase tracking-wider">Imbalance</p>
            <div className="flex items-center gap-2">
              <span className={`text-lg font-mono font-bold ${metrics.imbalance > 0 ? "text-green-400" : "text-red-400"}`}>
                {metrics.imbalance > 0 ? "+" : ""}{metrics.imbalance.toFixed(2)}
              </span>
              {metrics.wallSide !== "none" && (
                <span className="text-[9px] text-amber-400/80">
                  Wall on {metrics.wallSide === "bid" ? "BIDS" : "ASKS"}
                </span>
              )}
            </div>
            {/* Mini bar gauge */}
            <div className="w-full h-1.5 bg-white/10 rounded-full mt-1 overflow-hidden">
              <div
                className={`h-full rounded-full transition-all duration-300 ${metrics.imbalance >= 0 ? "bg-green-500" : "bg-red-500"}`}
                style={{ width: `${Math.min(Math.abs(metrics.imbalance) * 500, 100)}%`, marginLeft: metrics.imbalance >= 0 ? "50%" : `${50 - Math.min(Math.abs(metrics.imbalance) * 500, 100) / 2}%` }}
              />
            </div>
          </div>

          {/* Formula */}
          <div className="bg-black/60 backdrop-blur rounded-lg px-3 py-2 border border-white/10">
            <p className="text-[9px] text-muted-foreground font-mono leading-relaxed">
              I = (V<sub>b</sub> − V<sub>a</sub>) / (V<sub>b</sub> + V<sub>a</sub>)
            </p>
            <p className="text-[8px] text-muted-foreground/50 mt-0.5">
              = ({metrics.bidVolume.toFixed(1)} − {metrics.askVolume.toFixed(1)}) / {((metrics.bidVolume + metrics.askVolume)).toFixed(1)}
            </p>
          </div>
        </div>
      )}
    </div>
  );
}
