/**
 * 분석레포트 — 가상매매와 동일 3패널 (좌: 목록 · 중: 분석 · 우: 시그널)
 */
import React, { useCallback, useEffect, useMemo, useState } from 'react';
import type { Theme, Timeframe } from '../../types';
import {
  loadBacktestResults,
  deleteBacktestResult,
  deletePaperTradesBatch,
  loadPaperTrades,
  loadPaperSummary,
  loadStrategies,
  type BacktestResultRecord,
  type StrategyDto,
} from '../../utils/backendApi';
import {
  buildContextFromBacktest,
  buildContextFromLive,
} from '../../utils/analysisReportContext';
import { buildLiveExecutionItems, type LiveExecutionItem } from '../../utils/liveExecutionGroups';
import { PAPER_TRADES_CHANGED_EVENT, notifyPaperTradesChanged } from '../../utils/paperTradeEvents';
import BacktestExecutionList, { type ExecutionListTab } from '../backtest/BacktestExecutionList';
import BuilderPageShell from '../layout/BuilderPageShell';
import AnalysisReportCenterPanel from './AnalysisReportCenterPanel';
import AnalysisReportSignalsPanel from './AnalysisReportSignalsPanel';
import AnalysisReportContextBar from './AnalysisReportContextBar';
import BacktestAnalysisReportModal from '../backtest/BacktestAnalysisReportModal';
import {
  buildBacktestReportModel,
  buildLiveReportModel,
} from '../../utils/backtestReportModel';
import { enrichStrategyNameMap, strategyNamesFromList } from '../../utils/strategyNameResolver';
import { candleTypeToTimeframe } from '../../utils/strategyToChartIndicators';
import '../../styles/backtestDashboard.css';
import '../../styles/analysisReportPage.css';

interface Props {
  theme?: Theme;
}

function pickCompareBacktest(
  selected: BacktestResultRecord,
  records: BacktestResultRecord[],
): BacktestResultRecord | null {
  const others = records.filter(r => r.id !== selected.id);
  const sameSymbol = others.filter(r => r.symbol === selected.symbol);
  return sameSymbol[0] ?? others[0] ?? null;
}

