import { test, expect } from '@playwright/test';

test.describe('Demo Booking Flow', () => {
  test.describe('Demo Page', () => {
    test('should load demo page successfully', async ({ page }) => {
      await page.goto('/en/demo');

      await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
    });

    test('should display demo scheduler component', async ({ page }) => {
      await page.goto('/en/demo');

      // Check for key elements of the scheduler
      await expect(page.locator('text=/schedule|book|demo/i').first()).toBeVisible();
    });

    test('should allow selecting a date', async ({ page }) => {
      await page.goto('/en/demo');

      // Wait for calendar to load
      await page.waitForTimeout(1000);

      // Look for date picker or calendar
      const calendar = page.locator('[role="calendar"], [data-testid="calendar"]').first();
      if (await calendar.isVisible()) {
        await calendar.click();
      }
    });

    test('should show available time slots', async ({ page }) => {
      await page.goto('/en/demo');

      await page.waitForTimeout(1000);

      // Look for time slot buttons with AM or PM
      const timeSlots = page.locator('button').filter({ hasText: /AM|PM/ });
      const count = await timeSlots.count();

      expect(count).toBeGreaterThanOrEqual(0);
    });
  });

  test.describe('Booking Form', () => {
    test('should display contact form fields', async ({ page }) => {
      await page.goto('/en/demo');

      // Common form fields
      const nameInput = page.locator('input[name="name"], input[id*="name"], input[placeholder*="name" i]');
      const emailInput = page.locator('input[type="email"], input[name="email"], input[id*="email"]');

      // At least one of these should exist
      const hasNameField = await nameInput.count() > 0;
      const hasEmailField = await emailInput.count() > 0;

      expect(hasNameField || hasEmailField).toBe(true);
    });

    test('should validate email format', async ({ page }) => {
      await page.goto('/en/demo');

      const emailInput = page.locator('input[type="email"]').first();

      if (await emailInput.isVisible()) {
        await emailInput.fill('invalid-email');
        await emailInput.blur();

        // Check for validation message
        const errorMessage = page.locator('text=/invalid|valid email|email format/i');
        const hasError = await errorMessage.count() > 0;

        if (hasError) {
          await expect(errorMessage.first()).toBeVisible();
        }
      }
    });

    test('should validate required fields', async ({ page }) => {
      await page.goto('/en/demo');

      // Find submit button
      const submitButton = page.locator('button[type="submit"]').first();

      if (await submitButton.isVisible()) {
        await submitButton.click();

        // Should show validation errors
        const errorMessages = page.locator('text=/required|fill|enter/i');
        const errorCount = await errorMessages.count();

        expect(errorCount).toBeGreaterThanOrEqual(0);
      }
    });
  });

  test.describe('Duration Selection', () => {
    test('should allow selecting meeting duration', async ({ page }) => {
      await page.goto('/en/demo');

      // Look for duration options (30 min, 45 min, 60 min)
      const durationButtons = page.locator('button').filter({ hasText: /30|45|60|min/ });
      const count = await durationButtons.count();

      if (count > 0) {
        await durationButtons.first().click();
        await expect(durationButtons.first()).toHaveAttribute('aria-selected', 'true');
      }
    });
  });

  test.describe('Time Zone', () => {
    test('should display time zone selector', async ({ page }) => {
      await page.goto('/en/demo');

      // Look for timezone selector
      const timezoneSelect = page.locator('select, [data-testid="timezone"]').filter({ hasText: /GMT|UTC|timezone/i });
      const count = await timezoneSelect.count();

      expect(count).toBeGreaterThanOrEqual(0);
    });

    test('should default to user timezone', async ({ page }) => {
      await page.goto('/en/demo');

      // Get user's timezone
      const userTimezone = await page.evaluate(() => Intl.DateTimeFormat().resolvedOptions().timeZone);

      expect(userTimezone).toBeTruthy();
    });
  });

  test.describe('Complete Booking Flow', () => {
    test('should complete full 4-step booking flow with API and webhook', async ({ page }) => {
      // Mock n8n webhook to prevent actual calls
      await page.route('**/webhook-test/**', async (route) => {
        await route.fulfill({
          status: 200,
          contentType: 'application/json',
          body: JSON.stringify({ success: true }),
        });
      });

      // Mock API endpoint for testing
      await page.route('**/api/demo/book', async (route) => {
        const request = route.request();
        const postData = request.postDataJSON();

        // Validate request has required fields
        expect(postData).toHaveProperty('fullName');
        expect(postData).toHaveProperty('email');
        expect(postData).toHaveProperty('telephone');

        await route.fulfill({
          status: 201,
          contentType: 'application/json',
          body: JSON.stringify({
            success: true,
            message: 'Demo booking created successfully',
            bookingId: 'test-booking-e2e-123',
          }),
        });
      });

      await page.goto('/en/demo');

      // Step 1: Select duration
      await page.getByRole('button', { name: /1 hour|60/i }).click();
      await page.getByRole('button', { name: 'Next' }).click();

      // Step 2: Select date and time
      const firstAvailableDate = page.locator('[data-available="true"]').first();
      await firstAvailableDate.click();

      await page.waitForSelector('[data-time-slot]', { timeout: 5000 });
      const firstTimeSlot = page.locator('[data-time-slot]').first();
      await firstTimeSlot.click();

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

      // Step 3: Fill user info
      await page.fill('input[name="name"]', 'Ahmed Test User');
      await page.fill('input[name="email"]', 'ahmed.e2e@example.com');
      await page.fill('input[name="phone"]', '+971501234567');
      await page.fill('textarea[name="message"]', 'E2E test booking');

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

      // Step 4: Confirm booking
      await expect(page.getByText('Ahmed Test User')).toBeVisible();
      await expect(page.getByText('ahmed.e2e@example.com')).toBeVisible();

      await page.getByRole('button', { name: 'Confirm Booking' }).click();

      // Verify success message
      await expect(page.getByText(/confirmed|success|تم/i)).toBeVisible({ timeout: 10000 });
      await expect(page.getByText(/test-booking-e2e-123|BK-/i)).toBeVisible();
    });

    test('should show validation errors for missing fields', async ({ page }) => {
      await page.goto('/en/demo');

      // Skip through to user info without filling previous steps
      await page.getByRole('button', { name: /30 minutes|30/i }).click();
      await page.getByRole('button', { name: 'Next' }).click();

      const firstAvailableDate = page.locator('[data-available="true"]').first();
      await firstAvailableDate.click();
      await page.waitForSelector('[data-time-slot]');
      await page.locator('[data-time-slot]').first().click();
      await page.getByRole('button', { name: 'Next' }).click();

      // Try to proceed without filling form
      await page.getByRole('button', { name: 'Next' }).click();

      // Should show validation errors
      await expect(page.getByText(/required|مطلوب/i)).toBeVisible();
    });

    test('should handle API errors gracefully', async ({ page }) => {
      // Mock API error
      await page.route('**/api/demo/book', async (route) => {
        await route.fulfill({
          status: 500,
          contentType: 'application/json',
          body: JSON.stringify({ error: 'Database connection failed' }),
        });
      });

      await page.goto('/en/demo');

      // Complete form quickly
      await page.getByRole('button', { name: /30/i }).click();
      await page.getByRole('button', { name: 'Next' }).click();

      const firstAvailableDate = page.locator('[data-available="true"]').first();
      await firstAvailableDate.click();
      await page.waitForSelector('[data-time-slot]');
      await page.locator('[data-time-slot]').first().click();
      await page.getByRole('button', { name: 'Next' }).click();

      await page.fill('input[name="name"]', 'Error Test');
      await page.fill('input[name="email"]', 'error@test.com');
      await page.fill('input[name="phone"]', '+971501234567');
      await page.getByRole('button', { name: 'Next' }).click();

      await page.getByRole('button', { name: 'Confirm Booking' }).click();

      // Should show error message
      await expect(page.getByText(/error|failed|خطأ/i)).toBeVisible();
    });

    test('should show loading state during submission', async ({ page }) => {
      // Mock slow API
      await page.route('**/api/demo/book', async (route) => {
        await new Promise(resolve => setTimeout(resolve, 2000));
        await route.fulfill({
          status: 201,
          body: JSON.stringify({ success: true, bookingId: 'test-123' }),
        });
      });

      await page.goto('/en/demo');

      // Complete booking flow
      await page.getByRole('button', { name: /30/i }).click();
      await page.getByRole('button', { name: 'Next' }).click();

      const firstAvailableDate = page.locator('[data-available="true"]').first();
      await firstAvailableDate.click();
      await page.waitForSelector('[data-time-slot]');
      await page.locator('[data-time-slot]').first().click();
      await page.getByRole('button', { name: 'Next' }).click();

      await page.fill('input[name="name"]', 'Loading Test');
      await page.fill('input[name="email"]', 'loading@test.com');
      await page.fill('input[name="phone"]', '+971501234567');
      await page.getByRole('button', { name: 'Next' }).click();

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

      // Verify loading state
      await expect(page.getByText(/Submitting|جاري/i)).toBeVisible();
      await expect(confirmButton).toBeDisabled();
    });
  });

  test.describe('Arabic Version', () => {
    test('should display demo page in Arabic', async ({ page }) => {
      await page.goto('/ar/demo');

      // Check for Arabic text
      const content = await page.locator('body').textContent();
      const hasArabic = /[\u0600-\u06FF]/.test(content || '');
      expect(hasArabic).toBe(true);
    });

    test('should have RTL layout', async ({ page }) => {
      await page.goto('/ar/demo');

      const form = page.locator('form').first();
      if (await form.isVisible()) {
        await expect(form).toHaveAttribute('dir', 'rtl');
      }
    });
  });

  test.describe('Responsive Design', () => {
    test('should work on mobile', async ({ page }) => {
      await page.setViewportSize({ width: 375, height: 667 });
      await page.goto('/en/demo');

      await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
    });

    test('should work on tablet', async ({ page }) => {
      await page.setViewportSize({ width: 768, height: 1024 });
      await page.goto('/en/demo');

      await expect(page.getByRole('heading', { level: 1 })).toBeVisible();
    });
  });

  test.describe('Accessibility', () => {
    test('should have accessible form labels', async ({ page }) => {
      await page.goto('/en/demo');

      const inputs = await page.locator('input').all();

      for (const input of inputs) {
        const id = await input.getAttribute('id');
        const ariaLabel = await input.getAttribute('aria-label');
        const ariaLabelledBy = await input.getAttribute('aria-labelledby');
        const name = await input.getAttribute('name');

        // Should have at least one way to identify the field
        const hasLabel = id || ariaLabel || ariaLabelledBy || name;
        expect(hasLabel).toBeTruthy();
      }
    });

    test('should support keyboard navigation', async ({ page }) => {
      await page.goto('/en/demo');

      // Tab through form
      await page.keyboard.press('Tab');
      await page.keyboard.press('Tab');
      await page.keyboard.press('Tab');

      const focusedElement = await page.evaluate(() => document.activeElement?.tagName);
      expect(focusedElement).toBeTruthy();
    });
  });
});
