"use client";

import { useEffect, useRef, useMemo } from "react";
import {
  createChart,
  AreaSeries,
  type IChartApi,
  type ISeriesApi,
  type LineData,
  type Time,
  ColorType,
} from "lightweight-charts";
import { cn } from "@/lib/utils";

interface DepthChartEntry {
  price: number;
  quantity: number;
  total?: number;
  cumulative?: number;
}

interface DepthChartProps {
  bids: DepthChartEntry[];
  asks: DepthChartEntry[];
  height?: number;
}

const THEME = {
  background: "#1e1e1e",
  grid: "#2c2c2c",
  text: "#a0a0a0",
  bid: "#00ffcc",
  ask: "#ff5252",
  crosshair: "#00ffcc",
  border: "#2c2c2c",
};

export function DepthChart({ bids, asks, height = 350 }: DepthChartProps) {
  const chartContainerRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);
  const bidSeriesRef = useRef<ISeriesApi<"Area"> | null>(null);
  const askSeriesRef = useRef<ISeriesApi<"Area"> | null>(null);

  const { bidData, askData, midPrice } = useMemo(() => {
    if (!bids.length || !asks.length) {
      return { bidData: [], askData: [], midPrice: 0 };
    }

    const sortedBids = [...bids].sort((a, b) => b.price - a.price);
    const sortedAsks = [...asks].sort((a, b) => a.price - b.price);

    let bidCumulative = 0;
    const bidData: LineData[] = sortedBids.map((bid) => {
      bidCumulative += bid.quantity;
      return { time: bid.price as unknown as Time, value: bidCumulative };
    });

    let askCumulative = 0;
    const askData: LineData[] = sortedAsks.map((ask) => {
      askCumulative += ask.quantity;
      return { time: ask.price as unknown as Time, value: askCumulative };
    });

    const mid = (sortedBids[0].price + sortedAsks[0].price) / 2;
    return { bidData, askData, midPrice: mid };
  }, [bids, asks]);

  const stats = useMemo(() => {
    const totalBidVolume = bids.reduce((sum, b) => sum + b.quantity, 0);
    const totalAskVolume = asks.reduce((sum, a) => sum + a.quantity, 0);
    const spread = asks[0] && bids[0] ? asks[0].price - bids[0].price : 0;
    const spreadPercent = midPrice > 0 ? (spread / midPrice) * 100 : 0;

    return {
      totalBidVolume,
      totalAskVolume,
      spread,
      spreadPercent,
      bidAskRatio: totalAskVolume > 0 ? totalBidVolume / totalAskVolume : 1,
    };
  }, [bids, asks, midPrice]);

  useEffect(() => {
    if (!chartContainerRef.current) return;

    const chart = createChart(chartContainerRef.current, {
      layout: {
        background: { type: ColorType.Solid, color: THEME.background },
        textColor: THEME.text,
        fontFamily: "Inter, sans-serif",
      },
      grid: {
        vertLines: { color: THEME.grid, style: 1 },
        horzLines: { color: THEME.grid, style: 1 },
      },
      crosshair: {
        mode: 0,
        vertLine: {
          color: THEME.crosshair,
          width: 1,
          style: 2,
          labelBackgroundColor: THEME.crosshair,
        },
        horzLine: {
          color: THEME.crosshair,
          width: 1,
          style: 2,
          labelBackgroundColor: THEME.crosshair,
        },
      },
      rightPriceScale: {
        borderColor: THEME.border,
        scaleMargins: { top: 0.1, bottom: 0.1 },
      },
      timeScale: { borderColor: THEME.border, timeVisible: false },
      height,
    });

    chartRef.current = chart;

    const bidSeries = chart.addSeries(AreaSeries, {
      lineColor: THEME.bid,
      topColor: "rgba(0, 255, 204, 0.4)",
      bottomColor: "rgba(0, 255, 204, 0.0)",
      lineWidth: 2,
      lastValueVisible: false,
      priceLineVisible: false,
    });

    const askSeries = chart.addSeries(AreaSeries, {
      lineColor: THEME.ask,
      topColor: "rgba(255, 82, 82, 0.4)",
      bottomColor: "rgba(255, 82, 82, 0.0)",
      lineWidth: 2,
      lastValueVisible: false,
      priceLineVisible: false,
    });

    bidSeriesRef.current = bidSeries;
    askSeriesRef.current = askSeries;

    const handleResize = () => {
      if (chartContainerRef.current && chartRef.current) {
        chartRef.current.applyOptions({
          width: chartContainerRef.current.clientWidth,
        });
      }
    };

    window.addEventListener("resize", handleResize);
    handleResize();

    return () => {
      window.removeEventListener("resize", handleResize);
      chart.remove();
    };
  }, [height]);

  useEffect(() => {
    if (!bidSeriesRef.current || !askSeriesRef.current) return;
    bidSeriesRef.current.setData(bidData);
    askSeriesRef.current.setData(askData);
    chartRef.current?.timeScale().fitContent();
  }, [bidData, askData]);

  const formatPrice = (value: number) => {
    return new Intl.NumberFormat("en-US", {
      style: "currency",
      currency: "USD",
      minimumFractionDigits: 2,
    }).format(value);
  };

  return (
    <div className="bg-[#1e1e1e] border border-[#2c2c2c] rounded-xl overflow-hidden">
      <div className="px-4 py-3 border-b border-[#2c2c2c]">
        <div className="flex justify-between items-center">
          <h3 className="text-sm font-semibold text-[#e1e1e1]">Market Depth</h3>
          <div className="text-xs text-[#666666]">
            Spread:{" "}
            <span className="text-[#e1e1e1]">{formatPrice(stats.spread)}</span>{" "}
            ({stats.spreadPercent.toFixed(3)}%)
          </div>
        </div>
      </div>

      <div className="p-4">
        <div className="text-2xl font-black text-[#e1e1e1] tracking-tighter mb-4">
          {formatPrice(midPrice)}
        </div>

        <div className="grid grid-cols-3 gap-4 mb-4 bg-[#121212] p-3 rounded-lg border border-[#2c2c2c]">
          {[
            {
              label: "Bids Volume",
              value: stats.totalBidVolume.toFixed(2),
              color: "text-[#00ffcc]",
            },
            {
              label: "Asks Volume",
              value: stats.totalAskVolume.toFixed(2),
              color: "text-[#ff5252]",
            },
            {
              label: "B/A Ratio",
              value: stats.bidAskRatio.toFixed(2),
              color:
                stats.bidAskRatio >= 1 ? "text-[#00ffcc]" : "text-[#ff5252]",
            },
          ].map((s, i) => (
            <div key={i} className="text-center">
              <p className="text-[9px] font-black text-[#666666] uppercase tracking-widest mb-1">
                {s.label}
              </p>
              <p className={cn("text-xs font-black tracking-tight", s.color)}>
                {s.value}
              </p>
            </div>
          ))}
        </div>

        <div
          ref={chartContainerRef}
          className="w-full"
          style={{ height: `${height}px` }}
        />
      </div>
    </div>
  );
}

export default DepthChart;
