import { useEffect, useMemo, useRef } from "react";
import {
  ColorType,
  HistogramSeries,
  LineSeries,
  createChart,
  type IChartApi,
  type ISeriesApi,
  type UTCTimestamp,
} from "lightweight-charts";
import type { IndicatorPoint } from "../lib/technicalIndicators";

export interface OscLine {
  name: string;
  color: string;
  points: IndicatorPoint[];
}

function toTime(date: string) {
  return (Date.parse(date + "T00:00:00Z") / 1000) as UTCTimestamp;
}

export default function OscillatorChart({
  title,
  lines = [],
  hist,
  refLines = [],
  heightClass = "osc-chart",
}: {
  title: string;
  lines?: OscLine[];
  hist?: IndicatorPoint[];
  refLines?: { value: number; color: string; label?: string }[];
  heightClass?: string;
}) {
  const ref = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);
  const lineRefs = useRef<ISeriesApi<"Line">[]>([]);
  const histRef = useRef<ISeriesApi<"Histogram"> | null>(null);

  const hasData = useMemo(
    () => lines.some((l) => l.points.length > 1) || (hist && hist.length > 1),
    [lines, hist],
  );

  useEffect(() => {
    if (!ref.current) return;
    const chart = createChart(ref.current, {
      layout: { background: { type: ColorType.Solid, color: "transparent" }, textColor: "#9aa8cc", fontSize: 10 },
      grid: { vertLines: { visible: false }, horzLines: { color: "rgba(255,255,255,.05)" } },
      rightPriceScale: { borderVisible: false },
      timeScale: { borderVisible: false, visible: false },
      crosshair: { vertLine: { visible: false }, horzLine: { visible: false } },
      autoSize: true,
    });
    const h = hist
      ? chart.addSeries(HistogramSeries, { priceFormat: { type: "price", precision: 4, minMove: 0.0001 } })
      : null;
    const ls = lines.map((l) =>
      chart.addSeries(LineSeries, {
        color: l.color,
        lineWidth: 1,
        priceLineVisible: false,
        lastValueVisible: true,
        crosshairMarkerRadius: 0,
      }),
    );
    chartRef.current = chart;
    lineRefs.current = ls;
    histRef.current = h;
    return () => {
      chart.remove();
      chartRef.current = null;
      lineRefs.current = [];
      histRef.current = null;
    };
  }, [lines.length, !!hist]);

  useEffect(() => {
    if (!chartRef.current) return;
    lines.forEach((l, i) => {
      lineRefs.current[i]?.setData(l.points.map((p) => ({ time: toTime(p.date), value: p.value })));
    });
    if (histRef.current && hist) {
      histRef.current.setData(
        hist.map((p) => ({
          time: toTime(p.date),
          value: p.value,
          color: p.value >= 0 ? "rgba(232,106,82,.45)" : "rgba(111,207,151,.45)",
        })),
      );
    }
    chartRef.current.timeScale().fitContent();
  }, [lines, hist]);

  if (!hasData) return null;

  return (
    <div className="osc-wrap">
      <div className="osc-title">
        {title}
        {lines.map((l) => (
          <span key={l.name} className="osc-legend">
            <i style={{ background: l.color }} />
            {l.name}
          </span>
        ))}
        {refLines.map((r) => (
          <span key={r.label || r.value} className="osc-ref">
            {r.label || r.value}
          </span>
        ))}
      </div>
      <div ref={ref} className={heightClass} />
    </div>
  );
}