import { Hono } from 'hono';
import type { IServiceContainer } from '@stock-bot/handlers';
import { BacktestServiceV2 } from '../services/backtest-v2.service';
import { getLogger } from '@stock-bot/logger';

const logger = getLogger('backtests-v2-routes');

export function createBacktestV2Routes(container: IServiceContainer) {
  const app = new Hono();
  const backtestService = new BacktestServiceV2(container);

  // Backtest endpoints
  app.get('/api/v2/backtests', async (c) => {
    try {
      const limit = parseInt(c.req.query('limit') || '50');
      const offset = parseInt(c.req.query('offset') || '0');
      
      const backtests = await backtestService.listBacktests({ limit, offset });
      return c.json(backtests);
    } catch (error) {
      logger.error('Failed to list backtests', error);
      return c.json({ error: 'Failed to list backtests' }, 500);
    }
  });

  app.get('/api/v2/backtests/:id', async (c) => {
    try {
      const backtest = await backtestService.getBacktest(c.req.param('id'));
      if (!backtest) {
        return c.json({ error: 'Backtest not found' }, 404);
      }
      return c.json(backtest);
    } catch (error) {
      logger.error('Failed to get backtest', error);
      return c.json({ error: 'Failed to get backtest' }, 500);
    }
  });

  app.post('/api/v2/backtests', async (c) => {
    try {
      const body = await c.req.json();
      const backtest = await backtestService.createBacktest(body);
      return c.json(backtest, 201);
    } catch (error) {
      logger.error('Failed to create backtest', error);
      return c.json({ error: 'Failed to create backtest' }, 500);
    }
  });

  app.put('/api/v2/backtests/:id', async (c) => {
    try {
      const body = await c.req.json();
      const backtest = await backtestService.updateBacktest(c.req.param('id'), body);
      if (!backtest) {
        return c.json({ error: 'Backtest not found' }, 404);
      }
      return c.json(backtest);
    } catch (error) {
      logger.error('Failed to update backtest', error);
      return c.json({ error: 'Failed to update backtest' }, 500);
    }
  });

  app.delete('/api/v2/backtests/:id', async (c) => {
    try {
      await backtestService.deleteBacktest(c.req.param('id'));
      return c.text('', 204);
    } catch (error) {
      logger.error('Failed to delete backtest', error);
      return c.json({ error: 'Failed to delete backtest' }, 500);
    }
  });

  // Run endpoints
  app.get('/api/v2/backtests/:backtestId/runs', async (c) => {
    try {
      const runs = await backtestService.listRuns(c.req.param('backtestId'));
      return c.json(runs);
    } catch (error) {
      logger.error('Failed to list runs', error);
      return c.json({ error: 'Failed to list runs' }, 500);
    }
  });

  app.post('/api/v2/backtests/:backtestId/runs', async (c) => {
    try {
      const body = await c.req.json();
      const run = await backtestService.createRun({
        backtestId: c.req.param('backtestId'),
        speedMultiplier: body.speedMultiplier
      });
      return c.json(run, 201);
    } catch (error) {
      logger.error('Failed to create run', error);
      return c.json({ error: 'Failed to create run' }, 500);
    }
  });

  app.get('/api/v2/runs/:id', async (c) => {
    try {
      const run = await backtestService.getRun(c.req.param('id'));
      if (!run) {
        return c.json({ error: 'Run not found' }, 404);
      }
      return c.json(run);
    } catch (error) {
      logger.error('Failed to get run', error);
      return c.json({ error: 'Failed to get run' }, 500);
    }
  });

  app.get('/api/v2/runs/:id/results', async (c) => {
    try {
      const results = await backtestService.getRunResults(c.req.param('id'));
      if (!results) {
        return c.json({ error: 'Results not found' }, 404);
      }
      return c.json(results);
    } catch (error) {
      logger.error('Failed to get run results', error);
      return c.json({ error: 'Failed to get run results' }, 500);
    }
  });

  app.post('/api/v2/runs/:id/pause', async (c) => {
    try {
      await backtestService.pauseRun(c.req.param('id'));
      return c.json({ message: 'Run paused' });
    } catch (error) {
      logger.error('Failed to pause run', error);
      return c.json({ error: 'Failed to pause run' }, 500);
    }
  });

  app.post('/api/v2/runs/:id/resume', async (c) => {
    try {
      await backtestService.resumeRun(c.req.param('id'));
      return c.json({ message: 'Run resumed' });
    } catch (error) {
      logger.error('Failed to resume run', error);
      return c.json({ error: 'Failed to resume run' }, 500);
    }
  });

  app.post('/api/v2/runs/:id/cancel', async (c) => {
    try {
      await backtestService.cancelRun(c.req.param('id'));
      return c.json({ message: 'Run cancelled' });
    } catch (error) {
      logger.error('Failed to cancel run', error);
      return c.json({ error: 'Failed to cancel run' }, 500);
    }
  });

  app.put('/api/v2/runs/:id/speed', async (c) => {
    try {
      const body = await c.req.json();
      await backtestService.updateRunSpeed(c.req.param('id'), body.speedMultiplier);
      return c.json({ message: 'Speed updated' });
    } catch (error) {
      logger.error('Failed to update run speed', error);
      return c.json({ error: 'Failed to update run speed' }, 500);
    }
  });

  // Progress update endpoint (called by orchestrator)
  app.post('/api/runs/:id/progress', async (c) => {
    try {
      const runId = c.req.param('id');
      const body = await c.req.json();
      const { progress, currentDate } = body;
      
      // Update run progress in database
      await backtestService.updateRunStatus(runId, 'running', { 
        progress, 
        currentDate 
      });
      
      // Broadcast via WebSocket if handler is available
      const wsHandler = (global as any).wsHandler;
      if (wsHandler) {
        wsHandler.sendProgressUpdate(runId, progress, currentDate);
      }
      
      return c.json({ message: 'Progress updated' });
    } catch (error) {
      logger.error('Failed to update run progress', error);
      return c.json({ error: 'Failed to update run progress' }, 500);
    }
  });

  // TODO: WebSocket endpoint for real-time run updates
  // This needs additional setup with Hono WebSocket support

  return app;
}