/**
 * @ai-summary Fastify route handlers for audit log API
 * @ai-context HTTP request/response handling for audit log search and export
 */

import { FastifyRequest, FastifyReply } from 'fastify';
import { AuditLogService } from '../domain/audit-log.service';
import { AuditLogRepository } from '../data/audit-log.repository';
import { AuditLogFilters, isValidCategory, isValidSeverity } from '../domain/audit-log.types';
import { pool } from '../../../core/config/database';
import { logger } from '../../../core/logging/logger';

interface AuditLogsQuery {
  search?: string;
  category?: string;
  severity?: string;
  startDate?: string;
  endDate?: string;
  limit?: string;
  offset?: string;
}

export class AuditLogController {
  private service: AuditLogService;

  constructor() {
    const repository = new AuditLogRepository(pool);
    this.service = new AuditLogService(repository);
  }

  /**
   * GET /api/admin/audit-logs - Search audit logs with filters
   */
  async getAuditLogs(
    request: FastifyRequest<{ Querystring: AuditLogsQuery }>,
    reply: FastifyReply
  ) {
    try {
      const { search, category, severity, startDate, endDate, limit, offset } = request.query;

      // Validate category if provided
      if (category && !isValidCategory(category)) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: `Invalid category: ${category}. Valid values: auth, vehicle, user, system, admin`,
        });
      }

      // Validate severity if provided
      if (severity && !isValidSeverity(severity)) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: `Invalid severity: ${severity}. Valid values: info, warning, error`,
        });
      }

      const filters: AuditLogFilters = {
        search,
        category: category as AuditLogFilters['category'],
        severity: severity as AuditLogFilters['severity'],
        startDate: startDate ? new Date(startDate) : undefined,
        endDate: endDate ? new Date(endDate) : undefined,
      };

      const pagination = {
        limit: Math.min(parseInt(limit || '50', 10), 100),
        offset: parseInt(offset || '0', 10),
      };

      const result = await this.service.search(filters, pagination);

      return reply.send(result);
    } catch (error) {
      logger.error('Error fetching audit logs', { error });
      return reply.code(500).send({
        error: 'Internal Server Error',
        message: 'Failed to fetch audit logs',
      });
    }
  }

  /**
   * GET /api/admin/audit-logs/export - Export audit logs as CSV
   */
  async exportAuditLogs(
    request: FastifyRequest<{ Querystring: AuditLogsQuery }>,
    reply: FastifyReply
  ) {
    try {
      const { search, category, severity, startDate, endDate } = request.query;

      // Validate category if provided
      if (category && !isValidCategory(category)) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: `Invalid category: ${category}`,
        });
      }

      // Validate severity if provided
      if (severity && !isValidSeverity(severity)) {
        return reply.code(400).send({
          error: 'Bad Request',
          message: `Invalid severity: ${severity}`,
        });
      }

      const filters: AuditLogFilters = {
        search,
        category: category as AuditLogFilters['category'],
        severity: severity as AuditLogFilters['severity'],
        startDate: startDate ? new Date(startDate) : undefined,
        endDate: endDate ? new Date(endDate) : undefined,
      };

      const { logs, truncated } = await this.service.getForExport(filters);

      // Generate CSV
      const headers = ['ID', 'Timestamp', 'Category', 'Severity', 'User ID', 'Action', 'Resource Type', 'Resource ID'];
      const rows = logs.map((log) => [
        log.id,
        log.createdAt.toISOString(),
        log.category,
        log.severity,
        log.userId || '',
        `"${log.action.replace(/"/g, '""')}"`, // Escape quotes in CSV
        log.resourceType || '',
        log.resourceId || '',
      ]);

      const csv = [headers.join(','), ...rows.map((row) => row.join(','))].join('\n');

      // Set headers for file download
      const filename = `audit-logs-${new Date().toISOString().split('T')[0]}.csv`;
      reply.header('Content-Type', 'text/csv');
      reply.header('Content-Disposition', `attachment; filename="${filename}"`);

      // Warn if results were truncated
      if (truncated) {
        reply.header('X-Export-Truncated', 'true');
        reply.header('X-Export-Limit', '5000');
        logger.warn('Audit log export was truncated', { exportedCount: logs.length });
      }

      return reply.send(csv);
    } catch (error) {
      logger.error('Error exporting audit logs', { error });
      return reply.code(500).send({
        error: 'Internal Server Error',
        message: 'Failed to export audit logs',
      });
    }
  }
}
