import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import type { Theme } from '../types';
import {
  loadPaperSummary,
  loadPaperTrades,
  loadStrategies,
  type PaperSummaryDto,
  type PaperTradeDto,
  type StrategyDto,
} from '../utils/backendApi';
import {
  flushPendingUiPreferences,
  getUiPreferences,
  patchUiPreferences,
  subscribeUiPreferences,
} from '../utils/uiPreferencesDb';
import { defaultWidgetLayout, normalizeWidgetLayout, type WidgetLayoutSchema } from '../types/widgetDashboard';
import { WidgetDashboardProvider } from '../widgets/WidgetDashboardContext';
import WidgetDashboardShell from './widgetDashboard/WidgetDashboardShell';
import { PAPER_TRADES_CHANGED_EVENT } from '../utils/paperTradeEvents';
import { useMarketTicker } from '../hooks/useMarketTicker';
import type { ChartRealtimeSource } from '../hooks/useChartRealtimeData';
import { useChartWorkspaceContext } from '../chart/ChartWorkspaceContext';
import { useAppSettings } from '../hooks/useAppSettings';
import '../styles/widgetDashboard.css';

interface Props {
  theme: Theme;
  paperTradingEnabled: boolean;
  paperAutoTradeEnabled: boolean;
  onPaperOrderFilled?: () => void;
  chartRealtimeSource?: ChartRealtimeSource;
}

function readWidgetLayoutFromPrefs(): WidgetLayoutSchema {
  return normalizeWidgetLayout(getUiPreferences().widgetDashboard ?? defaultWidgetLayout());
}

const WidgetDashboardPage: React.FC<Props> = ({
  theme,
  paperTradingEnabled,
  paperAutoTradeEnabled,
  onPaperOrderFilled,
  chartRealtimeSource = 'BACKEND_STOMP',
}) => {
  const { isLoaded: appSettingsLoaded } = useAppSettings();
  const { symbol: defaultMarket } = useChartWorkspaceContext();
  const { tickers, marketInfos, loading: marketLoading, usdRate } = useMarketTicker(
    useMemo(() => ({ enabled: true, loadFull: true }), []),
  );
  const [layout, setLayout] = useState<WidgetLayoutSchema>(defaultWidgetLayout);
  const [strategies, setStrategies] = useState<StrategyDto[]>([]);
  const [summary, setSummary] = useState<PaperSummaryDto | null>(null);
  const [trades, setTrades] = useState<PaperTradeDto[]>([]);
  const layoutJsonRef = useRef('');

  useEffect(() => {
    if (!appSettingsLoaded) return;
    const next = readWidgetLayoutFromPrefs();
    const json = JSON.stringify(next);
    if (json !== layoutJsonRef.current) {
      layoutJsonRef.current = json;
      setLayout(next);
    }
  }, [appSettingsLoaded]);

  useEffect(() => {
    if (!appSettingsLoaded) return;
    return subscribeUiPreferences(() => {
      const next = readWidgetLayoutFromPrefs();
      const json = JSON.stringify(next);
      if (json === layoutJsonRef.current) return;
      layoutJsonRef.current = json;
      setLayout(next);
    });
  }, [appSettingsLoaded]);

  useEffect(() => {
    const flush = () => { flushPendingUiPreferences(); };
    window.addEventListener('beforeunload', flush);
    window.addEventListener('pagehide', flush);
    return () => {
      window.removeEventListener('beforeunload', flush);
      window.removeEventListener('pagehide', flush);
      flush();
    };
  }, []);

  const persistLayout = useCallback((
    next: WidgetLayoutSchema,
    opts?: { immediate?: boolean },
  ) => {
    const normalized = normalizeWidgetLayout(next);
    layoutJsonRef.current = JSON.stringify(normalized);
    setLayout(normalized);
    if (!appSettingsLoaded) return;
    patchUiPreferences({ widgetDashboard: normalized }, opts?.immediate ?? false);
  }, [appSettingsLoaded]);

  const refreshPaperData = useCallback(async () => {
    try {
      const [sum, tr] = await Promise.all([loadPaperSummary(), loadPaperTrades()]);
      setSummary(sum);
      setTrades(tr ?? []);
    } catch { /* ignore */ }
  }, []);

  useEffect(() => {
    void loadStrategies().then(list => setStrategies(list ?? []));
    void refreshPaperData();
  }, [refreshPaperData]);

  useEffect(() => {
    const onChanged = () => { void refreshPaperData(); };
    window.addEventListener(PAPER_TRADES_CHANGED_EVENT, onChanged);
    return () => window.removeEventListener(PAPER_TRADES_CHANGED_EVENT, onChanged);
  }, [refreshPaperData]);

  if (!appSettingsLoaded) {
    return <div className="wd-loading">위젯 대시보드 로딩…</div>;
  }

  return (
    <WidgetDashboardProvider
      theme={theme}
      tickers={tickers}
      marketInfos={marketInfos}
      marketLoading={marketLoading}
      usdRate={usdRate}
      defaultMarket={defaultMarket}
      strategies={strategies}
      summary={summary}
      trades={trades}
      refreshPaperData={() => { void refreshPaperData(); }}
      paperTradingEnabled={paperTradingEnabled}
      paperAutoTradeEnabled={paperAutoTradeEnabled}
      onPaperOrderFilled={onPaperOrderFilled}
      chartRealtimeSource={chartRealtimeSource}
    >
      <WidgetDashboardShell
        theme={theme}
        layout={layout}
        onLayoutChange={persistLayout}
      />
    </WidgetDashboardProvider>
  );
};

export default WidgetDashboardPage;
