/**
 * Integration test helpers
 */

import { FastifyInstance } from 'fastify';
import { Pool } from 'pg';
import { createTestPool, seedDatabase, cleanupDatabase } from './db-helpers';
import { createApiHelpers } from './api-helpers';

export interface IntegrationTestContext {
  app: FastifyInstance;
  db: Pool;
  api: ReturnType<typeof createApiHelpers>;
  cleanup: () => Promise<void>;
}

/**
 * Setup integration test environment
 */
export async function setupIntegrationTest(
  app: FastifyInstance,
  dbConnectionString?: string
): Promise<IntegrationTestContext> {
  // Create test database connection
  const db = createTestPool(dbConnectionString);
  
  // Seed database
  await seedDatabase(db);
  
  // Create API helpers
  const api = createApiHelpers(app);
  
  // Cleanup function
  const cleanup = async () => {
    await cleanupDatabase(db);
    await db.end();
  };
  
  return {
    app,
    db,
    api,
    cleanup,
  };
}

/**
 * Create authenticated request headers
 */
export function createAuthHeaders(token: string): Record<string, string> {
  return {
    Authorization: `Bearer ${token}`,
  };
}

/**
 * Create test user and get auth token
 */
export async function createTestUserWithToken(
  api: ReturnType<typeof createApiHelpers>,
  userData?: { email: string; password: string; name: string }
): Promise<{ userId: string; token: string }> {
  const user = userData || {
    email: `test-${Date.now()}@example.com`,
    password: 'TestPassword123!',
    name: 'Test User',
  };
  
  // Register user
  const registerResponse = await api.post('/auth/register', user);
  
  if (registerResponse.status !== 201) {
    throw new Error(`Failed to register user: ${registerResponse.status}`);
  }
  
  // Login to get token
  const loginResponse = await api.post('/auth/login', {
    email: user.email,
    password: user.password,
  });
  
  if (loginResponse.status !== 200) {
    throw new Error(`Failed to login: ${loginResponse.status}`);
  }
  
  const { token, userId } = loginResponse.body as { token: string; userId: string };
  
  return { userId, token };
}

/**
 * Wait for async operation to complete
 */
export async function waitForAsync(
  condition: () => Promise<boolean>,
  timeout: number = 5000,
  interval: number = 100
): Promise<void> {
  const start = Date.now();
  
  while (Date.now() - start < timeout) {
    if (await condition()) {
      return;
    }
    await new Promise((resolve) => setTimeout(resolve, interval));
  }
  
  throw new Error(`Condition not met within ${timeout}ms`);
}

/**
 * Create test data for integration tests
 */
export function createIntegrationTestData() {
  return {
    user: {
      email: `test-${Date.now()}@example.com`,
      password: 'TestPassword123!',
      name: 'Test User',
    },
    document: {
      title: 'Test Document',
      type: 'legal',
      content: 'Test content',
    },
    credential: {
      subject: `did:web:example.com:user:${Date.now()}`,
      type: ['VerifiableCredential', 'TestCredential'],
      credentialSubject: {
        name: 'Test User',
        email: `test-${Date.now()}@example.com`,
      },
    },
  };
}

