/**
 * Audit Controller
 * REST endpoints for viewing audit logs and compliance data.
 *
 * @module Audit
 */

import { Router, Request, Response, NextFunction } from 'express';
import { DataSource } from 'typeorm';
import { AuthMiddleware } from '../../auth/middleware/auth.middleware';
import { AuthService } from '../../auth/services/auth.service';
import {
  AuditLog,
  EntityChange,
  LoginHistory,
  SensitiveDataAccess,
  DataExport,
  PermissionChange,
  ConfigChange,
} from '../entities';
import {
  AuditLogService,
  AuditLogFilters,
  ServiceContext,
} from '../services/audit-log.service';
import { EntityChangeService, EntityChangeFilters } from '../services/entity-change.service';
import { LoginHistoryService, LoginHistoryFilters } from '../services/login-history.service';
import { SensitiveDataAccessService, SensitiveDataAccessFilters } from '../services/sensitive-data-access.service';
import { DataExportService, DataExportFilters } from '../services/data-export.service';
import { PermissionChangeService, PermissionChangeFilters } from '../services/permission-change.service';
import { ConfigChangeService, ConfigChangeFilters } from '../services/config-change.service';
import { RetentionPolicyService } from '../services/retention-policy.service';
import { User } from '../../core/entities/user.entity';
import { Tenant } from '../../core/entities/tenant.entity';
import { RefreshToken } from '../../auth/entities/refresh-token.entity';

