import React, { useCallback, useEffect, useRef, useState } from 'react';
import { createChart, CandlestickSeries, type IChartApi, type ISeriesApi, type Time, ColorType } from 'lightweight-charts';
import type { Theme, Timeframe } from '../../types';
import { fetchUpbitCandles } from '../../utils/upbitApi';

const TF_OPTIONS: Timeframe[] = ['1m', '5m', '15m', '1h', '4h', '1D'];

interface Props {
  market: string;
  theme?: Theme;
  wsLabel?: string;
  timeframe?: Timeframe;
  onTimeframeChange?: (tf: Timeframe) => void;
}

function readChartTheme(container: HTMLElement | null) {
  const root = container?.closest('.app') ?? document.documentElement;
  const s = getComputedStyle(root);
  const v = (name: string, fallback: string) => s.getPropertyValue(name).trim() || fallback;
  return {
    bgColor: v('--bg3', '#1f2335'),
    textColor: v('--text', '#c0caf5'),
    gridColor: v('--sep', 'rgba(122, 162, 247, 0.15)'),
    borderColor: v('--border', 'rgba(122, 162, 247, 0.15)'),
    upColor: v('--up', '#ff6b6b'),
    downColor: v('--down', '#4dabf7'),
  };
}

const PaperMiniChart: React.FC<Props> = ({
  market,
  theme = 'dark',
  wsLabel = 'WebSocket <100ms',
  timeframe: timeframeProp,
  onTimeframeChange,
}) => {
  const containerRef = useRef<HTMLDivElement>(null);
  const chartRef = useRef<IChartApi | null>(null);
  const seriesRef = useRef<ISeriesApi<'Candlestick'> | null>(null);
  const [timeframeInternal, setTimeframeInternal] = useState<Timeframe>('1h');
  const timeframe = timeframeProp ?? timeframeInternal;
  const setTimeframe = onTimeframeChange ?? setTimeframeInternal;
  const [loading, setLoading] = useState(true);

  const applyTheme = useCallback((chart: IChartApi, series: ISeriesApi<'Candlestick'>) => {
    const t = readChartTheme(containerRef.current);
    chart.applyOptions({
      layout: {
        background: { type: ColorType.Solid, color: t.bgColor },
        textColor: t.textColor,
      },
      grid: {
        vertLines: { color: t.gridColor },
        horzLines: { color: t.gridColor },
      },
      rightPriceScale: { borderColor: t.borderColor },
      timeScale: { borderColor: t.borderColor },
    });
    series.applyOptions({
      upColor: t.upColor,
      downColor: t.downColor,
      borderUpColor: t.upColor,
      borderDownColor: t.downColor,
      wickUpColor: t.upColor,
      wickDownColor: t.downColor,
    });
  }, []);

  useEffect(() => {
    if (!containerRef.current) return undefined;
    const t = readChartTheme(containerRef.current);
    const chart = createChart(containerRef.current, {
      layout: {
        background: { type: ColorType.Solid, color: t.bgColor },
        textColor: t.textColor,
      },
      grid: {
        vertLines: { color: t.gridColor },
        horzLines: { color: t.gridColor },
      },
      rightPriceScale: { borderColor: t.borderColor },
      timeScale: { borderColor: t.borderColor },
      crosshair: { mode: 1 },
    });
    const series = chart.addSeries(CandlestickSeries, {
      upColor: t.upColor,
      downColor: t.downColor,
      borderUpColor: t.upColor,
      borderDownColor: t.downColor,
      wickUpColor: t.upColor,
      wickDownColor: t.downColor,
    });
    chartRef.current = chart;
    seriesRef.current = series;

    const ro = new ResizeObserver(() => {
      if (containerRef.current) {
        chart.applyOptions({
          width: containerRef.current.clientWidth,
          height: containerRef.current.clientHeight,
        });
      }
    });
    ro.observe(containerRef.current);

    return () => {
      ro.disconnect();
      chart.remove();
      chartRef.current = null;
      seriesRef.current = null;
    };
  }, []);

  useEffect(() => {
    if (chartRef.current && seriesRef.current) {
      applyTheme(chartRef.current, seriesRef.current);
    }
  }, [theme, applyTheme]);

  useEffect(() => {
    let cancelled = false;
    setLoading(true);
    (async () => {
      try {
        const bars = await fetchUpbitCandles(market, timeframe, 200);
        if (cancelled || !seriesRef.current) return;
        seriesRef.current.setData(
          bars.map(b => ({
            time: b.time as Time,
            open: b.open,
            high: b.high,
            low: b.low,
            close: b.close,
          })),
        );
        chartRef.current?.timeScale().fitContent();
      } catch {
        /* ignore */
      } finally {
        if (!cancelled) setLoading(false);
      }
    })();
    return () => { cancelled = true; };
  }, [market, timeframe]);

  return (
    <div className="ptd-chart-wrap">
      <div className="ptd-chart-head">
        <span className="ptd-chart-title">실시간 분석 차트</span>
        <span className="ptd-ws-badge">{wsLabel} 실시간 데이터 반영</span>
      </div>
      <div ref={containerRef} className="ptd-chart-canvas" />
      {loading && <div className="ptd-chart-loading">차트 로딩…</div>}
      <div className="ptd-tf-row">
        {TF_OPTIONS.map(tf => (
          <button
            key={tf}
            type="button"
            className={`ptd-tf-btn${timeframe === tf ? ' ptd-tf-btn--active' : ''}`}
            onClick={() => setTimeframe(tf)}
          >
            {tf}
          </button>
        ))}
      </div>
    </div>
  );
};

export default PaperMiniChart;
