import { useWebSocket } from '@/hooks/useWebSocket';
import { ArrowLeftIcon, PlusIcon } from '@heroicons/react/24/outline';
import { useCallback, useEffect, useState } from 'react';
import { useNavigate, useParams } from 'react-router-dom';
import { BacktestConfiguration } from './components/BacktestConfiguration';
import { BacktestPlayback } from './components/BacktestPlayback';
import { BacktestTrades } from './components/BacktestTrades';
import { RunControlsCompact } from './components/RunControlsCompact';
import { RunsListWithMetrics } from './components/RunsListWithMetrics';
import { useBacktestV2 } from './hooks/useBacktestV2';
import type { BacktestConfig } from './types/backtest.types';

const baseTabs = [
  { id: 'runs', name: 'Runs' },
  { id: 'settings', name: 'Settings' },
];

const runTabs = [
  { id: 'details', name: 'Details' },
  { id: 'trades', name: 'Trades' },
];

export function BacktestDetailPageV2() {
  const { id, runId } = useParams<{ id: string; runId?: string }>();
  const navigate = useNavigate();
  const [activeTab, setActiveTab] = useState('details');
  const [showNewRun, setShowNewRun] = useState(false);
  
  const {
    backtest,
    runs,
    currentRun,
    runResults,
    isLoading,
    error,
    loadBacktest,
    updateBacktest,
    createRun,
    pauseRun,
    resumeRun,
    cancelRun,
    updateRunSpeed,
    selectRun,
  } = useBacktestV2();

  // WebSocket connection for real-time updates
  const { isConnected } = useWebSocket({
    runId: currentRun?.id || null,
    onProgress: (progress, currentDate) => {
      // Update the run progress in the UI
      if (currentRun) {
        // This will trigger a re-render with updated progress
        console.log('Progress update:', progress, currentDate);
      }
    },
    onError: (error) => {
      console.error('Run error:', error);
      // Reload runs to get updated status
      if (id) {
        loadBacktest(id);
      }
    },
    onCompleted: async (results) => {
      // When run completes, reload to get the final results
      if (currentRun?.id) {
        try {
          // Small delay to ensure the results are persisted
          await new Promise(resolve => setTimeout(resolve, 500));
          // Force re-select the run to load its results
          await selectRun(currentRun.id);
        } catch (err) {
          console.error('Failed to load completed run results:', err);
        }
      }
    }
  });

  // Load backtest on mount
  useEffect(() => {
    if (id) {
      loadBacktest(id);
    }
  }, [id, loadBacktest]);
  
  // Clear mismatched results immediately
  useEffect(() => {
    if (runResults && currentRun && runResults.runId !== currentRun.id) {
      console.warn('Run results mismatch:', {
        runResultsId: runResults.runId,
        currentRunId: currentRun.id
      });
      // Clear the mismatched results immediately to prevent rendering wrong data
      // The selectRun effect will load the correct results
    }
  }, [runResults?.runId, currentRun?.id]);
  
  // We don't need this effect anymore - it's causing unnecessary re-renders
  // The selectRun function already handles clearing mismatched results

  // Select run based on URL parameter with debounce
  useEffect(() => {
    const timeoutId = setTimeout(() => {
      if (runId) {
        // If the current run already matches, don't re-select
        if (currentRun?.id === runId) {
          return;
        }
        
        // Always try to select the run - selectRun will fetch it if not found
        selectRun(runId);
        
        // Show details tab by default when a run is selected
        if (activeTab === 'runs') {
          setActiveTab('details');
        }
      } else if (!runId && currentRun) {
        // Clear run selection when navigating away from run URL
        selectRun(undefined);
        setActiveTab('runs');
      }
    }, 50); // Small debounce to prevent rapid switching
    
    return () => clearTimeout(timeoutId);
  }, [runId, currentRun?.id, selectRun, activeTab]);

  // Handle configuration save
  const handleConfigSubmit = useCallback(async (config: BacktestConfig) => {
    if (!id) return;
    
    await updateBacktest(id, {
      name: config.name,
      strategy: config.strategy,
      symbols: config.symbols,
      startDate: config.startDate.toISOString().split('T')[0],
      endDate: config.endDate.toISOString().split('T')[0],
      initialCapital: config.initialCapital,
      config: {
        commission: config.commission,
        slippage: config.slippage,
        speedMultiplier: config.speedMultiplier,
      },
    });
  }, [id, updateBacktest]);

  // Handle new run creation
  const handleCreateRun = useCallback(async (speedMultiplier: number) => {
    const newRun = await createRun(speedMultiplier);
    setShowNewRun(false);
    // Navigate to the new run
    if (newRun && id) {
      navigate(`/backtests/${id}/run/${newRun.id}`);
    }
  }, [createRun, navigate, id]);

  // Handle rerun
  const handleRerun = useCallback(async (speedMultiplier: number | null) => {
    // Pass null for max speed (no limit)
    const newRun = await createRun(speedMultiplier ?? undefined);
    
    // Navigate to the new run's URL
    if (newRun && id) {
      navigate(`/backtests/${id}/run/${newRun.id}`);
    }
  }, [createRun, navigate, id]);

  // Convert backtest to config format for the form
  const backtestConfig: BacktestConfig | undefined = backtest ? {
    name: backtest.name,
    startDate: new Date(backtest.startDate),
    endDate: new Date(backtest.endDate),
    initialCapital: backtest.initialCapital,
    symbols: backtest.symbols,
    strategy: backtest.strategy,
    speedMultiplier: 1,
    commission: backtest.config?.commission ?? 0.001,
    slippage: backtest.config?.slippage ?? 0.0001,
  } : undefined;

  const renderTabContent = () => {
    // Show message if trying to view run-specific tabs without a run selected
    if (!currentRun && ['details', 'trades'].includes(activeTab)) {
      return (
        <div className="flex items-center justify-center h-full">
          <div className="text-center">
            <p className="text-text-secondary mb-4">Please select a run to view {activeTab}</p>
            <button
              onClick={() => setActiveTab('runs')}
              className="text-primary-500 hover:text-primary-600 font-medium"
            >
              Go to Runs
            </button>
          </div>
        </div>
      );
    }
    
    switch (activeTab) {
      case 'runs':
        return (
          <div className="space-y-4">
            <div className="flex justify-between items-center">
              <h3 className="text-lg font-medium text-text-primary">Run History</h3>
              <button
                onClick={() => setShowNewRun(true)}
                className="inline-flex items-center px-4 py-2 bg-primary-500 text-white rounded-md text-sm font-medium hover:bg-primary-600 transition-colors"
              >
                <PlusIcon className="w-4 h-4 mr-2" />
                New Run
              </button>
            </div>
            
            {showNewRun && (
              <div className="bg-surface-secondary rounded-lg border border-border p-4 space-y-4">
                <h4 className="text-base font-medium text-text-primary">Start New Run</h4>
                <p className="text-sm text-text-secondary">
                  This will start a new backtest run with the current configuration.
                </p>
                <div className="flex space-x-2">
                  <button
                    onClick={() => {
                      handleCreateRun(1000); // Always use max speed
                    }}
                    className="px-4 py-2 bg-primary-500 text-white rounded-md text-sm font-medium hover:bg-primary-600 transition-colors"
                  >
                    Start Run
                  </button>
                  <button
                    onClick={() => setShowNewRun(false)}
                    className="px-4 py-2 bg-surface-tertiary text-text-primary rounded-md text-sm font-medium hover:bg-surface-secondary transition-colors"
                  >
                    Cancel
                  </button>
                </div>
              </div>
            )}
            
            <RunsListWithMetrics
              runs={runs}
              currentRunId={currentRun?.id}
              onSelectRun={selectRun}
            />
          </div>
        );
      case 'settings':
        return (
          <div className="max-w-4xl mx-auto">
            <BacktestConfiguration
              onSubmit={handleConfigSubmit}
              disabled={false}
              initialConfig={backtestConfig}
            />
          </div>
        );
      case 'details':
        // Only render if we have matching results or no results yet
        if (runResults && currentRun && runResults.runId !== currentRun.id) {
          return (
            <div className="h-full flex items-center justify-center">
              <div className="text-text-secondary">Loading run data...</div>
            </div>
          );
        }
        
        return (
          <div className="h-full overflow-hidden">
            <BacktestPlayback
              key={currentRun?.id || 'no-run'} // Force remount on run change
              result={runResults}
              isLoading={isLoading}
            />
          </div>
        );
      case 'trades':
        return (
          <div className="h-full overflow-y-auto">
            <BacktestTrades
              result={runResults}
              isLoading={isLoading}
            />
          </div>
        );
      default:
        return null;
    }
  };

  if (!backtest && !isLoading) {
    return (
      <div className="h-full flex items-center justify-center">
        <div className="text-center">
          <p className="text-text-secondary mb-4">Backtest not found</p>
          <button
            onClick={() => navigate('/backtests')}
            className="text-primary-500 hover:text-primary-600"
          >
            Back to Backtests
          </button>
        </div>
      </div>
    );
  }

  return (
    <div className="h-full flex flex-col">
      {/* Header with Tabs */}
      <div className="flex-shrink-0 border-b border-border">
        <div className="flex items-center justify-between">
          <div className="flex items-center flex-1">
            <button
              onClick={() => navigate('/backtests')}
              className="p-2 hover:bg-surface-tertiary transition-colors"
              aria-label="Back to backtests"
            >
              <ArrowLeftIcon className="h-5 w-5 text-text-secondary" />
            </button>
            <div className="px-2">
              <h1 className="text-sm font-bold text-text-primary flex items-center gap-1">
                {backtest?.name || 'Loading...'}
                {currentRun && (
                  <span className="text-text-secondary font-normal">
                    - Run #{currentRun.runNumber}
                  </span>
                )}
              </h1>
              <p className="text-xs text-text-secondary">
                {backtest?.strategy || ''} • {backtest?.symbols.join(', ') || ''}
              </p>
            </div>
            
            {/* Tabs */}
            <nav className="flex ml-4" aria-label="Tabs">
              {(currentRun ? runTabs : []).concat(baseTabs).map((tab) => (
                <button
                  key={tab.id}
                  onClick={() => setActiveTab(tab.id)}
                  className={`
                    whitespace-nowrap py-2 px-3 border-b-2 font-medium text-sm
                    ${activeTab === tab.id
                      ? 'border-primary-500 text-primary-500'
                      : 'border-transparent text-text-secondary hover:text-text-primary hover:border-border'
                    }
                  `}
                >
                  {tab.name}
                </button>
              ))}
            </nav>
          </div>
          
          {/* Run Controls */}
          {currentRun && (
            <div className="px-4">
              <RunControlsCompact
                run={currentRun}
                onPause={pauseRun}
                onResume={resumeRun}
                onRerun={handleRerun}
                onSpeedChange={updateRunSpeed}
              />
            </div>
          )}
        </div>
      </div>

      {/* Tab Content */}
      <div className="flex-1 overflow-hidden py-4">
        {error && (
          <div className="mb-4 p-4 bg-error/10 border border-error/20 rounded-lg">
            <p className="text-sm text-error">{error}</p>
          </div>
        )}
        {renderTabContent()}
      </div>
    </div>
  );
}