export function AnalysisReportPage({ theme = 'dark' }: Props) {
  const [sourceTab, setSourceTab] = useState<ExecutionListTab>('backtest');
  const [records, setRecords] = useState<BacktestResultRecord[]>([]);
  const [liveItems, setLiveItems] = useState<LiveExecutionItem[]>([]);
  const [selectedBacktest, setSelectedBacktest] = useState<BacktestResultRecord | null>(null);
  const [selectedLive, setSelectedLive] = useState<LiveExecutionItem | null>(null);
  const [strategies, setStrategies] = useState<StrategyDto[]>([]);
  const [loading, setLoading] = useState(true);
  const [reportOpen, setReportOpen] = useState(false);

  const refreshLive = useCallback(async (backtestRecords: BacktestResultRecord[] = []) => {
    const [trades, summary, stratList] = await Promise.all([
      loadPaperTrades(),
      loadPaperSummary(),
      loadStrategies(),
    ]);
    setStrategies(stratList);
    const baseNames = strategyNamesFromList(stratList);
    const strategyNames = await enrichStrategyNameMap(
      baseNames,
      [
        ...trades.map(t => t.strategyId),
        ...backtestRecords.map(r => r.strategyId),
      ],
    );
    const live = buildLiveExecutionItems(trades, summary, strategyNames);
    setLiveItems(live);
    setSelectedLive(prev => (prev && live.some(x => x.id === prev.id) ? prev : live[0] ?? null));
    return strategyNames;
  }, []);

  const fetchAll = useCallback(async () => {
    setLoading(true);
    try {
      const [recs, stratList] = await Promise.all([
        loadBacktestResults(),
        loadStrategies(),
      ]);
      setStrategies(stratList);
      const strategyNames = await refreshLive(recs);
      const enrichedRecords = recs.map(r => ({
        ...r,
        strategyName: r.strategyName?.trim()
          || (r.strategyId != null ? strategyNames[r.strategyId] : undefined)
          || r.strategyName
          || '전략 없음',
      }));
      setRecords(enrichedRecords);
      setSelectedBacktest(prev => (
        prev && enrichedRecords.some(r => r.id === prev.id) ? prev : enrichedRecords[0] ?? null
      ));
    } finally {
      setLoading(false);
    }
  }, [refreshLive]);

  useEffect(() => { void fetchAll(); }, [fetchAll]);
  useEffect(() => {
    const onPaper = () => { void refreshLive(records); };
    window.addEventListener(PAPER_TRADES_CHANGED_EVENT, onPaper);
    return () => window.removeEventListener(PAPER_TRADES_CHANGED_EVENT, onPaper);
  }, [refreshLive, records]);

  const handleDeleteBacktest = useCallback(async (record: BacktestResultRecord) => {
    if (record.id == null) return;
    if (!window.confirm('이 백테스팅 결과를 삭제하시겠습니까?')) return;
    try {
      await deleteBacktestResult(record.id);
      setRecords(prev => {
        const next = prev.filter(r => r.id !== record.id);
        setSelectedBacktest(sel => (sel?.id === record.id ? next[0] ?? null : sel));
        return next;
      });
    } catch (e) {
      window.alert(e instanceof Error ? e.message : '삭제에 실패했습니다.');
    }
  }, []);

  const handleDeleteLive = useCallback(async (item: LiveExecutionItem) => {
    const ids = item.trades.map(t => t.id).filter(id => id > 0);
    if (ids.length === 0) return;
    if (!window.confirm(`실시간 매매 이력 ${ids.length}건을 삭제하시겠습니까?`)) return;
    try {
      const deleted = await deletePaperTradesBatch(ids);
      if (deleted <= 0) {
        window.alert('삭제할 체결 이력을 찾지 못했습니다.');
        return;
      }
      await refreshLive(records);
      notifyPaperTradesChanged();
    } catch (e) {
      window.alert(e instanceof Error ? e.message : '삭제에 실패했습니다.');
    }
  }, [refreshLive, records]);

  const compareBacktest = useMemo(() => {
    if (!selectedBacktest) return null;
    return pickCompareBacktest(selectedBacktest, records);
  }, [records, selectedBacktest]);

  const ctx = useMemo(() => {
    if (sourceTab === 'backtest' && selectedBacktest) {
      return buildContextFromBacktest(selectedBacktest, compareBacktest);
    }
    if (sourceTab === 'live' && selectedLive) {
      return buildContextFromLive(selectedLive);
    }
    return null;
  }, [sourceTab, selectedBacktest, selectedLive, compareBacktest]);

  const strategyNamesById = useMemo(
    () => Object.fromEntries(strategies.map(s => [s.id, s.name])),
    [strategies],
  );

  const reportModel = useMemo(() => {
    if (sourceTab === 'backtest' && selectedBacktest && ctx?.analysis) {
      return buildBacktestReportModel(
        selectedBacktest,
        ctx.analysis,
        ctx.signals,
        strategyNamesById,
      );
    }
    if (sourceTab === 'live' && selectedLive) {
      return buildLiveReportModel(selectedLive, ctx?.signals ?? []);
    }
    return null;
  }, [sourceTab, selectedBacktest, selectedLive, ctx, strategyNamesById]);

  const timelineFilter = useMemo(() => {
    if (sourceTab === 'live' && selectedLive) {
      return {
        symbol: selectedLive.symbol,
        strategyId: selectedLive.strategyId,
      };
    }
    if (sourceTab === 'backtest' && selectedBacktest) {
      return {
        symbol: selectedBacktest.symbol,
        strategyId: selectedBacktest.strategyId ?? null,
      };
    }
    return undefined;
  }, [sourceTab, selectedLive, selectedBacktest]);

  const timelineFilterLabel = useMemo(() => {
    if (sourceTab === 'live' && selectedLive) {
      return `${selectedLive.symbol} · ${selectedLive.strategyLabel}`;
    }
    if (sourceTab === 'backtest' && selectedBacktest) {
      return `${selectedBacktest.symbol} · ${selectedBacktest.strategyName}`;
    }
    return undefined;
  }, [sourceTab, selectedLive, selectedBacktest]);

  const timelineChartTimeframe = useMemo((): Timeframe => {
    if (sourceTab === 'live' && selectedLive?.timeframe) {
      return candleTypeToTimeframe(selectedLive.timeframe);
    }
    if (sourceTab === 'backtest' && selectedBacktest?.timeframe) {
      return candleTypeToTimeframe(selectedBacktest.timeframe);
    }
    return '3m';
  }, [sourceTab, selectedLive, selectedBacktest]);

  const headerActions = (
    <>
      <button type="button" className="btd-btn btd-btn--ghost" onClick={() => void fetchAll()}>새로고침</button>
      <button
        type="button"
        className="btd-btn btd-btn--gold"
        disabled={!reportModel}
        onClick={() => setReportOpen(true)}
      >
        인쇄 / PDF
      </button>
    </>
  );

  return (
    <>
      <BuilderPageShell
        theme={theme}
        title="분석레포트"
        subtitle="Golden Analysis Command Center"
        pageClassName="bps-page--arp"
        loading={loading}
        loadingText="분석레포트 로딩…"
        collapsiblePanels
        leftStorageKey="arp-left-width"
        leftDefaultWidth={380}
        leftCollapsedStorageKey="arp-left-open"
        rightStorageKey="arp-right-width"
        rightDefaultWidth={320}
        rightCollapsedStorageKey="arp-right-open"
        leftTitle="실행 목록"
        headerActions={headerActions}
        banner={<AnalysisReportContextBar model={reportModel} />}
        left={(
          <BacktestExecutionList
            tab={sourceTab}
            onTabChange={setSourceTab}
            backtestRecords={records}
            liveItems={liveItems}
            selectedBacktestId={selectedBacktest?.id ?? null}
            selectedLiveId={selectedLive?.id ?? null}
            onSelectBacktest={r => {
              setSelectedBacktest(r);
              setSourceTab('backtest');
            }}
            onSelectLive={item => {
              setSelectedLive(item);
              setSourceTab('live');
            }}
            onDeleteBacktest={r => void handleDeleteBacktest(r)}
            onDeleteLive={item => void handleDeleteLive(item)}
          />
        )}
        center={(
          <AnalysisReportCenterPanel
            model={reportModel}
            timelineFilter={timelineFilter}
            timelineFilterLabel={timelineFilterLabel}
            chartTimeframe={timelineChartTimeframe}
          />
        )}
        right={<AnalysisReportSignalsPanel model={reportModel} />}
      />

      <BacktestAnalysisReportModal
        open={reportOpen}
        onClose={() => setReportOpen(false)}
        model={reportModel}
      />
    </>
  );
}

export default AnalysisReportPage;
