import React, { useCallback, useEffect, useMemo, useState } from 'react';
import VirtualTargetCard, { type VirtualCardDisplayMode } from './VirtualTargetCard';
import VirtualTargetFocusView from './VirtualTargetFocusView';
import type { StrategyDto } from '../../utils/backendApi';
import type { Theme } from '../../types';
import type { ChartRealtimeSource } from '../../hooks/useChartRealtimeData';
import {
  type VirtualTargetItem,
  type VirtualCardViewMode,
  type VirtualSessionConfig,
} from '../../utils/virtualTradingStorage';
import type { VirtualLiveStatus } from '../../hooks/useVirtualTargetLiveStatus';
import type { VirtualIndicatorSnapshot } from '../../hooks/useVirtualIndicatorSnapshots';
import type { TickerData } from '../../hooks/useMarketTicker';
import { resolveVirtualTargetStrategyId } from '../../utils/virtualTargetStrategy';
import {
  getTradeNotificationGridPreset,
  type TradeNotificationGridPresetId,
} from '../../utils/tradeNotificationGridPresets';

interface Props {
  targets: VirtualTargetItem[];
  strategies: StrategyDto[];
  snapshots: Record<string, VirtualIndicatorSnapshot>;
  snapshotLoadingByMarket?: Record<string, boolean>;
  session: Pick<VirtualSessionConfig, 'globalStrategyId' | 'executionType' | 'positionMode' | 'running'>;
  onTargetStrategyChange: (market: string, strategyId: number | null) => void;
  liveStatusByMarket?: Record<string, VirtualLiveStatus>;
  lastTickAtByMarket?: Record<string, number>;
  selectedMarket?: string;
  onSelectMarket?: (market: string) => void;
  theme?: Theme;
  chartRealtimeSource?: ChartRealtimeSource;
  chartCandleAreaPriceLabels?: boolean;
  chartSeriesPriceLabels?: boolean;
  chartPaneSeparator?: import('../../types/chartPaneSeparator').ChartPaneSeparatorOptions;
  chartLiveReceiveHighlight?: boolean;
  tickers?: Map<string, TickerData>;
  viewMode: VirtualCardViewMode;
  globalDisplayMode: VirtualCardDisplayMode;
  onFocusMarketChange?: (market: string | null) => void;
  gridPreset: TradeNotificationGridPresetId;
}

