import { test, expect } from '@playwright/test';
import { acceptCookieConsent, waitForNavigation } from '../helpers/utils';
import path from 'path';

/**
 * Complete User Registration and Onboarding Flow Test
 *
 * This test suite covers the entire journey from registration to onboarding completion:
 * 1. User Registration (3-step process: basic info, subscription, payment)
 * 2. Onboarding Wizard (multiple steps based on business type and tier)
 */

test.describe('Complete Registration and Onboarding Flow', () => {
  // Generate unique test user for each test run
  const generateTestUser = () => ({
    fullName: `Test User ${Date.now()}`,
    email: `test.user.${Date.now()}@bakery-test.com`,
    password: 'SecurePass123!@#',
    plan: 'starter' // or 'professional', 'enterprise'
  });

  test('should complete full registration and onboarding flow for starter plan', async ({ page }) => {
    const testUser = generateTestUser();

    // ============================================
    // PHASE 1: REGISTRATION
    // ============================================

    await test.step('Navigate to registration page', async () => {
      await page.goto('/register');
      await acceptCookieConsent(page);

      // Verify we're on the registration page
      await expect(page.getByRole('heading', { name: /crear cuenta|create account/i })).toBeVisible();
    });

    await test.step('Fill basic information (Step 1/3)', async () => {
      // Fill in user details
      await page.getByLabel(/nombre completo|full name/i).fill(testUser.fullName);
      await page.getByLabel(/correo|email/i).fill(testUser.email);

      // Fill password
      await page.getByLabel(/^contraseña|^password/i).first().fill(testUser.password);

      // Fill confirm password
      await page.getByLabel(/confirmar contraseña|confirm password/i).fill(testUser.password);

      // Wait for password match indicator
      await expect(page.getByText(/las contraseñas coinciden|passwords match/i)).toBeVisible({ timeout: 5000 });

      // Accept terms and conditions
      await page.getByRole('checkbox', { name: /acepto los términos|accept terms/i }).check();

      // Optional consents
      await page.getByRole('checkbox', { name: /marketing|promociones/i }).check();
      await page.getByRole('checkbox', { name: /analytics|analíticas/i }).check();

      // Proceed to next step
      await page.getByRole('button', { name: /siguiente|next/i }).click();
    });

    await test.step('Select subscription plan (Step 2/3)', async () => {
      // Wait for subscription page
      await expect(page.getByRole('heading', { name: /selecciona tu plan|select.*plan/i })).toBeVisible({ timeout: 10000 });

      // Select starter plan (default is usually selected)
      const starterPlanButton = page.getByRole('button', { name: /starter|básico/i }).first();
      if (await starterPlanButton.isVisible().catch(() => false)) {
        await starterPlanButton.click();
      }

      // Proceed to payment
      await page.getByRole('button', { name: /siguiente|next/i }).click();
    });

    await test.step('Complete payment information (Step 3/3)', async () => {
      // Wait for payment page
      await expect(page.getByRole('heading', { name: /información de pago|payment info/i })).toBeVisible({ timeout: 10000 });

      // Check if bypass payment toggle exists (for testing environments)
      const bypassToggle = page.getByRole('checkbox', { name: /bypass|omitir|skip.*payment/i });
      const hasBypassOption = await bypassToggle.isVisible({ timeout: 2000 }).catch(() => false);

      if (hasBypassOption) {
        // Enable bypass for test environment
        await bypassToggle.check();
        await page.getByRole('button', { name: /completar registro|complete registration/i }).click();
      } else {
        // Fill Stripe test card details
        const cardFrame = page.frameLocator('iframe[name*="__privateStripeFrame"]').first();

        // Wait for Stripe iframe to load
        await page.waitForTimeout(2000);

        // Fill card number (Stripe test card)
        await cardFrame.getByPlaceholder(/card number|número.*tarjeta/i).fill('4242424242424242');

        // Fill expiry date
        await cardFrame.getByPlaceholder(/mm.*yy|expir/i).fill('1234');

        // Fill CVC
        await cardFrame.getByPlaceholder(/cvc|cvv/i).fill('123');

        // Fill postal code if visible
        const postalCode = cardFrame.getByPlaceholder(/postal|zip/i);
        if (await postalCode.isVisible().catch(() => false)) {
          await postalCode.fill('12345');
        }

        // Submit payment
        await page.getByRole('button', { name: /completar registro|complete registration|submit/i }).click();
      }

      // Wait for redirect to onboarding
      await page.waitForURL(/\/app\/onboarding/, { timeout: 15000 });
    });

    // ============================================
    // PHASE 2: ONBOARDING WIZARD
    // ============================================

    await test.step('Complete onboarding wizard', async () => {
      // Wait for onboarding page to load
      await expect(page.locator('body')).toContainText(/onboarding|configuración|bienvenido/i, { timeout: 10000 });

      // The onboarding has multiple steps, we'll navigate through them
      let stepCount = 0;
      const maxSteps = 15; // Maximum expected steps

      while (stepCount < maxSteps) {
        // Wait a bit for the step to render
        await page.waitForTimeout(1000);

        // Look for various button types that indicate progression
        const nextButton = page.getByRole('button', { name: /next|siguiente|continuar/i });
        const skipButton = page.getByRole('button', { name: /skip|omitir|saltar/i });
        const finishButton = page.getByRole('button', { name: /finish|finalizar|completar/i });
        const goToDashboardButton = page.getByRole('button', { name: /ir al panel|go to dashboard/i });

        // Check what step we're on and fill accordingly
        const bodyText = await page.locator('body').textContent();

        // Step: Bakery Type Selection
        if (bodyText?.match(/tipo.*panadería|bakery.*type|selecciona.*tipo/i)) {
          console.log('📍 Step: Bakery Type Selection');
          const retailOption = page.getByRole('button', { name: /retail|minorista|venta/i }).first();
          if (await retailOption.isVisible({ timeout: 2000 }).catch(() => false)) {
            await retailOption.click();
          }
        }

        // Step: Tenant Setup (Register Bakery)
        else if (bodyText?.match(/registra.*panadería|register.*bakery|datos.*negocio/i)) {
          console.log('📍 Step: Tenant Setup');

          // Fill bakery name if not filled
          const nameInput = page.getByLabel(/nombre.*panadería|bakery.*name|nombre.*negocio/i);
          if (await nameInput.isVisible({ timeout: 2000 }).catch(() => false)) {
            const currentValue = await nameInput.inputValue();
            if (!currentValue) {
              await nameInput.fill(`Test Bakery ${Date.now()}`);
            }
          }

          // Fill address
          const addressInput = page.getByLabel(/dirección|address/i);
          if (await addressInput.isVisible({ timeout: 2000 }).catch(() => false)) {
            const currentValue = await addressInput.inputValue();
            if (!currentValue) {
              await addressInput.fill('Calle Test 123');
            }
          }

          // Fill postal code
          const postalInput = page.getByLabel(/código postal|postal.*code|zip/i);
          if (await postalInput.isVisible({ timeout: 2000 }).catch(() => false)) {
            const currentValue = await postalInput.inputValue();
            if (!currentValue) {
              await postalInput.fill('28001');
            }
          }

          // Fill city
          const cityInput = page.getByLabel(/ciudad|city/i);
          if (await cityInput.isVisible({ timeout: 2000 }).catch(() => false)) {
            const currentValue = await cityInput.inputValue();
            if (!currentValue) {
              await cityInput.fill('Madrid');
            }
          }

          // Fill phone
          const phoneInput = page.getByLabel(/teléfono|phone/i);
          if (await phoneInput.isVisible({ timeout: 2000 }).catch(() => false)) {
            const currentValue = await phoneInput.inputValue();
            if (!currentValue) {
              await phoneInput.fill('666555444');
            }
          }
        }

        // Step: Upload Sales Data
        else if (bodyText?.match(/subir.*datos|upload.*sales|archivo.*ventas/i)) {
          console.log('📍 Step: Upload Sales Data');

          // Try to skip this step if possible
          if (await skipButton.isVisible({ timeout: 2000 }).catch(() => false)) {
            await skipButton.click();
            stepCount++;
            continue;
          }

          // Otherwise, we'd need to upload a test CSV file
          // For now, we'll just proceed if there's a next button
        }

        // Step: Inventory Review
        else if (bodyText?.match(/revisar.*inventario|inventory.*review|productos/i)) {
          console.log('📍 Step: Inventory Review');
          // Usually can skip or proceed with empty
        }

        // Step: Initial Stock Entry
        else if (bodyText?.match(/stock.*inicial|initial.*stock|cantidad/i)) {
          console.log('📍 Step: Initial Stock Entry');

          // Look for "Set all to 0" or skip button
          const setAllZeroButton = page.getByRole('button', { name: /establecer.*0|set.*all.*0/i });
          if (await setAllZeroButton.isVisible({ timeout: 2000 }).catch(() => false)) {
            await setAllZeroButton.click();
          }
        }

        // Step: Suppliers Setup
        else if (bodyText?.match(/proveedores|suppliers/i)) {
          console.log('📍 Step: Suppliers Setup');
          // Can skip for now
        }

        // Step: Recipes Setup
        else if (bodyText?.match(/recetas|recipes/i)) {
          console.log('📍 Step: Recipes Setup');
          // Can skip for now
        }

        // Step: ML Training
        else if (bodyText?.match(/entrenamiento|training|modelo.*ia|ai.*model/i)) {
          console.log('📍 Step: ML Training');

          // Look for skip to dashboard button
          if (await goToDashboardButton.isVisible({ timeout: 5000 }).catch(() => false)) {
            await goToDashboardButton.click();
            // Should redirect to dashboard
            await page.waitForURL(/\/app\/(dashboard|operations)/, { timeout: 10000 });
            break;
          }
        }

        // Step: Completion
        else if (bodyText?.match(/completado|completed|felicidades|congratulations/i)) {
          console.log('📍 Step: Completion');

          if (await goToDashboardButton.isVisible({ timeout: 2000 }).catch(() => false)) {
            await goToDashboardButton.click();
            await page.waitForURL(/\/app\/(dashboard|operations)/, { timeout: 10000 });
            break;
          } else if (await finishButton.isVisible({ timeout: 2000 }).catch(() => false)) {
            await finishButton.click();
            await page.waitForURL(/\/app\/(dashboard|operations)/, { timeout: 10000 });
            break;
          }
        }

        // Try to proceed to next step
        if (await nextButton.isVisible({ timeout: 2000 }).catch(() => false)) {
          await nextButton.click();
          stepCount++;
        } else if (await skipButton.isVisible({ timeout: 2000 }).catch(() => false)) {
          await skipButton.click();
          stepCount++;
        } else if (await finishButton.isVisible({ timeout: 2000 }).catch(() => false)) {
          await finishButton.click();
          // Should redirect to dashboard
          await page.waitForURL(/\/app\/(dashboard|operations)/, { timeout: 10000 });
          break;
        } else {
          // No more navigation buttons found
          console.log('ℹ️  No more navigation buttons found, checking if we reached dashboard');

          // Check if we're already at dashboard
          if (page.url().includes('/app/dashboard') || page.url().includes('/app/operations')) {
            break;
          }

          // If we can't find any buttons and we're still on onboarding, something might be wrong
          if (page.url().includes('/onboarding')) {
            console.warn('⚠️  Still on onboarding page but no navigation buttons found');
            // Take a screenshot for debugging
            await page.screenshot({ path: `test-results/onboarding-stuck-step-${stepCount}.png` });
          }

          break;
        }

        // Safety check: wait a bit between steps
        await page.waitForTimeout(500);
      }

      console.log(`✅ Completed ${stepCount} onboarding steps`);
    });

    await test.step('Verify successful onboarding completion', async () => {
      // Should be redirected to dashboard
      await expect(page).toHaveURL(/\/app\/(dashboard|operations)/, { timeout: 10000 });

      // Verify dashboard elements are visible
      await expect(page.locator('body')).toContainText(/dashboard|panel|operaciones|operations/i, { timeout: 5000 });

      // Take final screenshot
      await page.screenshot({ path: 'test-results/onboarding-completed.png', fullPage: true });
    });
  });

  test('should complete onboarding with manual data entry (no file upload)', async ({ page }) => {
    const testUser = generateTestUser();

    // Quick registration (simplified for this test)
    await page.goto('/register');
    await acceptCookieConsent(page);

    // Fill registration form quickly
    await page.getByLabel(/nombre completo|full name/i).fill(testUser.fullName);
    await page.getByLabel(/correo|email/i).fill(testUser.email);
    await page.getByLabel(/^contraseña|^password/i).first().fill(testUser.password);
    await page.getByLabel(/confirmar contraseña|confirm password/i).fill(testUser.password);
    await page.getByRole('checkbox', { name: /acepto los términos|accept terms/i }).check();

    // Proceed through registration
    await page.getByRole('button', { name: /siguiente|next/i }).click();

    // Select plan (if subscription step appears)
    await page.waitForTimeout(2000);
    const nextButtonAfterPlan = page.getByRole('button', { name: /siguiente|next/i });
    if (await nextButtonAfterPlan.isVisible({ timeout: 3000 }).catch(() => false)) {
      await nextButtonAfterPlan.click();
    }

    // Handle payment page
    const bypassToggle = page.getByRole('checkbox', { name: /bypass|omitir|skip.*payment/i });
    if (await bypassToggle.isVisible({ timeout: 3000 }).catch(() => false)) {
      await bypassToggle.check();
      await page.getByRole('button', { name: /completar registro|complete registration/i }).click();
    }

    // Wait for onboarding
    await page.waitForURL(/\/app\/onboarding/, { timeout: 15000 });

    // Test specific scenario: Skip file upload and add products manually
    await test.step('Navigate to manual product entry', async () => {
      // Look for file upload step and skip it
      let attempts = 0;
      while (attempts < 10) {
        const bodyText = await page.locator('body').textContent();

        if (bodyText?.match(/subir.*archivo|upload.*file|sales.*data/i)) {
          // Found upload step, try to skip
          const skipButton = page.getByRole('button', { name: /skip|omitir|saltar|manual/i });
          if (await skipButton.isVisible({ timeout: 2000 }).catch(() => false)) {
            await skipButton.click();
            break;
          }
        }

        // Try next button if available
        const nextButton = page.getByRole('button', { name: /next|siguiente/i });
        if (await nextButton.isVisible({ timeout: 2000 }).catch(() => false)) {
          await nextButton.click();
          attempts++;
        } else {
          break;
        }

        await page.waitForTimeout(500);
      }
    });
  });

  test('should handle validation errors gracefully', async ({ page }) => {
    await page.goto('/register');
    await acceptCookieConsent(page);

    await test.step('Test password validation', async () => {
      // Try weak password
      await page.getByLabel(/nombre completo|full name/i).fill('Test User');
      await page.getByLabel(/correo|email/i).fill('test@example.com');
      await page.getByLabel(/^contraseña|^password/i).first().fill('weak');

      // Next button should be disabled or show error
      const nextButton = page.getByRole('button', { name: /siguiente|next/i });

      // Either button is disabled or we see password criteria errors
      const isDisabled = await nextButton.isDisabled();
      const hasPasswordError = await page.getByText(/mínimo|caracteres|mayúscula|minúscula/i).isVisible().catch(() => false);

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

    await test.step('Test email validation', async () => {
      // Try invalid email
      await page.getByLabel(/correo|email/i).fill('invalid-email');
      await page.getByLabel(/^contraseña|^password/i).first().click(); // Blur the email field

      // Should show email error
      await expect(page.getByText(/email.*válido|valid.*email/i)).toBeVisible({ timeout: 3000 });
    });

    await test.step('Test terms acceptance requirement', async () => {
      // Fill valid data but don't accept terms
      await page.getByLabel(/nombre completo|full name/i).fill('Test User');
      await page.getByLabel(/correo|email/i).fill('test@example.com');
      await page.getByLabel(/^contraseña|^password/i).first().fill('SecurePass123!');
      await page.getByLabel(/confirmar contraseña|confirm password/i).fill('SecurePass123!');

      // Try to proceed without accepting terms
      const nextButton = page.getByRole('button', { name: /siguiente|next/i });

      // Button should be disabled
      await expect(nextButton).toBeDisabled();
    });
  });
});
