/**
 * @ai-summary Integration tests for audit_logs table migration
 * @ai-context Tests table creation, constraints, and indexes
 */

import { Pool } from 'pg';
import { appConfig } from '../../../core/config/config-loader';

describe('Audit Logs Migration', () => {
  let pool: Pool;

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

  afterAll(async () => {
    await pool.end();
  });

  describe('Table Structure', () => {
    it('should have audit_logs table with correct columns', async () => {
      const result = await pool.query(`
        SELECT column_name, data_type, is_nullable
        FROM information_schema.columns
        WHERE table_name = 'audit_logs'
        ORDER BY ordinal_position
      `);

      const columns = result.rows.map((row) => row.column_name);
      expect(columns).toContain('id');
      expect(columns).toContain('category');
      expect(columns).toContain('severity');
      expect(columns).toContain('user_id');
      expect(columns).toContain('action');
      expect(columns).toContain('resource_type');
      expect(columns).toContain('resource_id');
      expect(columns).toContain('details');
      expect(columns).toContain('created_at');
    });
  });

  describe('CHECK Constraints', () => {
    it('should accept valid category values', async () => {
      const validCategories = ['auth', 'vehicle', 'user', 'system', 'admin'];

      for (const category of validCategories) {
        const result = await pool.query(
          `INSERT INTO audit_logs (category, severity, action)
           VALUES ($1, 'info', 'test action')
           RETURNING id`,
          [category]
        );
        expect(result.rows[0].id).toBeDefined();

        // Cleanup
        await pool.query('DELETE FROM audit_logs WHERE id = $1', [result.rows[0].id]);
      }
    });

    it('should reject invalid category values', async () => {
      await expect(
        pool.query(
          `INSERT INTO audit_logs (category, severity, action)
           VALUES ('invalid', 'info', 'test action')`
        )
      ).rejects.toThrow();
    });

    it('should accept valid severity values', async () => {
      const validSeverities = ['info', 'warning', 'error'];

      for (const severity of validSeverities) {
        const result = await pool.query(
          `INSERT INTO audit_logs (category, severity, action)
           VALUES ('auth', $1, 'test action')
           RETURNING id`,
          [severity]
        );
        expect(result.rows[0].id).toBeDefined();

        // Cleanup
        await pool.query('DELETE FROM audit_logs WHERE id = $1', [result.rows[0].id]);
      }
    });

    it('should reject invalid severity values', async () => {
      await expect(
        pool.query(
          `INSERT INTO audit_logs (category, severity, action)
           VALUES ('auth', 'invalid', 'test action')`
        )
      ).rejects.toThrow();
    });
  });

  describe('Nullable Columns', () => {
    it('should allow NULL user_id for system actions', async () => {
      const result = await pool.query(
        `INSERT INTO audit_logs (category, severity, user_id, action)
         VALUES ('system', 'info', NULL, 'system startup')
         RETURNING id, user_id`
      );

      expect(result.rows[0].id).toBeDefined();
      expect(result.rows[0].user_id).toBeNull();

      // Cleanup
      await pool.query('DELETE FROM audit_logs WHERE id = $1', [result.rows[0].id]);
    });
  });

  describe('Indexes', () => {
    it('should have required indexes', async () => {
      const result = await pool.query(`
        SELECT indexname
        FROM pg_indexes
        WHERE tablename = 'audit_logs'
      `);

      const indexNames = result.rows.map((row) => row.indexname);
      expect(indexNames).toContain('idx_audit_logs_category_created');
      expect(indexNames).toContain('idx_audit_logs_severity_created');
      expect(indexNames).toContain('idx_audit_logs_user_created');
      expect(indexNames).toContain('idx_audit_logs_created');
      expect(indexNames).toContain('idx_audit_logs_action_gin');
    });
  });
});
