/**
 * 매매 시그널 알림 행 — 캔들·지표 미니 차트 카드
 */
import React, {
  useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState,
} from 'react';
import TradingChart from '../TradingChart';
import type { IndicatorConfig } from '../../types';
import type {
  ChartMode, ChartType, Drawing, LegendData, OHLCVBar, Theme, Timeframe,
} from '../../types';
import { isUpbitMarket } from '../../utils/upbitApi';
import { useChartRealtimeData } from '../../hooks/useChartRealtimeData';
import { useHistoryLoader } from '../../hooks/useHistoryLoader';
import type { ChartManager } from '../../utils/ChartManager';
import { pinCandleWatch } from '../../utils/backendApi';
import { timeframeToCandleType } from '../../utils/chartCandleType';
import { DEFAULT_DISPLAY_TIMEZONE } from '../../utils/timezone';

interface Props {
  market: string;
  timeframe: Timeframe;
  theme?: Theme;
  indicators?: IndicatorConfig[];
  enabled?: boolean;
  /** 전체보기 모드 — 부모 높이에 맞춤 */
  fillHeight?: boolean;
  /** STOMP/WS 실시간 봉 수신 시 (목록 행 형광 플래시 등) */
  onRealtimeActivity?: () => void;
}

const noop = () => {};