const VirtualTargetGrid: React.FC<Props> = ({
  targets, strategies, snapshots, snapshotLoadingByMarket = {}, session,
  onTargetStrategyChange,
  liveStatusByMarket = {}, lastTickAtByMarket = {}, selectedMarket,
  onSelectMarket,
  theme = 'dark',
  chartRealtimeSource = 'BACKEND_STOMP',
  chartCandleAreaPriceLabels = true,
  chartSeriesPriceLabels = true,
  chartPaneSeparator,
  chartLiveReceiveHighlight = true,
  tickers,
  viewMode,
  globalDisplayMode,
  onFocusMarketChange,
  gridPreset,
}) => {
  const gridCols = getTradeNotificationGridPreset(gridPreset).cols;
  const [cardDisplayOverrides, setCardDisplayOverrides] = useState<Record<string, VirtualCardDisplayMode>>({});
  const [focusMarket, setFocusMarket] = useState<string | null>(null);

  const activeMarkets = useMemo(() => new Set(targets.map(t => t.market)), [targets]);

  useEffect(() => {
    if (focusMarket && !activeMarkets.has(focusMarket)) {
      setFocusMarket(null);
      onFocusMarketChange?.(null);
    }
  }, [activeMarkets, focusMarket, onFocusMarketChange]);

  useEffect(() => {
    onFocusMarketChange?.(focusMarket);
  }, [focusMarket, onFocusMarketChange]);

  useEffect(() => {
    setCardDisplayOverrides(prev => {
      const next: Record<string, VirtualCardDisplayMode> = {};
      let changed = false;
      for (const [market, mode] of Object.entries(prev)) {
        if (activeMarkets.has(market)) next[market] = mode;
        else changed = true;
      }
      return changed ? next : prev;
    });
  }, [activeMarkets]);

  useEffect(() => {
    setCardDisplayOverrides({});
  }, [globalDisplayMode]);

  const handleCardDisplayMode = useCallback((market: string, mode: VirtualCardDisplayMode) => {
    setCardDisplayOverrides(prev => ({ ...prev, [market]: mode }));
  }, []);

  const resolveCardDisplayMode = useCallback(
    (market: string) => cardDisplayOverrides[market] ?? globalDisplayMode,
    [cardDisplayOverrides, globalDisplayMode],
  );

  const focusTarget = useMemo(
    () => (focusMarket ? targets.find(t => t.market === focusMarket) : undefined),
    [focusMarket, targets],
  );

  if (targets.length === 0) {
    return (
      <div className="vtd-grid-wrap">
        <div className="vtd-grid-empty">
          <p className="vtd-muted">좌측에서 투자대상 종목을 추가하면 카드가 표시됩니다.</p>
        </div>
      </div>
    );
  }

  return (
    <div className={`vtd-grid-wrap${focusMarket ? ' vtd-grid-wrap--focus' : ''}`}>
      {focusMarket && focusTarget ? (
        <VirtualTargetFocusView
          market={focusTarget.market}
          strategy={strategies.find(s => s.id === resolveVirtualTargetStrategyId(focusTarget, session.globalStrategyId))}
          strategies={strategies}
          strategyId={focusTarget.strategyId}
          globalStrategyId={session.globalStrategyId}
          onStrategyChange={id => onTargetStrategyChange(focusTarget.market, id)}
          snapshot={snapshots[focusTarget.market]}
          signalLoading={snapshotLoadingByMarket[focusTarget.market]}
          running={session.running}
          liveStatus={liveStatusByMarket[focusTarget.market] ?? (session.running ? 'connecting' : 'idle')}
          lastTickAt={lastTickAtByMarket[focusTarget.market]}
          viewMode={viewMode}
          onExit={() => setFocusMarket(null)}
          theme={theme}
          chartRealtimeSource={chartRealtimeSource}
          chartCandleAreaPriceLabels={chartCandleAreaPriceLabels}
          chartSeriesPriceLabels={chartSeriesPriceLabels}
          chartPaneSeparator={chartPaneSeparator}
          chartLiveReceiveHighlight={chartLiveReceiveHighlight}
          ticker={tickers?.get(focusTarget.market)}
          koreanName={focusTarget.koreanName}
          englishName={focusTarget.englishName}
        />
      ) : (
        <div
          className={[
            'vtd-grid',
            'vtd-grid--layout-preset',
            `vtd-grid--${viewMode}`,
            `vtd-grid--cols-${gridCols}`,
          ].join(' ')}
          style={{ ['--vtd-grid-cols' as string]: gridCols }}
        >
          {targets.map(t => {
            const strat = strategies.find(s => s.id === resolveVirtualTargetStrategyId(t, session.globalStrategyId));
            return (
              <VirtualTargetCard
                key={t.market}
                market={t.market}
                strategy={strat}
                strategies={strategies}
                strategyId={t.strategyId}
                globalStrategyId={session.globalStrategyId}
                onStrategyChange={id => onTargetStrategyChange(t.market, id)}
                snapshot={snapshots[t.market]}
                signalLoading={snapshotLoadingByMarket[t.market]}
                running={session.running}
                liveStatus={liveStatusByMarket[t.market] ?? (session.running ? 'connecting' : 'idle')}
                lastTickAt={lastTickAtByMarket[t.market]}
                viewMode={viewMode}
                displayMode={resolveCardDisplayMode(t.market)}
                onDisplayModeChange={mode => handleCardDisplayMode(t.market, mode)}
                onEnterFocus={() => setFocusMarket(t.market)}
                selected={t.market === selectedMarket}
                onSelect={onSelectMarket ? () => onSelectMarket(t.market) : undefined}
                theme={theme}
                chartRealtimeSource={chartRealtimeSource}
                chartCandleAreaPriceLabels={chartCandleAreaPriceLabels}
          chartSeriesPriceLabels={chartSeriesPriceLabels}
          chartPaneSeparator={chartPaneSeparator}
                chartLiveReceiveHighlight={chartLiveReceiveHighlight}
                ticker={tickers?.get(t.market)}
                koreanName={t.koreanName}
                englishName={t.englishName}
              />
            );
          })}
        </div>
      )}
    </div>
  );
};

export default VirtualTargetGrid;