export function createAuditController(dataSource: DataSource): Router {
  const router = Router();

  // Repositories
  const auditLogRepository = dataSource.getRepository(AuditLog);
  const entityChangeRepository = dataSource.getRepository(EntityChange);
  const loginHistoryRepository = dataSource.getRepository(LoginHistory);
  const sensitiveDataAccessRepository = dataSource.getRepository(SensitiveDataAccess);
  const dataExportRepository = dataSource.getRepository(DataExport);
  const permissionChangeRepository = dataSource.getRepository(PermissionChange);
  const configChangeRepository = dataSource.getRepository(ConfigChange);
  const userRepository = dataSource.getRepository(User);
  const tenantRepository = dataSource.getRepository(Tenant);
  const refreshTokenRepository = dataSource.getRepository(RefreshToken);

  // Services
  const auditLogService = new AuditLogService(auditLogRepository);
  const entityChangeService = new EntityChangeService(entityChangeRepository);
  const loginHistoryService = new LoginHistoryService(loginHistoryRepository);
  const sensitiveDataAccessService = new SensitiveDataAccessService(sensitiveDataAccessRepository);
  const dataExportService = new DataExportService(dataExportRepository);
  const permissionChangeService = new PermissionChangeService(permissionChangeRepository);
  const configChangeService = new ConfigChangeService(configChangeRepository);
  const retentionPolicyService = new RetentionPolicyService(
    auditLogRepository,
    entityChangeRepository,
    loginHistoryRepository,
    sensitiveDataAccessRepository,
    dataExportRepository,
    permissionChangeRepository,
    configChangeRepository,
  );

  const authService = new AuthService(userRepository, tenantRepository, refreshTokenRepository as any);
  const authMiddleware = new AuthMiddleware(authService, dataSource);

  // Helper to create service context
  const getContext = (req: Request): ServiceContext => {
    if (!req.tenantId) {
      throw new Error('Tenant ID is required');
    }
    return {
      tenantId: req.tenantId,
      userId: req.user?.sub,
    };
  };

  // =====================
  // AUDIT LOGS ENDPOINTS
  // =====================

  /**
   * GET /audit/logs
   * Get audit logs with filters
   */
  router.get('/logs', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: AuditLogFilters = {};
      if (req.query.userId) filters.userId = req.query.userId as string;
      if (req.query.action) filters.action = req.query.action as any;
      if (req.query.actionCategory) filters.actionCategory = req.query.actionCategory as any;
      if (req.query.resourceType) filters.resourceType = req.query.resourceType as string;
      if (req.query.resourceId) filters.resourceId = req.query.resourceId as string;
      if (req.query.status) filters.status = req.query.status as any;
      if (req.query.ipAddress) filters.ipAddress = req.query.ipAddress as string;
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);
      if (req.query.search) filters.search = req.query.search as string;

      const result = await auditLogService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logs/stats
   * Get audit log statistics
   */
  router.get('/logs/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await auditLogService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logs/resource/:type/:id
   * Get audit logs for a specific resource
   */
  router.get('/logs/resource/:type/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor', 'supervisor_obra'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);

      const result = await auditLogService.findByResource(
        getContext(req),
        req.params.type,
        req.params.id,
        page,
        limit,
      );

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logs/user/:userId
   * Get audit logs for a specific user
   */
  router.get('/logs/user/:userId', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const result = await auditLogService.findByUser(
        getContext(req),
        req.params.userId,
        page,
        limit,
      );

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logs/failed
   * Get failed operations
   */
  router.get('/logs/failed', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const hours = parseInt(req.query.hours as string) || 24;
      const limit = Math.min(parseInt(req.query.limit as string) || 100, 500);

      const logs = await auditLogService.getFailedOperations(getContext(req), hours, limit);
      res.status(200).json({ success: true, data: logs });
    } catch (error) {
      next(error);
    }
  });

  // =========================
  // ENTITY CHANGES ENDPOINTS
  // =========================

  /**
   * GET /audit/changes
   * Get entity changes with filters
   */
  router.get('/changes', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: EntityChangeFilters = {};
      if (req.query.entityType) filters.entityType = req.query.entityType as string;
      if (req.query.entityId) filters.entityId = req.query.entityId as string;
      if (req.query.changedBy) filters.changedBy = req.query.changedBy as string;
      if (req.query.changeType) filters.changeType = req.query.changeType as any;
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);

      const result = await entityChangeService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/changes/entity/:type/:id
   * Get change history for a specific entity
   */
  router.get('/changes/entity/:type/:id', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor', 'supervisor_obra'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);

      const result = await entityChangeService.getHistory(
        getContext(req),
        req.params.type,
        req.params.id,
        page,
        limit,
      );

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/changes/entity/:type/:id/version/:version
   * Get a specific version of an entity
   */
  router.get('/changes/entity/:type/:id/version/:version', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const version = parseInt(req.params.version);
      const change = await entityChangeService.getVersion(
        getContext(req),
        req.params.type,
        req.params.id,
        version,
      );

      if (!change) {
        res.status(404).json({ success: false, error: 'Version not found' });
        return;
      }

      res.status(200).json({ success: true, data: change });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/changes/entity/:type/:id/compare
   * Compare two versions of an entity
   */
  router.get('/changes/entity/:type/:id/compare', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const version1 = parseInt(req.query.v1 as string);
      const version2 = parseInt(req.query.v2 as string);

      if (isNaN(version1) || isNaN(version2)) {
        res.status(400).json({ success: false, error: 'Both v1 and v2 query parameters are required' });
        return;
      }

      const comparison = await entityChangeService.compareVersions(
        getContext(req),
        req.params.type,
        req.params.id,
        version1,
        version2,
      );

      if (!comparison) {
        res.status(404).json({ success: false, error: 'One or both versions not found' });
        return;
      }

      res.status(200).json({ success: true, data: comparison });
    } catch (error) {
      next(error);
    }
  });

  // ==========================
  // LOGIN HISTORY ENDPOINTS
  // ==========================

  /**
   * GET /audit/logins
   * Get login history with filters
   */
  router.get('/logins', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: LoginHistoryFilters = {};
      if (req.query.userId) filters.userId = req.query.userId as string;
      if (req.query.email) filters.email = req.query.email as string;
      if (req.query.status) filters.status = req.query.status as any;
      if (req.query.authMethod) filters.authMethod = req.query.authMethod as any;
      if (req.query.ipAddress) filters.ipAddress = req.query.ipAddress as string;
      if (req.query.isSuspicious) filters.isSuspicious = req.query.isSuspicious === 'true';
      if (req.query.isNewDevice) filters.isNewDevice = req.query.isNewDevice === 'true';
      if (req.query.isNewLocation) filters.isNewLocation = req.query.isNewLocation === 'true';
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);
      if (req.query.minRiskScore) filters.minRiskScore = parseInt(req.query.minRiskScore as string);

      const result = await loginHistoryService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/stats
   * Get login statistics
   */
  router.get('/logins/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await loginHistoryService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/suspicious
   * Get suspicious login attempts
   */
  router.get('/logins/suspicious', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 7;
      const limit = Math.min(parseInt(req.query.limit as string) || 100, 500);

      const logins = await loginHistoryService.getSuspiciousLogins(getContext(req), days, limit);
      res.status(200).json({ success: true, data: logins });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/failed
   * Get failed login attempts
   */
  router.get('/logins/failed', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const hours = parseInt(req.query.hours as string) || 24;
      const limit = Math.min(parseInt(req.query.limit as string) || 100, 500);

      const logins = await loginHistoryService.getFailedLogins(getContext(req), hours, limit);
      res.status(200).json({ success: true, data: logins });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/high-risk
   * Get high risk login attempts
   */
  router.get('/logins/high-risk', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const minRiskScore = parseInt(req.query.minRiskScore as string) || 70;
      const days = parseInt(req.query.days as string) || 7;
      const limit = Math.min(parseInt(req.query.limit as string) || 100, 500);

      const logins = await loginHistoryService.getHighRiskLogins(getContext(req), minRiskScore, days, limit);
      res.status(200).json({ success: true, data: logins });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/user/:userId
   * Get login history for a specific user
   */
  router.get('/logins/user/:userId', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const result = await loginHistoryService.findByUser(
        getContext(req),
        req.params.userId,
        page,
        limit,
      );

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/logins/user/:userId/devices
   * Get user's known devices
   */
  router.get('/logins/user/:userId/devices', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const devices = await loginHistoryService.getUserDevices(getContext(req), req.params.userId);
      res.status(200).json({ success: true, data: devices });
    } catch (error) {
      next(error);
    }
  });

  // ================================
  // SENSITIVE DATA ACCESS ENDPOINTS
  // ================================

  /**
   * GET /audit/sensitive-access
   * Get sensitive data access logs
   */
  router.get('/sensitive-access', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: SensitiveDataAccessFilters = {};
      if (req.query.userId) filters.userId = req.query.userId as string;
      if (req.query.dataType) filters.dataType = req.query.dataType as any;
      if (req.query.dataCategory) filters.dataCategory = req.query.dataCategory as string;
      if (req.query.entityType) filters.entityType = req.query.entityType as string;
      if (req.query.entityId) filters.entityId = req.query.entityId as string;
      if (req.query.accessType) filters.accessType = req.query.accessType as any;
      if (req.query.wasAuthorized !== undefined) filters.wasAuthorized = req.query.wasAuthorized === 'true';
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);

      const result = await sensitiveDataAccessService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/sensitive-access/stats
   * Get sensitive data access statistics
   */
  router.get('/sensitive-access/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await sensitiveDataAccessService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/sensitive-access/denied
   * Get denied access attempts
   */
  router.get('/sensitive-access/denied', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 7;
      const limit = Math.min(parseInt(req.query.limit as string) || 100, 500);

      const logs = await sensitiveDataAccessService.getDeniedAccess(getContext(req), days, limit);
      res.status(200).json({ success: true, data: logs });
    } catch (error) {
      next(error);
    }
  });

  // =======================
  // DATA EXPORTS ENDPOINTS
  // =======================

  /**
   * GET /audit/exports
   * Get data exports with filters
   */
  router.get('/exports', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: DataExportFilters = {};
      if (req.query.userId) filters.userId = req.query.userId as string;
      if (req.query.exportType) filters.exportType = req.query.exportType as any;
      if (req.query.exportFormat) filters.exportFormat = req.query.exportFormat as any;
      if (req.query.status) filters.status = req.query.status as any;
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);

      const result = await dataExportService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/exports/stats
   * Get data export statistics
   */
  router.get('/exports/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await dataExportService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/exports/gdpr
   * Get GDPR export requests
   */
  router.get('/exports/gdpr', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);

      const result = await dataExportService.getGdprRequests(getContext(req), page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  // ==============================
  // PERMISSION CHANGES ENDPOINTS
  // ==============================

  /**
   * GET /audit/permissions
   * Get permission changes with filters
   */
  router.get('/permissions', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: PermissionChangeFilters = {};
      if (req.query.changedBy) filters.changedBy = req.query.changedBy as string;
      if (req.query.targetUserId) filters.targetUserId = req.query.targetUserId as string;
      if (req.query.changeType) filters.changeType = req.query.changeType as any;
      if (req.query.roleCode) filters.roleCode = req.query.roleCode as string;
      if (req.query.permissionCode) filters.permissionCode = req.query.permissionCode as string;
      if (req.query.scope) filters.scope = req.query.scope as any;
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);

      const result = await permissionChangeService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/permissions/stats
   * Get permission change statistics
   */
  router.get('/permissions/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await permissionChangeService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/permissions/user/:userId
   * Get permission history for a specific user
   */
  router.get('/permissions/user/:userId', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director', 'auditor'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const changes = await permissionChangeService.getUserPermissionHistory(
        getContext(req),
        req.params.userId,
      );
      res.status(200).json({ success: true, data: changes });
    } catch (error) {
      next(error);
    }
  });

  // ==========================
  // CONFIG CHANGES ENDPOINTS
  // ==========================

  /**
   * GET /audit/config
   * Get configuration changes with filters
   */
  router.get('/config', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const page = parseInt(req.query.page as string) || 1;
      const limit = Math.min(parseInt(req.query.limit as string) || 50, 200);

      const filters: ConfigChangeFilters = {};
      if (req.query.changedBy) filters.changedBy = req.query.changedBy as string;
      if (req.query.configType) filters.configType = req.query.configType as any;
      if (req.query.configKey) filters.configKey = req.query.configKey as string;
      if (req.query.dateFrom) filters.dateFrom = new Date(req.query.dateFrom as string);
      if (req.query.dateTo) filters.dateTo = new Date(req.query.dateTo as string);
      if (req.query.search) filters.search = req.query.search as string;

      const result = await configChangeService.findWithFilters(getContext(req), filters, page, limit);

      res.status(200).json({
        success: true,
        data: result.data,
        pagination: { total: result.total, page: result.page, limit: result.limit, totalPages: result.totalPages },
      });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/config/stats
   * Get configuration change statistics
   */
  router.get('/config/stats', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const days = parseInt(req.query.days as string) || 30;
      const stats = await configChangeService.getStats(getContext(req), days);

      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/config/key/:key
   * Get change history for a specific config key
   */
  router.get('/config/key/:key', authMiddleware.authenticate, authMiddleware.authorize('admin', 'director'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const limit = Math.min(parseInt(req.query.limit as string) || 20, 100);
      const changes = await configChangeService.getConfigHistory(getContext(req), req.params.key, limit);

      res.status(200).json({ success: true, data: changes });
    } catch (error) {
      next(error);
    }
  });

  // ==========================
  // RETENTION POLICY ENDPOINTS
  // ==========================

  /**
   * GET /audit/retention/policy
   * Get current retention policy
   */
  router.get('/retention/policy', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (_req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const policy = retentionPolicyService.getPolicy();
      res.status(200).json({ success: true, data: policy });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/retention/stats
   * Get storage statistics
   */
  router.get('/retention/stats', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const stats = await retentionPolicyService.getStorageStats(getContext(req));
      res.status(200).json({ success: true, data: stats });
    } catch (error) {
      next(error);
    }
  });

  /**
   * GET /audit/retention/preview
   * Preview what would be cleaned up
   */
  router.get('/retention/preview', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const preview = await retentionPolicyService.previewCleanup(getContext(req));
      res.status(200).json({ success: true, data: preview });
    } catch (error) {
      next(error);
    }
  });

  /**
   * POST /audit/retention/cleanup
   * Run cleanup based on retention policy
   */
  router.post('/retention/cleanup', authMiddleware.authenticate, authMiddleware.authorize('admin'), async (req: Request, res: Response, next: NextFunction): Promise<void> => {
    try {
      const result = await retentionPolicyService.runCleanup(getContext(req));
      res.status(200).json({
        success: true,
        message: `Cleaned up ${result.totalDeleted} records`,
        data: result,
      });
    } catch (error) {
      next(error);
    }
  });

  return router;
}

export default createAuditController;
