/**
 * Demo Booking End-to-End Test
 *
 * Verifies complete booking flow:
 * 1. Cookie consent handling
 * 2. Form validation
 * 3. API submission
 * 4. Success message display
 * 5. Database persistence
 */

import { test, expect } from '@playwright/test';
import { createClient } from '@supabase/supabase-js';

// Supabase client for database verification
const supabase = createClient(
  process.env.NEXT_PUBLIC_SUPABASE_URL || 'http://127.0.0.1:54321',
  process.env.SUPABASE_SERVICE_ROLE_KEY || 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZS1kZW1vIiwicm9sZSI6InNlcnZpY2Vfcm9sZSIsImV4cCI6MTk4MzgxMjk5Nn0.EGIM96RAZx35lJzdJsyH-qQwv8Hdp7fsn3W0YpN81IU'
);

test.describe('Demo Booking - Complete Flow', () => {
  test('should complete booking and save to database', async ({ page }) => {
    // Unique email for this test
    const testEmail = `e2e-test-${Date.now()}@mawidi.com`;
    let bookingId: string | null = null;

    test.setTimeout(90000); // 90 seconds for complete flow

    console.log('🧪 Starting complete booking flow test');

    // Navigate to demo page
    await page.goto('http://localhost:9000/en/demo');
    await page.waitForLoadState('networkidle');

    // Handle cookie consent banner
    try {
      const cookieBanner = page.locator('text=cookies').first();
      if (await cookieBanner.isVisible({ timeout: 2000 })) {
        console.log('📋 Cookie banner detected, dismissing...');
        const acceptButton = page.getByRole('button', { name: /accept|got it|okay/i });
        await acceptButton.click({ timeout: 5000 });
        await page.waitForTimeout(500);
      }
    } catch (e) {
      console.log('No cookie banner or already dismissed');
    }

    // Step 1: Select Duration (30 minutes)
    console.log('1️⃣ Selecting duration...');
    await page.getByRole('button', { name: /30 minutes/i }).click();

    // Verify helper text appears
    await expect(page.getByText(/You've selected a 30 minutes session/i)).toBeVisible();

    // Click Next
    await page.getByRole('button', { name: 'Next' }).click();
    await page.waitForTimeout(1000);

    // Step 2: Select Date & Time
    console.log('2️⃣ Selecting date and time...');

    // Select tomorrow's date
    const tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    const dayStr = tomorrow.getDate().toString();

    // Find and click tomorrow's date button
    const dateButton = page.locator(`button[aria-label*="${dayStr}"]`).first();
    await dateButton.click();
    await page.waitForTimeout(500);

    // Select time slot 14:00 (2:00 PM)
    const timeSlot = page.getByRole('button', { name: /14:00|2:00 PM/i }).first();
    await timeSlot.click();

    // Click Next
    await page.getByRole('button', { name: 'Next' }).click();
    await page.waitForTimeout(1000);

    // Step 3: Fill User Information
    console.log('3️⃣ Filling user information...');

    await page.getByLabel(/name/i).fill('E2E Test User');
    await page.getByLabel(/email/i).fill(testEmail);
    await page.getByLabel(/phone|telephone/i).fill('+966501234567');

    const messageField = page.getByLabel(/message|requirements/i);
    await messageField.fill('Automated end-to-end test booking');

    // Click Next to confirmation
    await page.getByRole('button', { name: 'Next' }).click();
    await page.waitForTimeout(1000);

    // Step 4: Confirm Booking
    console.log('4️⃣ Confirming booking...');

    // Set up response listener BEFORE clicking
    const responsePromise = page.waitForResponse(
      response => {
        return response.url().includes('/api/demo/book') &&
               response.request().method() === 'POST';
      },
      { timeout: 15000 }
    );

    // Click Confirm Booking button
    const confirmButton = page.getByRole('button', { name: /Confirm Booking/i });
    await confirmButton.click();

    // Wait for API response
    console.log('5️⃣ Waiting for API response...');
    const apiResponse = await responsePromise;

    const statusCode = apiResponse.status();
    const responseBody = await apiResponse.json();

    console.log(`API Status: ${statusCode}`);
    console.log(`API Response:`, responseBody);

    // Verify API success
    expect(statusCode).toBe(201);
    expect(responseBody.success).toBe(true);
    expect(responseBody.bookingId).toBeTruthy();

    bookingId = responseBody.bookingId;
    console.log(`✅ Booking ID: ${bookingId}`);

    // Wait for success screen
    await page.waitForTimeout(2000);

    // Step 5: Verify Success Message
    console.log('6️⃣ Verifying success message...');

    // Check for success indicators
    const successMessage = page.getByText(/success|confirmed|booked/i);
    await expect(successMessage).toBeVisible({ timeout: 10000 });

    // Verify booking reference is displayed
    const referenceText = page.getByText(new RegExp(bookingId || 'BK-'));
    await expect(referenceText).toBeVisible();

    // Verify action buttons exist
    await expect(page.getByRole('button', { name: /Add to Calendar/i })).toBeVisible();
    await expect(page.getByRole('button', { name: /Book Another/i })).toBeVisible();

    console.log('✅ Success message verified');

    // Step 6: Verify in Database
    console.log('7️⃣ Verifying in Supabase database...');

    if (bookingId) {
      await new Promise(resolve => setTimeout(resolve, 1000)); // Wait for DB write

      const { data, error } = await supabase
        .from('demo_bookings')
        .select('*')
        .eq('id', bookingId)
        .single();

      expect(error).toBeNull();
      expect(data).toBeTruthy();
      expect(data?.email).toBe(testEmail);
      expect(data?.telephone).toBe('+966501234567');
      expect(data?.status).toBe('pending');

      console.log('✅ Booking verified in database:');
      console.log(`   ID: ${data?.id}`);
      console.log(`   Name: ${data?.full_name}`);
      console.log(`   Email: ${data?.email}`);
      console.log(`   Phone: ${data?.telephone}`);
      console.log(`   Date: ${data?.appointment_date}`);
      console.log(`   Time: ${data?.appointment_time}`);

      // Cleanup test data
      await supabase.from('demo_bookings').delete().eq('id', bookingId);
      console.log('🧹 Cleaned up test booking from database');
    }

    console.log('🎉 Complete booking flow test PASSED!');
  });

  test('should show validation errors for invalid phone', async ({ page }) => {
    await page.goto('http://localhost:9000/en/demo');
    await page.waitForLoadState('networkidle');

    // Dismiss cookies
    try {
      const acceptButton = page.getByRole('button', { name: /accept|got it/i });
      if (await acceptButton.isVisible({ timeout: 2000 })) {
        await acceptButton.click();
      }
    } catch (e) {
      // No banner
    }

    // Go through form with invalid phone
    await page.getByRole('button', { name: /30 minutes/i }).click();
    await page.getByRole('button', { name: 'Next' }).click();

    // Select date and time
    await page.waitForTimeout(1000);
    const tomorrow = new Date();
    tomorrow.setDate(tomorrow.getDate() + 1);
    const dateButton = page.locator(`button[aria-label*="${tomorrow.getDate()}"]`).first();
    await dateButton.click();
    await page.waitForTimeout(500);

    const timeSlot = page.getByRole('button', { name: /14:00/i }).first();
    await timeSlot.click();
    await page.getByRole('button', { name: 'Next' }).click();

    // Fill with invalid phone (no +, letters)
    await page.getByLabel(/name/i).fill('Test User');
    await page.getByLabel(/email/i).fill('test@test.com');
    await page.getByLabel(/phone/i).fill('abc123'); // Invalid
    await page.getByLabel(/message/i).fill('Test');

    // Try to proceed - should show error
    await page.getByRole('button', { name: 'Next' }).click();

    // Should see validation error
    const errorMessage = page.getByText(/phone|invalid|format/i);
    await expect(errorMessage).toBeVisible({ timeout: 5000 });

    console.log('✅ Validation error shown correctly');
  });
});
