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

/**
 * E2E Form Interactions Test Suite
 * Deep testing of contact form with various scenarios
 */

test.describe('Contact Form - Complete Interaction Flow', () => {
  test.beforeEach(async ({ page }) => {
    await page.goto('/contact');
  });

  test('successful form submission with all fields', async ({ page }) => {
    // Fill all fields including optional ones
    await page.locator('input[name="name"]').fill('Alice Johnson');
    await page.locator('#contact-form input[name="email"]').fill('alice.johnson@company.com');
    await page.locator('input[name="phone"]').fill('+1 (555) 987-6543');
    await page.locator('select[name="subject"]').selectOption('cloud-services');
    await page.locator('textarea[name="message"]').fill('I need help migrating our infrastructure to the cloud. We currently run on-premise servers and want to move to AWS.');

    // Submit
    const submitButton = page.locator('#contact-form button[type="submit"]');
    await submitButton.click();

    // Verify loading state
    await expect(submitButton).toBeDisabled();

    // Verify success or API response (rate limiting may occur during testing)
    await page.waitForFunction(() => {
      const successState = document.getElementById('success-state');
      const toastAlert = document.querySelector('#toast-container [role="alert"]');
      const successVisible = successState && !successState.classList.contains('hidden');
      const toastVisible = toastAlert && (toastAlert as HTMLElement).offsetParent !== null;
      return successVisible || toastVisible;
    }, { timeout: 10000 });
  });

  test('form validation - empty submission', async ({ page }) => {
    // Try to submit without filling anything
    await page.locator('#contact-form button[type="submit"]').click();

    // Check for validation errors
    const nameInput = page.locator('input[name="name"]');
    const emailInput = page.locator('#contact-form input[name="email"]');

    const nameInvalid = await nameInput.evaluate((el: HTMLInputElement) => !el.checkValidity());
    const emailInvalid = await emailInput.evaluate((el: HTMLInputElement) => !el.checkValidity());

    expect(nameInvalid || await page.locator('[class*="error"]').count() > 0).toBeTruthy();
  });

  test('form validation - invalid email format', async ({ page }) => {
    await page.locator('input[name="name"]').fill('Test User');
    await page.locator('#contact-form input[name="email"]').fill('invalid-email');
    await page.locator('select[name="subject"]').selectOption('consulting');
    await page.locator('textarea[name="message"]').fill('This is a test message.');

    await page.locator('#contact-form button[type="submit"]').click();

    // Should show email error
    const emailError = page.locator('[data-error="email"]');
    await expect(emailError).toBeVisible();
  });

  test('form validation - name too short', async ({ page }) => {
    await page.locator('input[name="name"]').fill('A');
    await page.locator('#contact-form input[name="email"]').fill('valid@email.com');
    await page.locator('select[name="subject"]').selectOption('web-development');
    await page.locator('textarea[name="message"]').fill('Test message content here.');

    await page.locator('#contact-form button[type="submit"]').click();

    // Should show name error
    const nameError = page.locator('[data-error="name"]');
    await expect(nameError).toBeVisible();
  });

  test('form validation - message too short', async ({ page }) => {
    await page.locator('input[name="name"]').fill('Valid Name');
    await page.locator('#contact-form input[name="email"]').fill('valid@email.com');
    await page.locator('select[name="subject"]').selectOption('ai-ml');
    await page.locator('textarea[name="message"]').fill('Short');

    await page.locator('#contact-form button[type="submit"]').click();

    // Should show message error
    const messageError = page.locator('[data-error="message"]');
    await expect(messageError).toBeVisible();
  });

  test('form validation - real-time email correction', async ({ page }) => {
    const emailInput = page.locator('#contact-form input[name="email"]');

    // Type invalid email
    await emailInput.fill('bad-email');
    await emailInput.blur();

    // Should show error
    await page.waitForTimeout(200);
    const hasError = await page.locator('[data-error="email"]').isVisible();

    // Correct the email
    await emailInput.fill('good@email.com');
    await emailInput.blur();

    // Error should disappear
    await page.waitForTimeout(200);
    const errorGone = await page.locator('[data-error="email"]').isHidden();
    expect(errorGone).toBeTruthy();
  });

  test('honeypot protection - bot detection', async ({ page }) => {
    // Fill form normally
    await page.locator('input[name="name"]').fill('Bot User');
    await page.locator('#contact-form input[name="email"]').fill('bot@spam.com');
    await page.locator('select[name="subject"]').selectOption('other');
    await page.locator('textarea[name="message"]').fill('This is spam content.');

    // Fill honeypot field (bots do this)
    await page.evaluate(() => {
      const honeypot = document.querySelector('input[name="website"]') as HTMLInputElement;
      if (honeypot) honeypot.value = 'http://spam.com';
    });

    await page.locator('#contact-form button[type="submit"]').click();

    // Should show success (silent fail - honeypot triggers server-side reject but shows success to bot)
    await page.waitForFunction(() => {
      const successState = document.getElementById('success-state');
      const toastAlert = document.querySelector('#toast-container [role="alert"]');
      const successVisible = successState && !successState.classList.contains('hidden');
      const toastVisible = toastAlert && (toastAlert as HTMLElement).offsetParent !== null;
      return successVisible || toastVisible;
    }, { timeout: 10000 });
  });

  test('phone field validation - various formats', async ({ page }) => {
    await page.locator('input[name="name"]').fill('Phone Tester');
    await page.locator('#contact-form input[name="email"]').fill('phone@test.com');
    await page.locator('select[name="subject"]').selectOption('support');
    await page.locator('textarea[name="message"]').fill('Testing phone number formats.');

    const phoneInput = page.locator('input[name="phone"]');
    const validFormats = [
      '+1 555-123-4567',
      '(555) 123-4567',
      '555.123.4567',
      '+1 (555) 123-4567'
    ];

    for (const format of validFormats) {
      await phoneInput.fill(format);
      await expect(phoneInput).toHaveValue(format);
    }
  });

  test('subject dropdown - all options selectable', async ({ page }) => {
    const subjectSelect = page.locator('select[name="subject"]');

    const options = await subjectSelect.locator('option').all();
    expect(options.length).toBeGreaterThan(1);

    // Try selecting each option
    for (let i = 1; i < options.length; i++) {
      const value = await options[i].getAttribute('value');
      if (value) {
        await subjectSelect.selectOption(value);
        expect(await subjectSelect.inputValue()).toBe(value);
      }
    }
  });

  test('form field focus states and keyboard navigation', async ({ page }) => {
    // Click on name field first to establish focus context, then verify tab order
    const nameInput = page.locator('input[name="name"]');
    await nameInput.click();
    await expect(nameInput).toBeFocused();

    await page.keyboard.press('Tab');
    await expect(page.locator('#contact-form input[name="email"]')).toBeFocused();

    await page.keyboard.press('Tab');
    await expect(page.locator('input[name="phone"]')).toBeFocused();

    await page.keyboard.press('Tab');
    await expect(page.locator('select[name="subject"]')).toBeFocused();

    // Tab through budget radio buttons (optional field between subject and message)
    // There may be multiple radio buttons - tab until message textarea is focused
    for (let i = 0; i < 10; i++) {
      await page.keyboard.press('Tab');
      const isMessageFocused = await page.locator('textarea[name="message"]').evaluate(
        el => document.activeElement === el
      );
      if (isMessageFocused) break;
    }
    await expect(page.locator('textarea[name="message"]')).toBeFocused();
  });

  test('form persistence during session', async ({ page }) => {
    // Fill form partially
    await page.locator('input[name="name"]').fill('Partial Fill');
    await page.locator('#contact-form input[name="email"]').fill('partial@test.com');

    // Navigate away
    await page.goto('/services');
    await expect(page).toHaveURL('/services');

    // Navigate back
    await page.goto('/contact');

    // Form should be empty (no persistence - expected behavior)
    await expect(page.locator('input[name="name"]')).toHaveValue('');
  });

  test('multiple rapid submissions prevented', async ({ page }) => {
    // Fill form
    await page.locator('input[name="name"]').fill('Rapid Submitter');
    await page.locator('#contact-form input[name="email"]').fill('rapid@test.com');
    await page.locator('select[name="subject"]').selectOption('web-development');
    await page.locator('textarea[name="message"]').fill('Testing rapid submission prevention.');

    const submitButton = page.locator('#contact-form button[type="submit"]');

    // Click submit
    await submitButton.click();

    // Button should be disabled immediately
    await expect(submitButton).toBeDisabled();

    // Try clicking again (should not work)
    await submitButton.click({ force: true });

    // Still disabled
    await expect(submitButton).toBeDisabled();
  });
});