const TradeSignalMiniChart: React.FC<Props> = ({
  market,
  timeframe,
  theme = 'dark',
  indicators = [],
  enabled = true,
  fillHeight = false,
  onRealtimeActivity,
}) => {
  const managerRef = useRef<ChartManager | null>(null);
  const canvasWrapRef = useRef<HTMLDivElement | null>(null);
  const [chartReloadTick, setChartReloadTick] = useState(0);
  const chartReloadTriggeredRef = useRef(false);
  const pendingBarRef = useRef<OHLCVBar | null>(null);
  const barsMarketRef = useRef<string | null>(null);
  const chartLiveReadyRef = useRef(false);
  const marketRef = useRef(market);
  marketRef.current = market;

  const handleCandlesReady = useCallback(() => {
    chartLiveReadyRef.current = true;
    const pending = pendingBarRef.current;
    const mgr = managerRef.current;
    if (!pending || !mgr || barsMarketRef.current !== marketRef.current) return;
    pendingBarRef.current = null;
    mgr.updateBar(pending);
    const wrap = canvasWrapRef.current;
    if (wrap && wrap.clientWidth > 0 && wrap.clientHeight > 0) {
      mgr.resetPaneHeights(wrap.clientHeight);
      mgr.resize(wrap.clientWidth, wrap.clientHeight);
    }
  }, []);

  const applyRealtimeBar = useCallback((bar: OHLCVBar, append: boolean) => {
    if (barsMarketRef.current !== marketRef.current) return;
    if (!chartLiveReadyRef.current || !managerRef.current) {
      pendingBarRef.current = bar;
      return;
    }
    if (append) managerRef.current.appendBar(bar);
    else managerRef.current.updateBar(bar);
  }, []);

  const handleTickUpdate = useCallback((bar: OHLCVBar) => {
    applyRealtimeBar(bar, false);
    onRealtimeActivity?.();
  }, [applyRealtimeBar, onRealtimeActivity]);

  const handleNewCandle = useCallback((bar: OHLCVBar) => {
    applyRealtimeBar(bar, true);
    onRealtimeActivity?.();
  }, [applyRealtimeBar, onRealtimeActivity]);

  const useUpbit = isUpbitMarket(market);

  const { bars, barsMarket, isLoading } = useChartRealtimeData(
    market,
    timeframe,
    useMemo(() => ({
      onTickUpdate: handleTickUpdate,
      onNewCandle: handleNewCandle,
      enabled: enabled && useUpbit,
      source: 'BACKEND_STOMP' as const,
    }), [handleTickUpdate, handleNewCandle, enabled, useUpbit]),
  );

  const { isLoadingMore } = useHistoryLoader({
    symbol: market,
    timeframe,
    isUpbit: useUpbit && enabled,
    managerRef,
  });

  barsMarketRef.current = barsMarket;
  const barsReady = bars.length >= 2 && barsMarket === market;

  const syncChartLayout = useCallback(() => {
    const wrap = canvasWrapRef.current;
    const mgr = managerRef.current;
    if (!wrap || !mgr?.hasMainSeries()) return;
    const w = wrap.clientWidth;
    const h = wrap.clientHeight;
    if (w <= 0 || h <= 0) return;
    mgr.resetPaneHeights(h);
    mgr.resize(w, h);
  }, []);

  useLayoutEffect(() => {
    chartLiveReadyRef.current = false;
    pendingBarRef.current = null;
    chartReloadTriggeredRef.current = false;
  }, [market, timeframe, enabled]);

  useEffect(() => {
    if (!enabled) return;
    const wrap = canvasWrapRef.current;
    if (!wrap) return;

    const timers = [200, 600, 1200].map(delay =>
      setTimeout(() => {
        if (!canvasWrapRef.current) return;
        const h = canvasWrapRef.current.clientHeight;
        if (h <= 0) return;
        const w = canvasWrapRef.current.clientWidth;
        if (managerRef.current?.hasMainSeries()) {
          if (w > 0) {
            managerRef.current.resetPaneHeights(h);
            managerRef.current.resize(w, h);
          }
        } else if (!chartReloadTriggeredRef.current && delay >= 600 && barsReady) {
          chartReloadTriggeredRef.current = true;
          setChartReloadTick(t => t + 1);
        }
      }, delay),
    );

    const ro = new ResizeObserver(() => syncChartLayout());
    ro.observe(wrap);
    return () => {
      timers.forEach(clearTimeout);
      ro.disconnect();
    };
  }, [market, timeframe, enabled, barsReady, syncChartLayout, fillHeight]);

  useEffect(() => {
    if (!enabled || !barsReady) return;
    if (!managerRef.current?.hasMainSeries() && !chartReloadTriggeredRef.current) {
      chartReloadTriggeredRef.current = true;
      setChartReloadTick(t => t + 1);
    }
  }, [enabled, barsReady]);

  useEffect(() => {
    if (!enabled) return;
    const t = setTimeout(() => syncChartLayout(), 80);
    return () => clearTimeout(t);
  }, [fillHeight, enabled, syncChartLayout]);

  useEffect(() => {
    if (!enabled || !useUpbit) return;
    void pinCandleWatch(market, timeframeToCandleType(timeframe));
    if (timeframeToCandleType(timeframe) !== '1m') {
      void pinCandleWatch(market, '1m');
    }
  }, [market, timeframe, enabled, useUpbit]);

  if (!enabled) {
    return (
      <div className={`tnl-mini-chart-placeholder${fillHeight ? ' tnl-mini-chart-placeholder--fill' : ''}`}>
        차트 대기
      </div>
    );
  }

  return (
    <div
      ref={canvasWrapRef}
      className={[
        'tnl-mini-chart-canvas',
        'slot-chart-wrap',
        fillHeight ? 'tnl-mini-chart-canvas--fill' : '',
      ].filter(Boolean).join(' ')}
    >
      {isLoading && <div className="tnl-mini-chart-loading">로딩…</div>}
      {isLoadingMore && (
        <div className="chart-history-loading">
          <div className="loading-spinner" style={{ width: 12, height: 12 }} />
        </div>
      )}
      <TradingChart
        key={`${market}-${timeframe}-${chartReloadTick}-${indicators.map(i => i.id).join(',')}`}
        chartVisible
        bars={bars}
        barsMarket={barsMarket}
        market={market}
        timeframe={timeframe}
        chartType={'candlestick' as ChartType}
        theme={theme}
        mode={'chart' as ChartMode}
        indicators={indicators}
        drawingTool="cursor"
        drawings={[] as Drawing[]}
        logScale={false}
        drawingsLocked
        drawingsVisible={false}
        onCrosshair={noop as (d: LegendData | null) => void}
        onManagerReady={mgr => { managerRef.current = mgr; }}
        onAddDrawing={noop as (d: Drawing) => void}
        onCandlesReady={handleCandlesReady}
        magnifierEnabled={false}
        volumeVisible={false}
        showHoverToolbar={false}
        seriesPriceLabelsEnabled={false}
        paneLayoutClamp
        showPaneLegend={false}
      />
    </div>
  );
};

export default TradeSignalMiniChart;
