import type { FastifyInstance } from 'fastify';
import type { AuditEventService } from '../services/audit-event.service.js';
import type { AuditEventCreateInput } from '../repositories/interfaces.js';

interface AuditEventQuery {
  sessionId?: string;
  projectName?: string;
  eventKind?: string;
  serverName?: string;
  correlationId?: string;
  userName?: string;
  from?: string;
  to?: string;
  limit?: string;
  offset?: string;
}

export function registerAuditEventRoutes(app: FastifyInstance, service: AuditEventService): void {
  // POST /api/v1/audit/events — batch insert from mcplocal
  app.post('/api/v1/audit/events', async (request, reply) => {
    const body = request.body;
    if (!Array.isArray(body) || body.length === 0) {
      return reply.code(400).send({ error: 'Request body must be a non-empty array of audit events' });
    }

    // Basic validation
    for (const event of body) {
      const e = event as Record<string, unknown>;
      if (!e['sessionId'] || !e['projectName'] || !e['eventKind'] || !e['source'] || !e['timestamp']) {
        return reply.code(400).send({ error: 'Each event requires: timestamp, sessionId, projectName, eventKind, source' });
      }
    }

    const count = await service.createBatch(body as AuditEventCreateInput[]);
    reply.code(201);
    return { inserted: count };
  });

  // GET /api/v1/audit/events — query with filters
  app.get<{ Querystring: AuditEventQuery }>('/api/v1/audit/events', async (request) => {
    const q = request.query;
    const params: Record<string, unknown> = {};
    if (q.sessionId !== undefined) params['sessionId'] = q.sessionId;
    if (q.projectName !== undefined) params['projectName'] = q.projectName;
    if (q.eventKind !== undefined) params['eventKind'] = q.eventKind;
    if (q.serverName !== undefined) params['serverName'] = q.serverName;
    if (q.correlationId !== undefined) params['correlationId'] = q.correlationId;
    if (q.userName !== undefined) params['userName'] = q.userName;
    if (q.from !== undefined) params['from'] = q.from;
    if (q.to !== undefined) params['to'] = q.to;
    if (q.limit !== undefined) params['limit'] = parseInt(q.limit, 10);
    if (q.offset !== undefined) params['offset'] = parseInt(q.offset, 10);
    return service.list(params);
  });

  // GET /api/v1/audit/events/:id — single event
  app.get<{ Params: { id: string } }>('/api/v1/audit/events/:id', async (request) => {
    return service.getById(request.params.id);
  });

  // GET /api/v1/audit/tool-usage — rank tools by invocation count (for favourites)
  app.get<{ Querystring: { projectName?: string; window?: string; limit?: string } }>('/api/v1/audit/tool-usage', async (request, reply) => {
    const q = request.query;
    if (!q.projectName) return reply.code(400).send({ error: 'projectName is required' });
    const windowDays = q.window !== undefined ? parseInt(q.window, 10) : 30;
    const limit = q.limit !== undefined ? parseInt(q.limit, 10) : 50;
    return { tools: await service.toolUsage(q.projectName, windowDays, limit) };
  });

  // GET /api/v1/audit/sessions — list sessions with aggregates
  app.get<{ Querystring: { projectName?: string; userName?: string; from?: string; to?: string; limit?: string; offset?: string } }>('/api/v1/audit/sessions', async (request) => {
    const q = request.query;
    const params: { projectName?: string; userName?: string; from?: string; to?: string; limit?: number; offset?: number } = {};
    if (q.projectName !== undefined) params.projectName = q.projectName;
    if (q.userName !== undefined) params.userName = q.userName;
    if (q.from !== undefined) params.from = q.from;
    if (q.to !== undefined) params.to = q.to;
    if (q.limit !== undefined) params.limit = parseInt(q.limit, 10);
    if (q.offset !== undefined) params.offset = parseInt(q.offset, 10);
    return service.listSessions(Object.keys(params).length > 0 ? params : undefined);
  });
}
