/**
 * E2E Tests: PreferencesTab Internationalization & RTL
 *
 * Tests translation completeness, language switching, RTL layout,
 * and bilingual UX consistency for the Preferences settings tab.
 *
 * Run with: npm run test:e2e -- preferences-i18n.spec.ts
 */

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

// Test configuration
const BASE_URL = process.env.BASE_URL || 'http://localhost:9000';
const TEST_USER = {
  email: 'guqo@mailinator.com',
  // OTP will be fetched from MailHog at http://localhost:8025
};

test.describe('PreferencesTab - Internationalization', () => {
  test.beforeEach(async ({ page }) => {
    // Login as test user (assumes user is already registered)
    // You may need to adapt this based on your auth flow
    await page.goto(`${BASE_URL}/en/signin`);
    // Add login steps here if not already logged in
    // For now, assume we're testing with authenticated session
  });

  test.describe('Translation Completeness - English', () => {
    test('displays all labels in English', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Main section
      await expect(page.locator('h2')).toContainText('Preferences');
      await expect(page.locator('text=Customize your experience')).toBeVisible();

      // Language & Localization section
      await expect(page.locator('text=Language & Localization')).toBeVisible();
      await expect(page.locator('label:has-text("Language")')).toBeVisible();
      await expect(page.locator('label:has-text("Timezone")')).toBeVisible();

      // Email Notifications section
      await expect(page.locator('text=Email Notifications')).toBeVisible();

      // Notification types
      await expect(page.locator('text=New bookings')).toBeVisible();
      await expect(page.locator('text=Appointment reminders')).toBeVisible();
      await expect(page.locator('text=Payment receipts')).toBeVisible();
      await expect(page.locator('text=Marketing emails')).toBeVisible();
      await expect(page.locator('text=Security alerts')).toBeVisible();
      await expect(page.locator('text=Weekly report')).toBeVisible();

      // Save button
      await expect(page.locator('button:has-text("Save Changes")')).toBeVisible();
    });

    test('displays timezone options in English', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      const timezoneSelect = page.locator('select').nth(1); // Timezone dropdown
      const options = await timezoneSelect.locator('option').allTextContents();

      expect(options.join(' ')).toContain('Qatar');
      expect(options.join(' ')).toContain('UAE');
      expect(options.join(' ')).toContain('Saudi Arabia');
      expect(options.join(' ')).toContain('Kuwait');
      expect(options.join(' ')).toContain('Bahrain');
      expect(options.join(' ')).toContain('Oman');
    });
  });

  test.describe('Translation Completeness - Arabic', () => {
    test('displays all labels in Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Main section
      await expect(page.locator('h2')).toContainText('التفضيلات');
      await expect(page.locator('text=تخصيص تجربتك')).toBeVisible();

      // Language & Localization section
      await expect(page.locator('text=اللغة والتوطين')).toBeVisible();
      await expect(page.locator('label:has-text("اللغة")')).toBeVisible();
      await expect(page.locator('label:has-text("المنطقة الزمنية")')).toBeVisible();

      // Email Notifications section
      await expect(page.locator('text=إشعارات البريد الإلكتروني')).toBeVisible();

      // Notification types
      await expect(page.locator('text=حجوزات جديدة')).toBeVisible();
      await expect(page.locator('text=تذكيرات المواعيد')).toBeVisible();
      await expect(page.locator('text=إيصالات الدفع')).toBeVisible();
      await expect(page.locator('text=رسائل تسويقية')).toBeVisible();
      await expect(page.locator('text=تنبيهات أمنية')).toBeVisible();
      await expect(page.locator('text=تقرير أسبوعي')).toBeVisible();

      // Save button
      await expect(page.locator('button:has-text("حفظ التغييرات")')).toBeVisible();
    });

    test('displays timezone options in Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      const timezoneSelect = page.locator('select').nth(1); // Timezone dropdown
      const options = await timezoneSelect.locator('option').allTextContents();

      expect(options.join(' ')).toContain('قطر');
      expect(options.join(' ')).toContain('الإمارات');
      expect(options.join(' ')).toContain('السعودية');
      expect(options.join(' ')).toContain('الكويت');
      expect(options.join(' ')).toContain('البحرين');
      expect(options.join(' ')).toContain('عمان');
    });

    test('uses Arabic script for all text', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Get all visible text
      const allText = await page.locator('body').textContent();

      // Check that Arabic text contains Arabic Unicode characters
      const hasArabicScript = /[\u0600-\u06FF]/.test(allText || '');
      expect(hasArabicScript).toBe(true);
    });
  });

  test.describe('RTL Layout', () => {
    test('applies RTL direction for Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Check HTML dir attribute
      const dir = await page.locator('html').getAttribute('dir');
      expect(dir).toBe('rtl');

      // Check language attribute
      const lang = await page.locator('html').getAttribute('lang');
      expect(lang).toBe('ar');
    });

    test('applies LTR direction for English', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      const dir = await page.locator('html').getAttribute('dir');
      expect(dir).toBe('ltr');

      const lang = await page.locator('html').getAttribute('lang');
      expect(lang).toBe('en');
    });

    test('text aligns correctly for RTL', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Check main heading alignment
      const heading = page.locator('h2').first();
      const textAlign = await heading.evaluate(el =>
        window.getComputedStyle(el).textAlign
      );

      // In RTL, text should be right-aligned or start-aligned (which resolves to right)
      expect(['right', 'start']).toContain(textAlign);
    });

    test('toggle switches render in both directions', async ({ page }) => {
      // English toggles
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);
      const toggleEn = page.locator('button[type="button"]').first();
      const toggleEnVisible = await toggleEn.isVisible();
      expect(toggleEnVisible).toBe(true);

      // Arabic toggles
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);
      const toggleAr = page.locator('button[type="button"]').first();
      const toggleArVisible = await toggleAr.isVisible();
      expect(toggleArVisible).toBe(true);

      // Note: Visual direction of toggle knob movement is handled by CSS
      // and should be tested with visual regression tools
    });

    test('form layout maintains structure in RTL', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Check grid layout (should be 2 columns on desktop)
      const grid = page.locator('.grid').first();
      const gridColumns = await grid.evaluate(el =>
        window.getComputedStyle(el).gridTemplateColumns
      );

      // Should have multiple columns (exact value depends on viewport)
      expect(gridColumns).toBeTruthy();
    });
  });

  test.describe('Language Switching', () => {
    test('shows warning when language selection changes', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Change language to Arabic
      await page.selectOption('select', 'ar');

      // Should show warning message
      await expect(page.locator('text=Page will reload')).toBeVisible({
        timeout: 1000,
      });
    });

    test('switches from English to Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Change language
      await page.selectOption('select', 'ar');

      // Click Save
      await page.click('button:has-text("Save Changes")');

      // Should show success message
      await expect(page.locator('text=Saved! Redirecting...')).toBeVisible({
        timeout: 2000,
      });

      // Should redirect to Arabic version
      await page.waitForURL(`${BASE_URL}/ar/dashboard**`, {
        timeout: 3000,
      });

      // Verify we're on Arabic page
      const dir = await page.locator('html').getAttribute('dir');
      expect(dir).toBe('rtl');
    });

    test('switches from Arabic to English', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Change language
      await page.selectOption('select', 'en');

      // Click Save (Arabic button)
      await page.click('button:has-text("حفظ التغييرات")');

      // Should show success message in Arabic
      await expect(page.locator('text=تم الحفظ')).toBeVisible({
        timeout: 2000,
      });

      // Should redirect to English version
      await page.waitForURL(`${BASE_URL}/en/dashboard**`, {
        timeout: 3000,
      });

      // Verify we're on English page
      const dir = await page.locator('html').getAttribute('dir');
      expect(dir).toBe('ltr');
    });

    test('preserves current route during language switch', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Change language and save
      await page.selectOption('select', 'ar');
      await page.click('button:has-text("Save Changes")');

      // Wait for redirect
      await page.waitForURL(`${BASE_URL}/ar/dashboard**`, { timeout: 3000 });

      // Should still be on dashboard, not redirected to home
      expect(page.url()).toContain('/dashboard');
    });
  });

  test.describe('Notification Toggles', () => {
    test('toggles work in English', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Find the first notification toggle
      const firstToggle = page
        .locator('label')
        .filter({ hasText: 'New bookings' })
        .locator('button')
        .first();

      // Get initial state
      const initialClass = await firstToggle.getAttribute('class');
      const initiallyEnabled = initialClass?.includes('bg-brand-green');

      // Click toggle
      await firstToggle.click();

      // Wait for state change
      await page.waitForTimeout(200);

      // Verify state changed
      const newClass = await firstToggle.getAttribute('class');
      const nowEnabled = newClass?.includes('bg-brand-green');

      expect(nowEnabled).not.toBe(initiallyEnabled);
    });

    test('toggles work in Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Find the first notification toggle (Arabic label)
      const firstToggle = page
        .locator('label')
        .filter({ hasText: 'حجوزات جديدة' })
        .locator('button')
        .first();

      // Get initial state
      const initialClass = await firstToggle.getAttribute('class');
      const initiallyEnabled = initialClass?.includes('bg-brand-green');

      // Click toggle
      await firstToggle.click();

      // Wait for state change
      await page.waitForTimeout(200);

      // Verify state changed
      const newClass = await firstToggle.getAttribute('class');
      const nowEnabled = newClass?.includes('bg-brand-green');

      expect(nowEnabled).not.toBe(initiallyEnabled);
    });

    test('all 6 notification toggles are present', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Count toggle buttons in the notification section
      const toggles = page.locator('button[type="button"]');
      const count = await toggles.count();

      // Should have 6 notification toggles
      expect(count).toBeGreaterThanOrEqual(6);
    });
  });

  test.describe('Save Functionality', () => {
    test('saves preferences successfully in English', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Change timezone
      await page.selectOption('select', { index: 1 });

      // Click Save
      await page.click('button:has-text("Save Changes")');

      // Should show success message
      await expect(
        page.locator('text=Preferences saved successfully')
      ).toBeVisible({ timeout: 2000 });

      // Success message should disappear after 3 seconds
      await expect(
        page.locator('text=Preferences saved successfully')
      ).not.toBeVisible({ timeout: 4000 });
    });

    test('saves preferences successfully in Arabic', async ({ page }) => {
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

      // Change timezone
      await page.selectOption('select', { index: 1 });

      // Click Save (Arabic)
      await page.click('button:has-text("حفظ التغييرات")');

      // Should show success message in Arabic
      await expect(page.locator('text=تم حفظ التفضيلات بنجاح')).toBeVisible({
        timeout: 2000,
      });
    });

    test('shows error message in correct language', async ({ page }) => {
      // Test error handling (you may need to mock an API error)
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Mock API error
      await page.route('**/api/user/preferences', route =>
        route.fulfill({
          status: 500,
          contentType: 'application/json',
          body: JSON.stringify({ error: 'Server error' }),
        })
      );

      // Try to save
      await page.click('button:has-text("Save Changes")');

      // Should show error message
      await expect(page.locator('[role="alert"]')).toBeVisible({
        timeout: 2000,
      });
    });

    test('disables save button when no changes', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Save button should be disabled initially (no changes)
      const saveButton = page.locator('button:has-text("Save Changes")');
      const isDisabled = await saveButton.isDisabled();

      expect(isDisabled).toBe(true);
    });

    test('enables save button when changes made', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Make a change
      const firstToggle = page.locator('button[type="button"]').first();
      await firstToggle.click();

      // Wait a bit for state update
      await page.waitForTimeout(300);

      // Save button should now be enabled
      const saveButton = page.locator('button:has-text("Save Changes")');
      const isDisabled = await saveButton.isDisabled();

      expect(isDisabled).toBe(false);
    });
  });

  test.describe('Loading States', () => {
    test('shows loading spinner initially', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Should show loading state briefly (or might be too fast to catch)
      const loadingSpinner = page.locator('.animate-spin');

      // If visible, verify it has loading text
      const isVisible = await loadingSpinner.isVisible();
      if (isVisible) {
        await expect(page.locator('text=Loading...')).toBeVisible();
      }
    });

    test('shows saving state when saving', async ({ page }) => {
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

      // Make a change
      const firstToggle = page.locator('button[type="button"]').first();
      await firstToggle.click();
      await page.waitForTimeout(200);

      // Start saving
      const saveButton = page.locator('button:has-text("Save Changes")');
      await saveButton.click();

      // Should briefly show "Saving..." (might be too fast)
      // Use a race condition to catch it if possible
      try {
        await expect(page.locator('button:has-text("Saving...")')).toBeVisible({
          timeout: 500,
        });
      } catch {
        // Too fast to catch, that's okay
      }
    });
  });

  test.describe('Bilingual UX Consistency', () => {
    test('same number of form elements in both languages', async ({ page }) => {
      // Count elements in English
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);
      const selectsEn = await page.locator('select').count();
      const buttonsEn = await page.locator('button[type="button"]').count();

      // Count elements in Arabic
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);
      const selectsAr = await page.locator('select').count();
      const buttonsAr = await page.locator('button[type="button"]').count();

      // Should have same number of controls
      expect(selectsAr).toBe(selectsEn);
      expect(buttonsAr).toBe(buttonsEn);
    });

    test('layout structure consistent across languages', async ({ page }) => {
      // Check English layout
      await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);
      const sectionsEn = await page.locator('h3, h2').count();

      // Check Arabic layout
      await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);
      const sectionsAr = await page.locator('h3, h2').count();

      // Should have same number of sections
      expect(sectionsAr).toBe(sectionsEn);
    });

    test('no text overflow in both languages', async ({ page }) => {
      const languages = [
        { lang: 'en', url: `${BASE_URL}/en/dashboard/settings?tab=preferences` },
        { lang: 'ar', url: `${BASE_URL}/ar/dashboard/settings?tab=preferences` },
      ];

      for (const { lang, url } of languages) {
        await page.goto(url);

        // Check all labels for overflow
        const labels = page.locator('label');
        const count = await labels.count();

        for (let i = 0; i < count; i++) {
          const label = labels.nth(i);
          const box = await label.boundingBox();

          if (box) {
            const scrollWidth = await label.evaluate(
              el => (el as HTMLElement).scrollWidth
            );
            const clientWidth = await label.evaluate(
              el => (el as HTMLElement).clientWidth
            );

            // Text should not overflow container (allow 5px tolerance)
            expect(scrollWidth).toBeLessThanOrEqual(clientWidth + 5);
          }
        }
      }
    });
  });
});

test.describe('PreferencesTab - Accessibility', () => {
  test('has proper ARIA labels in English', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

    // Check for proper form labels
    const labels = page.locator('label');
    const count = await labels.count();
    expect(count).toBeGreaterThan(0);

    // Check for alert regions (for messages)
    // This may need to be added to the component
  });

  test('has proper ARIA labels in Arabic', async ({ page }) => {
    await page.goto(`${BASE_URL}/ar/dashboard/settings?tab=preferences`);

    const labels = page.locator('label');
    const count = await labels.count();
    expect(count).toBeGreaterThan(0);
  });

  test('keyboard navigation works', async ({ page }) => {
    await page.goto(`${BASE_URL}/en/dashboard/settings?tab=preferences`);

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

    // Should be able to focus on selects and buttons
    const activeElement = await page.evaluate(() => document.activeElement?.tagName);
    expect(['SELECT', 'BUTTON', 'INPUT']).toContain(activeElement || '');
  });
});
