/**
 * @ai-summary Integration tests for audit log wiring across features
 * @ai-context Verifies audit logging is properly integrated into auth, vehicle, admin, and backup features
 */

import { Pool } from 'pg';
import { appConfig } from '../../../core/config/config-loader';
import { AuditLogService } from '../domain/audit-log.service';
import { AuditLogRepository } from '../data/audit-log.repository';

describe('AuditLog Feature Integration', () => {
  let pool: Pool;
  let repository: AuditLogRepository;
  let service: AuditLogService;
  const createdIds: string[] = [];

  beforeAll(async () => {
    pool = new Pool({
      connectionString: appConfig.getDatabaseUrl(),
    });
    repository = new AuditLogRepository(pool);
    service = new AuditLogService(repository);
  });

  afterAll(async () => {
    // Cleanup test data
    if (createdIds.length > 0) {
      await pool.query(`DELETE FROM audit_logs WHERE id = ANY($1::uuid[])`, [createdIds]);
    }
    await pool.end();
  });

  describe('Vehicle logging integration', () => {
    it('should create audit log with vehicle category and correct resource', async () => {
      const userId = 'test-user-vehicle-123';
      const vehicleId = 'vehicle-uuid-123';
      const entry = await service.info(
        'vehicle',
        userId,
        'Vehicle created: 2024 Toyota Camry',
        'vehicle',
        vehicleId,
        { vin: '1HGBH41JXMN109186', make: 'Toyota', model: 'Camry', year: 2024 }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('vehicle');
      expect(entry.severity).toBe('info');
      expect(entry.userId).toBe(userId);
      expect(entry.action).toContain('Vehicle created');
      expect(entry.resourceType).toBe('vehicle');
      expect(entry.resourceId).toBe(vehicleId);
      expect(entry.details).toHaveProperty('vin');
      expect(entry.details).toHaveProperty('make', 'Toyota');
    });

    it('should log vehicle update with correct fields', async () => {
      const userId = 'test-user-vehicle-456';
      const vehicleId = 'vehicle-uuid-456';
      const entry = await service.info(
        'vehicle',
        userId,
        'Vehicle updated: 2024 Toyota Camry',
        'vehicle',
        vehicleId,
        { updatedFields: ['color', 'licensePlate'] }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('vehicle');
      expect(entry.action).toContain('Vehicle updated');
      expect(entry.details).toHaveProperty('updatedFields');
    });

    it('should log vehicle deletion with vehicle info', async () => {
      const userId = 'test-user-vehicle-789';
      const vehicleId = 'vehicle-uuid-789';
      const entry = await service.info(
        'vehicle',
        userId,
        'Vehicle deleted: 2024 Toyota Camry',
        'vehicle',
        vehicleId,
        { vin: '1HGBH41JXMN109186', make: 'Toyota', model: 'Camry', year: 2024 }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('vehicle');
      expect(entry.action).toContain('Vehicle deleted');
      expect(entry.resourceId).toBe(vehicleId);
    });
  });

  describe('Auth logging integration', () => {
    it('should create audit log with auth category for signup', async () => {
      const userId = 'test-user-auth-123';
      const entry = await service.info(
        'auth',
        userId,
        'User signup: test@example.com',
        'user',
        userId,
        { email: 'test@example.com', ipAddress: '192.168.1.1' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('auth');
      expect(entry.severity).toBe('info');
      expect(entry.userId).toBe(userId);
      expect(entry.action).toContain('signup');
      expect(entry.resourceType).toBe('user');
    });

    it('should create audit log for password reset request', async () => {
      const userId = 'test-user-auth-456';
      const entry = await service.info(
        'auth',
        userId,
        'Password reset requested',
        'user',
        userId
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('auth');
      expect(entry.action).toBe('Password reset requested');
    });
  });

  describe('Admin logging integration', () => {
    it('should create audit log for admin user creation', async () => {
      const adminId = 'admin-user-123';
      const targetAdminSub = 'auth0|target-admin-456';
      const entry = await service.info(
        'admin',
        adminId,
        'Admin user created: newadmin@example.com',
        'admin_user',
        targetAdminSub,
        { email: 'newadmin@example.com', role: 'admin' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('admin');
      expect(entry.severity).toBe('info');
      expect(entry.userId).toBe(adminId);
      expect(entry.action).toContain('Admin user created');
      expect(entry.resourceType).toBe('admin_user');
      expect(entry.details).toHaveProperty('role', 'admin');
    });

    it('should create audit log for admin revocation', async () => {
      const adminId = 'admin-user-123';
      const targetAdminSub = 'auth0|target-admin-789';
      const entry = await service.info(
        'admin',
        adminId,
        'Admin user revoked: revoked@example.com',
        'admin_user',
        targetAdminSub,
        { email: 'revoked@example.com' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('admin');
      expect(entry.action).toContain('Admin user revoked');
    });

    it('should create audit log for admin reinstatement', async () => {
      const adminId = 'admin-user-123';
      const targetAdminSub = 'auth0|target-admin-reinstated';
      const entry = await service.info(
        'admin',
        adminId,
        'Admin user reinstated: reinstated@example.com',
        'admin_user',
        targetAdminSub,
        { email: 'reinstated@example.com' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('admin');
      expect(entry.action).toContain('Admin user reinstated');
    });
  });

  describe('Backup/System logging integration', () => {
    it('should create audit log for backup creation', async () => {
      const adminId = 'admin-user-backup-123';
      const backupId = 'backup-uuid-123';
      const entry = await service.info(
        'system',
        adminId,
        'Backup created: Manual backup',
        'backup',
        backupId,
        { name: 'Manual backup', includeDocuments: true }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('system');
      expect(entry.severity).toBe('info');
      expect(entry.action).toContain('Backup created');
      expect(entry.resourceType).toBe('backup');
      expect(entry.resourceId).toBe(backupId);
    });

    it('should create audit log for backup restore', async () => {
      const adminId = 'admin-user-backup-456';
      const backupId = 'backup-uuid-456';
      const entry = await service.info(
        'system',
        adminId,
        'Backup restored: backup-uuid-456',
        'backup',
        backupId,
        { safetyBackupId: 'safety-backup-uuid' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('system');
      expect(entry.action).toContain('Backup restored');
    });

    it('should create error-level audit log for backup failure', async () => {
      const adminId = 'admin-user-backup-789';
      const backupId = 'backup-uuid-789';
      const entry = await service.error(
        'system',
        adminId,
        'Backup failed: Daily backup',
        'backup',
        backupId,
        { error: 'Disk full' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('system');
      expect(entry.severity).toBe('error');
      expect(entry.action).toContain('Backup failed');
      expect(entry.details).toHaveProperty('error', 'Disk full');
    });

    it('should create error-level audit log for restore failure', async () => {
      const adminId = 'admin-user-restore-fail';
      const backupId = 'backup-uuid-restore-fail';
      const entry = await service.error(
        'system',
        adminId,
        'Backup restore failed: backup-uuid-restore-fail',
        'backup',
        backupId,
        { error: 'Corrupted archive', safetyBackupId: 'safety-uuid' }
      );

      createdIds.push(entry.id);

      expect(entry.category).toBe('system');
      expect(entry.severity).toBe('error');
      expect(entry.action).toContain('restore failed');
    });
  });

  describe('Cross-feature audit log queries', () => {
    it('should be able to filter logs by category', async () => {
      // Search for vehicle logs
      const vehicleResult = await service.search(
        { category: 'vehicle' },
        { limit: 100, offset: 0 }
      );

      expect(vehicleResult.logs.length).toBeGreaterThan(0);
      expect(vehicleResult.logs.every((log) => log.category === 'vehicle')).toBe(true);
    });

    it('should be able to search across all categories', async () => {
      const result = await service.search(
        { search: 'created' },
        { limit: 100, offset: 0 }
      );

      expect(result.logs.length).toBeGreaterThan(0);
      // Should find logs from vehicle and admin categories
      const categories = new Set(result.logs.map((log) => log.category));
      expect(categories.size).toBeGreaterThanOrEqual(1);
    });

    it('should be able to filter by severity across categories', async () => {
      const errorResult = await service.search(
        { severity: 'error' },
        { limit: 100, offset: 0 }
      );

      expect(errorResult.logs.every((log) => log.severity === 'error')).toBe(true);
    });
  });
});
