import { useEffect, useRef, useState } from "react";
import * as LightweightCharts from "lightweight-charts";

type ChartTime = string | number;

interface ChartDataPoint {
  time: ChartTime;
  open: number;
  high: number;
  low: number;
  close: number;
}

interface TradingViewChartProps {
  ticker: string;
  data?: ChartDataPoint[];
  timeframe?: string;
  currentPrice?: number;
  // priceStream.subscribe(cb) should return an unsubscribe function
  priceStream?: { subscribe: (cb: (price: number) => void) => () => void };
}

const TIMEFRAME_HEIGHTS: Record<string, number> = {
  "1D": 300,
  "5Min": 250,
  "15Min": 250,
  "1H": 350,
  "1W": 400,
};

export default function TradingViewChart({ ticker, data, timeframe = "1D", currentPrice, priceStream }: TradingViewChartProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const [livePrice, setLivePrice] = useState<number | undefined>(undefined);
  const height = TIMEFRAME_HEIGHTS[timeframe] ?? 400;

  const isIntraday = ["1Min", "5Min", "15Min", "30Min", "1H"].includes(timeframe);
  
  useEffect(() => {
    if (!containerRef.current) {
      return;
    }

    const chart = LightweightCharts.createChart(containerRef.current, {
      height,
      autoSize: true,
    });

    // Configure time scale based on timeframe and range
    chart.timeScale().applyOptions({
      timeVisible: isIntraday,
      secondsVisible: timeframe === "1Min",
    });

    const candlestickSeries = chart.addSeries(LightweightCharts.CandlestickSeries, {
      upColor: "#26a69a",
      downColor: "#ef5350",
      borderUpColor: "#26a69a",
      borderDownColor: "#ef5350",
      wickUpColor: "#26a69a",
      wickDownColor: "#ef5350",
    });
    
    if (data && data.length > 0) {
      try {
        candlestickSeries.setData(data as any);
        // Fit the visible data range
        chart.timeScale().fitContent();
      } catch (err) {
        console.error(`TradingViewChart: error setting data for ${ticker}`, err);
      }
    }

    return () => chart.remove();
  }, [data, ticker, isIntraday, timeframe]);

  // Subscribe to a streaming price if provided
  useEffect(() => {
    if (!priceStream) return;
    let unsub: (() => void) | void = undefined;
    try {
      unsub = priceStream.subscribe((p: number) => {
        setLivePrice(p);
      });
    } catch (e) {
      console.warn("TradingViewChart: priceStream subscribe failed", e);
    }
    return () => {
      try {
        if (typeof unsub === "function") unsub();
      } catch (e) {
        /* ignore */
      }
    };
  }, [priceStream]);

  const derivedPrice = currentPrice ?? livePrice ?? (data && data.length ? data[data.length - 1].close : undefined);

  return (
    <div className="bg-white rounded-xl shadow-lg p-4">
      <div className="flex items-baseline justify-between mb-3">
        <h3 className="text-lg font-bold">{ticker} Price Chart</h3>
        {typeof derivedPrice === "number" ? (
          <div data-testid="current-price" className="text-xl font-semibold text-gray-900">
            ${derivedPrice.toFixed(2)}
          </div>
        ) : null}
      </div>
      <div ref={containerRef} className="w-full" />
    </div>
  );
}