import { useCallback, useEffect, useRef, useState } from 'react';
import type { BacktestJob, BacktestRequest, BacktestResult } from '../services/backtestApi';
import { backtestApi, } from '../services/backtestApi';

interface UseBacktestReturn {
  // State
  backtest: BacktestJob | null;
  results: BacktestResult | null;
  isLoading: boolean;
  isPolling: boolean;
  error: string | null;

  // Actions
  createBacktest: (request: BacktestRequest) => Promise<void>;
  cancelBacktest: () => Promise<void>;
  reset: () => void;
}

export function useBacktest(): UseBacktestReturn {
  const [backtest, setBacktest] = useState<BacktestJob | null>(null);
  const [results, setResults] = useState<BacktestResult | null>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [isPolling, setIsPolling] = useState(false);
  const [error, setError] = useState<string | null>(null);
  
  const pollingIntervalRef = useRef<NodeJS.Timeout | null>(null);

  // Poll for status updates
  const pollStatus = useCallback(async (backtestId: string) => {
    try {
      const updatedBacktest = await backtestApi.getBacktest(backtestId);
      setBacktest(updatedBacktest);

      if (updatedBacktest.status === 'completed') {
        // Fetch results
        const backtestResults = await backtestApi.getBacktestResults(backtestId);
        setResults(backtestResults);
        setIsPolling(false);
        
        // Clear polling interval
        if (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          pollingIntervalRef.current = null;
        }
      } else if (updatedBacktest.status === 'failed' || updatedBacktest.status === 'cancelled') {
        setIsPolling(false);
        
        // Clear polling interval
        if (pollingIntervalRef.current) {
          clearInterval(pollingIntervalRef.current);
          pollingIntervalRef.current = null;
        }
        
        if (updatedBacktest.status === 'failed' && updatedBacktest.error) {
          setError(updatedBacktest.error);
        }
      }
    } catch (err) {
      console.error('Error polling backtest status:', err);
      // Don't stop polling on transient errors
    }
  }, []);

  // Create a new backtest
  const createBacktest = useCallback(async (request: BacktestRequest) => {
    setIsLoading(true);
    setError(null);
    setResults(null);

    try {
      const newBacktest = await backtestApi.createBacktest(request);
      setBacktest(newBacktest);
      
      // Start polling for updates
      setIsPolling(true);
      pollingIntervalRef.current = setInterval(() => {
        pollStatus(newBacktest.id);
      }, 200); // Poll every 2 seconds
      
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to create backtest');
    } finally {
      setIsLoading(false);
    }
  }, [pollStatus]);

  // Cancel running backtest
  const cancelBacktest = useCallback(async () => {
    if (!backtest || backtest.status !== 'running') return;

    try {
      await backtestApi.cancelBacktest(backtest.id);
      setBacktest({ ...backtest, status: 'cancelled' });
      setIsPolling(false);
      
      // Clear polling interval
      if (pollingIntervalRef.current) {
        clearInterval(pollingIntervalRef.current);
        pollingIntervalRef.current = null;
      }
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to cancel backtest');
    }
  }, [backtest]);

  // Reset state
  const reset = useCallback(() => {
    setBacktest(null);
    setResults(null);
    setError(null);
    setIsLoading(false);
    setIsPolling(false);
    
    // Clear polling interval
    if (pollingIntervalRef.current) {
      clearInterval(pollingIntervalRef.current);
      pollingIntervalRef.current = null;
    }
  }, []);

  // Cleanup on unmount
  useEffect(() => {
    return () => {
      if (pollingIntervalRef.current) {
        clearInterval(pollingIntervalRef.current);
      }
    };
  }, []);

  return {
    backtest,
    results,
    isLoading,
    isPolling,
    error,
    createBacktest,
    cancelBacktest,
    reset,
  };
}

// Separate hook for listing backtests
interface UseBacktestListReturn {
  backtests: BacktestJob[];
  isLoading: boolean;
  error: string | null;
  loadBacktests: (limit?: number, offset?: number) => Promise<void>;
}

export function useBacktestList(): UseBacktestListReturn {
  const [backtests, setBacktests] = useState<BacktestJob[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const loadBacktests = useCallback(async (limit = 50, offset = 0) => {
    setIsLoading(true);
    setError(null);

    try {
      const list = await backtestApi.listBacktests(limit, offset);
      setBacktests(list);
    } catch (err) {
      setError(err instanceof Error ? err.message : 'Failed to load backtests');
    } finally {
      setIsLoading(false);
    }
  }, []);

  return {
    backtests,
    isLoading,
    error,
    loadBacktests,
  };
}