import type { BacktestConfig, BacktestResult, BacktestStatus } from '../types';

const API_BASE = '/api/backtest';

export class BacktestService {
  static async createBacktest(config: BacktestConfig): Promise<{ id: string }> {
    const response = await fetch(`${API_BASE}/create`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        ...config,
        startDate: config.startDate.toISOString(),
        endDate: config.endDate.toISOString(),
      }),
    });

    if (!response.ok) {
      throw new Error('Failed to create backtest');
    }

    return response.json();
  }

  static async startBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}/start`, {
      method: 'POST',
    });

    if (!response.ok) {
      throw new Error('Failed to start backtest');
    }
  }

  static async pauseBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}/pause`, {
      method: 'POST',
    });

    if (!response.ok) {
      throw new Error('Failed to pause backtest');
    }
  }

  static async resumeBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}/resume`, {
      method: 'POST',
    });

    if (!response.ok) {
      throw new Error('Failed to resume backtest');
    }
  }

  static async stopBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}/stop`, {
      method: 'POST',
    });

    if (!response.ok) {
      throw new Error('Failed to stop backtest');
    }
  }

  static async stepBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}/step`, {
      method: 'POST',
    });

    if (!response.ok) {
      throw new Error('Failed to step backtest');
    }
  }

  static async getBacktestStatus(id: string): Promise<{
    status: BacktestStatus;
    currentTime?: number;
    progress?: number;
  }> {
    const response = await fetch(`${API_BASE}/${id}/status`);

    if (!response.ok) {
      throw new Error('Failed to get backtest status');
    }

    return response.json();
  }

  static async getBacktestResults(id: string): Promise<BacktestResult> {
    const response = await fetch(`${API_BASE}/${id}/results`);

    if (!response.ok) {
      throw new Error('Failed to get backtest results');
    }

    const data = await response.json();
    
    // Convert date strings back to Date objects
    return {
      ...data,
      config: {
        ...data.config,
        startDate: new Date(data.config.startDate),
        endDate: new Date(data.config.endDate),
      },
    };
  }

  static async listBacktests(): Promise<BacktestResult[]> {
    const response = await fetch(`${API_BASE}/list`);

    if (!response.ok) {
      throw new Error('Failed to list backtests');
    }

    const data = await response.json();
    
    // Convert date strings back to Date objects
    return data.map((backtest: any) => ({
      ...backtest,
      config: {
        ...backtest.config,
        startDate: new Date(backtest.config.startDate),
        endDate: new Date(backtest.config.endDate),
      },
    }));
  }

  static async deleteBacktest(id: string): Promise<void> {
    const response = await fetch(`${API_BASE}/${id}`, {
      method: 'DELETE',
    });

    if (!response.ok) {
      throw new Error('Failed to delete backtest');
    }
  }

  // Helper method to poll for updates
  static async pollBacktestUpdates(
    id: string,
    onUpdate: (status: BacktestStatus, progress?: number, currentTime?: number) => void,
    interval: number = 200
  ): Promise<() => void> {
    let isPolling = true;

    const poll = async () => {
      while (isPolling) {
        try {
          const { status, progress, currentTime } = await this.getBacktestStatus(id);
          onUpdate(status, progress, currentTime);

          if (status === 'completed' || status === 'error' || status === 'stopped') {
            isPolling = false;
            break;
          }
        } catch (error) {
          console.error('Polling error:', error);
        }

        await new Promise(resolve => setTimeout(resolve, interval));
      }
    };

    poll();

    // Return cleanup function
    return () => {
      isPolling = false;
    };
  }
}