test.describe('Contact Form - Accessibility', () => {
  test('form labels associated with inputs', async ({ page }) => {
    await page.goto('/contact');

    const fields = [
      { id: 'name', label: 'Full Name' },
      { id: 'email', label: 'Email Address' },
      { id: 'phone', label: 'Phone' },
      { id: 'subject', label: 'Service Needed' },
      { id: 'message', label: 'Message' }
    ];

    for (const field of fields) {
      const label = page.locator(`label[for="${field.id}"]`);
      await expect(label).toBeVisible();

      const labelText = await label.textContent();
      expect(labelText).toContain(field.label);
    }
  });

  test('error messages are announced', async ({ page }) => {
    await page.goto('/contact');

    // Submit empty form
    await page.locator('#contact-form button[type="submit"]').click();

    // Check that error messages exist and are associated
    const errorMessages = page.locator('[data-error]');
    expect(await errorMessages.count()).toBeGreaterThan(0);
  });

  test('submit button has proper state', async ({ page }) => {
    await page.goto('/contact');

    const submitButton = page.locator('#contact-form button[type="submit"]');

    // Initially enabled
    await expect(submitButton).toBeEnabled();

    // Fill and submit
    await page.locator('input[name="name"]').fill('Test User');
    await page.locator('#contact-form input[name="email"]').fill('test@example.com');
    await page.locator('select[name="subject"]').selectOption('consulting');
    await page.locator('textarea[name="message"]').fill('Test message content.');

    await submitButton.click();

    // Disabled during submission
    await expect(submitButton).toBeDisabled();
  });
});

