/**
 * Index Routes
 *
 * Code indexing/ingestion endpoints.
 */

import { Hono } from 'hono';
import { zValidator } from '@hono/zod-validator';
import type { AppContext } from '../router.js';
import { IndexRequestSchema, type IndexStatus } from '../types.js';
import { IngestionOrchestrator } from '../../ingestion/orchestrator.js';

export const indexRoutes = new Hono<AppContext>();

/**
 * POST /index/start - Start indexing a repository
 */
indexRoutes.post(
  '/start',
  zValidator('json', IndexRequestSchema),
  async (c) => {
    const conn = c.get('conn');
    const body = c.req.valid('json');

    if (!conn) {
      return c.json({ error: 'No database connection' }, 500);
    }

    try {
      const orchestrator = new IngestionOrchestrator({
        repoRoot: body.repoPath,
        changedOnly: body.options?.changedOnly ?? false,
        maxWorkers: body.options?.maxWorkers ?? 4,
      });

      orchestrator.setConnection(conn);

      const stats = await orchestrator.index();

      return c.json({
        success: true,
        stats: {
          filesProcessed: stats.filesProcessed,
          filesSucceeded: stats.filesSucceeded,
          filesFailed: stats.filesFailed,
          classesFound: stats.classesFound,
          functionsFound: stats.functionsFound,
          importsFound: stats.importsFound,
          durationMs: stats.durationMs,
        },
      });
    } catch (error) {
      return c.json(
        {
          success: false,
          error: error instanceof Error ? error.message : 'Unknown error',
        },
        500
      );
    }
  }
);

/**
 * GET /index/status - Get indexing status for a repository
 */
indexRoutes.get('/status', async (c) => {
  const conn = c.get('conn');
  const repoPath = c.req.query('repoPath');

  if (!repoPath) {
    return c.json({ error: 'repoPath query parameter required' }, 400);
  }

  if (!conn) {
    return c.json({ error: 'No database connection' }, 500);
  }

  try {
    const info = await conn.getDatabaseInfo();

    // Check if we have any files indexed
    const fileCount = info.nodeCount.File ?? 0;
    const isIndexed = fileCount > 0;

    const status: IndexStatus = {
      isIndexed,
      fileCount,
      functionCount: info.nodeCount.Function ?? 0,
      classCount: info.nodeCount.Class ?? 0,
      moduleCount: info.nodeCount.Module ?? 0,
    };

    // Try to get last indexed commit from metadata
    try {
      const result = await conn.query(`
        MATCH (r:Repository)
        RETURN r.last_indexed_commit AS commit
        LIMIT 1
      `);
      const row = result.single();
      if (row?.commit) {
        status.lastIndexedCommit = row.commit as string;
      }
    } catch {
      // Repository node might not exist yet
    }

    return c.json(status);
  } catch (error) {
    return c.json(
      { error: error instanceof Error ? error.message : 'Unknown error' },
      500
    );
  }
});
