// src/tests/e2e/admin-dashboard.e2e.test.ts
import { describe, it, expect, afterAll } from 'vitest';
import * as apiClient from '../../services/apiClient';
import { getPool } from '../../services/db/connection.db';
import { cleanupDb } from '../utils/cleanup';

/**
 * @vitest-environment node
 */

describe('E2E Admin Dashboard Flow', () => {
  // Use a unique email for every run to avoid collisions
  const uniqueId = Date.now();
  const adminEmail = `e2e-admin-${uniqueId}@example.com`;
  const adminPassword = 'StrongPassword123!';

  let authToken: string;
  let adminUserId: string | null = null;

  afterAll(async () => {
    // Safety cleanup: Ensure the user is deleted from the DB if the test fails mid-way.
    await cleanupDb({
      userIds: [adminUserId],
    });
  });

  it('should allow an admin to log in and access dashboard features', async () => {
    // 1. Register a new user (initially a regular user)
    const registerResponse = await apiClient.registerUser(
      adminEmail,
      adminPassword,
      'E2E Admin User',
    );

    expect(registerResponse.status).toBe(201);
    const registerResponseBody = await registerResponse.json();
    const registeredUser = registerResponseBody.data.userprofile.user;
    adminUserId = registeredUser.user_id;
    expect(adminUserId).toBeDefined();

    // 2. Promote the user to 'admin' via direct DB access
    // (This simulates an existing admin or a manual promotion, as there is no public "register as admin" endpoint)
    await getPool().query(`UPDATE public.profiles SET role = 'admin' WHERE user_id = $1`, [
      adminUserId,
    ]);

    // 3. Login to get the access token (now with admin privileges)
    // We wait briefly to ensure the DB transaction is committed and visible to the API,
    // and to provide a buffer for any rate limits from previous tests.
    await new Promise((resolve) => setTimeout(resolve, 2000));

    const loginResponse = await apiClient.loginUser(adminEmail, adminPassword, false);
    if (!loginResponse.ok) {
      const errorText = await loginResponse.text();
      throw new Error(`Failed to log in as admin: ${loginResponse.status} ${errorText}`);
    }
    const loginResponseBody = await loginResponse.json();

    expect(loginResponse.status).toBe(200);
    authToken = loginResponseBody.data.token;
    expect(authToken).toBeDefined();
    // Verify the role returned in the login response is now 'admin'
    expect(loginResponseBody.data.userprofile.role).toBe('admin');

    // 4. Fetch System Stats (Protected Admin Route)
    const statsResponse = await apiClient.getApplicationStats(authToken);

    expect(statsResponse.status).toBe(200);
    const statsResponseBody = await statsResponse.json();
    expect(statsResponseBody.data).toHaveProperty('userCount');
    expect(statsResponseBody.data).toHaveProperty('flyerCount');

    // 5. Fetch User List (Protected Admin Route)
    const usersResponse = await apiClient.authedGet('/admin/users', { tokenOverride: authToken });

    expect(usersResponse.status).toBe(200);
    const usersResponseBody = await usersResponse.json();
    expect(Array.isArray(usersResponseBody.data)).toBe(true);
    // The list should contain the admin user we just created
    const self = usersResponseBody.data.find((u: any) => u.user_id === adminUserId);
    expect(self).toBeDefined();

    // 6. Check Queue Status (Protected Admin Route)
    const queueResponse = await apiClient.authedGet('/admin/queues/status', {
      tokenOverride: authToken,
    });

    expect(queueResponse.status).toBe(200);
    const queueResponseBody = await queueResponse.json();
    expect(Array.isArray(queueResponseBody.data)).toBe(true);
    // Verify that the 'flyer-processing' queue is present in the status report
    const flyerQueue = queueResponseBody.data.find((q: any) => q.name === 'flyer-processing');
    expect(flyerQueue).toBeDefined();
    expect(flyerQueue.counts).toBeDefined();
  });
});
