/**
 * Database Fixtures for Playwright Tests
 * 
 * Provides direct database access for test setup and teardown using service role.
 * IMPORTANT: Only use for test data management, never in production code!
 */

import { createClient } from '@supabase/supabase-js';
import type { Database } from '@/integrations/supabase/types';

const supabaseUrl = 'https://ydvtmnrszybqnbcqbdcy.supabase.co';
const supabaseAnonKey = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InlkdnRtbnJzenlicW5iY3FiZGN5Iiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTgzMjYzNTYsImV4cCI6MjA3MzkwMjM1Nn0.DM3oyapd_omP5ZzIlrT0H9qBsiQBxBRgw2tYuqgXKX4';

// For test setup/teardown only - requires service role key
const supabaseServiceRoleKey = process.env.SUPABASE_SERVICE_ROLE_KEY;

// Regular client for authenticated operations
export const supabase = createClient<Database>(supabaseUrl, supabaseAnonKey);

// Service role client for test setup/teardown (bypasses RLS)
export const supabaseAdmin = supabaseServiceRoleKey
  ? createClient<Database>(supabaseUrl, supabaseServiceRoleKey)
  : null;

/**
 * Create a test user with specific role
 */
export async function setupTestUser(
  email: string,
  password: string,
  role: 'user' | 'moderator' | 'admin' | 'superuser' = 'user'
): Promise<{ userId: string; email: string }> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  // Check if user already exists
  const { data: existingUsers } = await supabaseAdmin.auth.admin.listUsers();
  const existingUser = existingUsers?.users.find(u => u.email === email);

  let userId: string;

  if (existingUser) {
    // User exists - use their ID
    userId = existingUser.id;
    console.log(`ℹ️  Using existing test user: ${email}`);
  } else {
    // User doesn't exist - create new one
    const { data: authData, error: authError } = await supabaseAdmin.auth.admin.createUser({
      email,
      password,
      email_confirm: true,
    });

    if (authError) throw authError;
    if (!authData.user) throw new Error('User creation failed');

    userId = authData.user.id;
    console.log(`✓ Created new test user: ${email}`);
  }

  // Create or update profile (ensures correct role and is_test_data flag)
  const { error: profileError } = await supabaseAdmin
    .from('profiles')
    .upsert({
      id: userId,
      username: email.split('@')[0],
      email,
      role,
      is_test_data: true,
    });

  if (profileError) throw profileError;

  return { userId, email };
}

/**
 * Clean up all test data
 */
export async function cleanupTestData(): Promise<void> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  // Delete in dependency order (child tables first)
  const tables = [
    'moderation_audit_log',
    'ride_photos',
    'park_photos',
    'submission_items',
    'content_submissions',
    'ride_versions',
    'park_versions',
    'company_versions',
    'ride_model_versions',
    'rides',
    'ride_models',
    'parks',
    'companies',
  ];

  for (const table of tables) {
    await supabaseAdmin
      .from(table as any)
      .delete()
      .eq('is_test_data', true);
  }

  // Delete test profiles
  const { data: profiles } = await supabaseAdmin
    .from('profiles')
    .select('id')
    .eq('is_test_data', true);

  if (profiles) {
    for (const profile of profiles) {
      await supabaseAdmin.auth.admin.deleteUser(profile.id);
    }
  }
}

/**
 * Query database directly for assertions
 */
export async function queryDatabase<T = any>(
  table: string,
  query: (qb: any) => any
): Promise<T[]> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  const { data, error } = await query(supabaseAdmin.from(table));
  
  if (error) throw error;
  return data || [];
}

/**
 * Wait for a version to be created
 */
export async function waitForVersion(
  entityId: string,
  versionNumber: number,
  table: string,
  maxWaitMs: number = 5000
): Promise<boolean> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  const startTime = Date.now();
  
  while (Date.now() - startTime < maxWaitMs) {
    const { data } = await supabaseAdmin
      .from(table as any)
      .select('version_number')
      .eq('entity_id', entityId)
      .eq('version_number', versionNumber)
      .single();

    if (data) return true;
    
    await new Promise(resolve => setTimeout(resolve, 500));
  }

  return false;
}

/**
 * Approve a submission directly (for test setup)
 */
export async function approveSubmissionDirect(submissionId: string): Promise<void> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  const { error } = await supabaseAdmin.rpc('approve_submission', {
    submission_id: submissionId,
  });

  if (error) throw error;
}

/**
 * Get test data statistics
 */
export async function getTestDataStats(): Promise<Record<string, number>> {
  if (!supabaseAdmin) {
    throw new Error('Service role key not configured');
  }

  const tables = ['parks', 'rides', 'companies', 'ride_models', 'content_submissions', 'moderation_audit_log'];
  const stats: Record<string, number> = {};

  for (const table of tables) {
    const { count } = await supabaseAdmin
      .from(table as any)
      .select('*', { count: 'exact', head: true })
      .eq('is_test_data', true);

    stats[table] = count || 0;
  }

  return stats;
}
