import { describe, it, expect } from 'vitest';

// Document the 10 most common queries and their expected execution plans
const CRITICAL_QUERIES = [
  {
    name: 'Client list (paginated, port-scoped)',
    sql: `SELECT * FROM clients WHERE port_id = $1 AND archived_at IS NULL ORDER BY updated_at DESC LIMIT $2 OFFSET $3`,
    expectedIndex: 'idx_clients_port',
    maxRows: 1000,
  },
  {
    name: 'Interest list (paginated, port-scoped)',
    sql: `SELECT * FROM interests WHERE port_id = $1 AND archived_at IS NULL ORDER BY updated_at DESC LIMIT $2 OFFSET $3`,
    expectedIndex: 'idx_interests_port',
    maxRows: 5000,
  },
  {
    name: 'Search clients (tsvector)',
    sql: `SELECT * FROM clients WHERE port_id = $1 AND to_tsvector('simple', coalesce(full_name,'') || ' ' || coalesce(company_name,'')) @@ plainto_tsquery('simple', $2) LIMIT 10`,
    expectedIndex: 'idx_clients_search_expr (GIN)',
    maxRows: 10,
  },
  {
    name: 'Search berths (trigram)',
    sql: `SELECT * FROM berths WHERE port_id = $1 AND mooring_number % $2 ORDER BY similarity(mooring_number, $2) DESC LIMIT 10`,
    expectedIndex: 'idx_berths_mooring_trgm (GIN)',
    maxRows: 10,
  },
  {
    name: 'Dashboard KPIs - total clients',
    sql: `SELECT count(*) FROM clients WHERE port_id = $1 AND archived_at IS NULL`,
    expectedIndex: 'idx_clients_port',
    maxRows: 1,
  },
  {
    name: 'Dashboard - pipeline counts',
    sql: `SELECT pipeline_stage, count(*) FROM interests WHERE port_id = $1 AND archived_at IS NULL GROUP BY pipeline_stage`,
    expectedIndex: 'idx_interests_port',
    maxRows: 8,
  },
  {
    name: 'Activity feed',
    sql: `SELECT * FROM audit_logs WHERE port_id = $1 ORDER BY created_at DESC LIMIT 20`,
    expectedIndex: 'idx_al_port',
    maxRows: 20,
  },
  {
    name: 'Notifications - unread count',
    sql: `SELECT count(*) FROM notifications WHERE user_id = $1 AND port_id = $2 AND is_read = false`,
    expectedIndex: 'idx_notif_user',
    maxRows: 1,
  },
  {
    name: 'Webhook dispatch - active webhooks for port',
    sql: `SELECT * FROM webhooks WHERE port_id = $1 AND is_active = true AND events @> ARRAY[$2]`,
    expectedIndex: 'idx_webhooks_port',
    maxRows: 50,
  },
  {
    name: 'Custom field values for entity',
    sql: `SELECT cfv.*, cfd.* FROM custom_field_values cfv JOIN custom_field_definitions cfd ON cfv.field_id = cfd.id WHERE cfv.entity_id = $1 AND cfd.port_id = $2`,
    expectedIndex: 'cfv_field_entity_idx, idx_cfd_port',
    maxRows: 50,
  },
];

describe('Query plan documentation', () => {
  for (const query of CRITICAL_QUERIES) {
    it(`${query.name} uses index ${query.expectedIndex}`, () => {
      // Document the expected query plan.
      // When running against a real DB, extend this test with:
      //   const result = await db.execute(`EXPLAIN ANALYZE ${query.sql}`, params);
      //   expect(result).toContain(query.expectedIndex);
      expect(query.sql).toBeTruthy();
      expect(query.expectedIndex).toBeTruthy();
      expect(query.maxRows).toBeLessThanOrEqual(5000);
    });
  }

  it('all 10 critical queries are documented', () => {
    expect(CRITICAL_QUERIES.length).toBe(10);
  });

  it('every query targets a specific port scope via port_id', () => {
    const portScopedQueries = CRITICAL_QUERIES.filter(
      (q) => q.sql.includes('port_id'),
    );
    // All queries except the notifications unread-count (user_id primary) are port-scoped.
    // Notifications also includes port_id, so all 10 should qualify.
    expect(portScopedQueries.length).toBe(CRITICAL_QUERIES.length);
  });

  it('paginated queries cap maxRows at reasonable limits', () => {
    const paginatedQueries = CRITICAL_QUERIES.filter((q) =>
      q.sql.includes('LIMIT'),
    );
    paginatedQueries.forEach((q) => {
      expect(q.maxRows).toBeLessThanOrEqual(5000);
    });
  });

  it('full-text and trigram search queries use GIN indexes', () => {
    const searchQueries = CRITICAL_QUERIES.filter((q) =>
      q.expectedIndex.includes('GIN'),
    );
    expect(searchQueries.length).toBeGreaterThanOrEqual(2);
    searchQueries.forEach((q) => {
      expect(q.maxRows).toBeLessThanOrEqual(10);
    });
  });

  it('all index names follow the project naming convention', () => {
    // Indexes should be lowercase with underscores (or include GIN/note suffix).
    const validPattern = /^[a-z0-9_,\s()]+$/i;
    CRITICAL_QUERIES.forEach((q) => {
      expect(q.expectedIndex).toMatch(validPattern);
    });
  });
});