test.describe('Contact Form - Mobile Experience', () => {
  test.use({ viewport: { width: 375, height: 667 } });

  test('mobile form is fully usable', async ({ page }) => {
    await page.goto('/contact');

    // All fields should be visible and clickable on mobile
    await page.locator('input[name="name"]').click();
    await page.locator('input[name="name"]').fill('Mobile User');

    await page.locator('#contact-form input[name="email"]').click();
    await page.locator('#contact-form input[name="email"]').fill('mobile@test.com');

    await page.locator('textarea[name="message"]').click();
    await page.locator('textarea[name="message"]').fill('Testing mobile form interaction.');

    // Submit button should be fully visible and clickable
    const submitButton = page.locator('#contact-form button[type="submit"]');
    await submitButton.scrollIntoViewIfNeeded();
    await expect(submitButton).toBeVisible();
  });

  test('mobile keyboard types are appropriate', async ({ page }) => {
    await page.goto('/contact');

    // Email field should trigger email keyboard
    const emailInput = page.locator('#contact-form input[name="email"]');
    expect(await emailInput.getAttribute('type')).toBe('email');

    // Phone field should trigger tel keyboard
    const phoneInput = page.locator('input[name="phone"]');
    expect(await phoneInput.getAttribute('type')).toBe('tel');
  });
});
