"use client";

import { useEffect, useMemo, useRef } from "react";
import {
  CandlestickSeries,
  ColorType,
  createChart,
  CrosshairMode,
  LineStyle,
  UTCTimestamp,
} from "lightweight-charts";
import { ChartCandle } from "../lib/demo";

type PriceLevels = {
  entry?: number;
  stopLoss?: number;
  takeProfit1?: number;
  takeProfit2?: number;
};

type CandlestickChartProps = {
  candles?: ChartCandle[];
  values?: number[];
  anchorTime?: string;
  levels?: PriceLevels;
  compact?: boolean;
  label?: string;
};

function fallbackCandles(values: number[], anchorTime?: string): ChartCandle[] {
  const end = Number.isFinite(Date.parse(anchorTime ?? "")) ? Date.parse(anchorTime!) : Date.now();
  return values.map((close, index) => {
    const open = index ? values[index - 1] : close;
    const body = Math.max(Math.abs(close - open), Math.abs(close) * .00035, .00001);
    return {
      time: new Date(end - (values.length - 1 - index) * 3_600_000).toISOString(),
      open,
      high: Math.max(open, close) + body * .42,
      low: Math.min(open, close) - body * .38,
      close,
    };
  });
}

export function CandlestickChart({ candles, values = [], anchorTime, levels, compact = false, label = "Chart candlestick" }: CandlestickChartProps) {
  const containerRef = useRef<HTMLDivElement>(null);
  const chartData = useMemo(() => {
    const source = candles?.length ? candles : fallbackCandles(values, anchorTime);
    const unique = new Map<number, ChartCandle>();
    for (const candle of source) {
      const seconds = Math.floor(Date.parse(candle.time) / 1000);
      if (Number.isFinite(seconds)) unique.set(seconds, candle);
    }
    return [...unique.entries()]
      .sort((a, b) => a[0] - b[0])
      .map(([time, candle]) => ({
        time: time as UTCTimestamp,
        open: candle.open,
        high: candle.high,
        low: candle.low,
        close: candle.close,
      }));
  }, [anchorTime, candles, values]);

  useEffect(() => {
    const container = containerRef.current;
    if (!container || !chartData.length) return;

    const chart = createChart(container, {
      autoSize: true,
      height: compact ? 116 : 252,
      layout: {
        background: { type: ColorType.Solid, color: "#181713" },
        textColor: compact ? "rgba(251,247,238,.48)" : "rgba(251,247,238,.62)",
        attributionLogo: false,
        fontFamily: '"DM Mono", ui-monospace, monospace',
        fontSize: compact ? 9 : 10,
      },
      grid: {
        vertLines: { color: "rgba(251,247,238,.055)" },
        horzLines: { color: "rgba(251,247,238,.055)" },
      },
      crosshair: { mode: CrosshairMode.Normal },
      rightPriceScale: { borderColor: "rgba(251,247,238,.12)", scaleMargins: { top: .14, bottom: .14 } },
      timeScale: {
        borderColor: "rgba(251,247,238,.12)",
        timeVisible: !compact,
        secondsVisible: false,
        rightOffset: compact ? 1 : 3,
        barSpacing: compact ? 7 : 9,
        minBarSpacing: 3,
      },
      handleScroll: !compact,
      handleScale: !compact,
    });

    const series = chart.addSeries(CandlestickSeries, {
      upColor: "#2f9a73",
      downColor: "#c64652",
      wickUpColor: "#72c6a5",
      wickDownColor: "#e17b84",
      borderVisible: false,
      priceLineVisible: false,
      lastValueVisible: !compact,
    });
    series.setData(chartData);

    const priceLines = [
      levels?.takeProfit2 ? { price: levels.takeProfit2, color: "#56b88f", title: "TP2" } : null,
      levels?.takeProfit1 ? { price: levels.takeProfit1, color: "#79caaa", title: "TP1" } : null,
      levels?.entry ? { price: levels.entry, color: "#d8a137", title: "ENTRY" } : null,
      levels?.stopLoss ? { price: levels.stopLoss, color: "#d95a66", title: "SL" } : null,
    ].filter(Boolean) as Array<{ price: number; color: string; title: string }>;

    for (const line of priceLines) {
      series.createPriceLine({
        ...line,
        lineWidth: 1,
        lineStyle: LineStyle.Dashed,
        axisLabelVisible: !compact,
      });
    }
    chart.timeScale().fitContent();
    if (priceLines.length) {
      const prices = chartData.flatMap(item => [item.high, item.low]).concat(priceLines.map(item => item.price));
      const minimum = Math.min(...prices);
      const maximum = Math.max(...prices);
      const padding = Math.max((maximum - minimum) * .08, Math.abs(maximum) * .0004, .00001);
      chart.priceScale("right").setVisibleRange({ from: minimum - padding, to: maximum + padding });
    }
    return () => chart.remove();
  }, [chartData, compact, levels?.entry, levels?.stopLoss, levels?.takeProfit1, levels?.takeProfit2]);

  return <div ref={containerRef} className={`candlestick-chart ${compact ? "is-compact" : ""}`} role="img" aria-label={label} />;
}
