/**
 * Critical User Flows E2E Tests
 * FE-TEST-012: Test login, upload, playlist creation end-to-end
 * 
 * This test suite covers the most critical user journeys:
 * 1. User login flow
 * 2. Track upload flow
 * 3. Playlist creation flow
 * 
 * These tests ensure that the core functionality works together seamlessly.
 */

 
import { test, expect } from '@playwright/test';
import {
  TEST_CONFIG,
  TEST_USERS,
  forceSubmitForm,
  fillField,
  waitForToast,
  setupErrorCapture,
  openModal,
} from './utils/test-helpers';
import { createMockMP3Buffer } from './fixtures/file-helpers';

test.describe('Critical User Flows - End-to-End', () => {
  // Reset storage state for these tests to ensure we start unauthenticated
  test.use({ storageState: { cookies: [], origins: [] } });

  let consoleErrors: string[] = [];
  let networkErrors: Array<{ url: string; status: number; method: string }> = [];

  test.beforeEach(async ({ page }) => {
    const errorCapture = setupErrorCapture(page);
    consoleErrors = errorCapture.consoleErrors;
    networkErrors = errorCapture.networkErrors;
  });

  /**
   * CRITICAL FLOW 1: Complete user journey from login to playlist creation
   * 
   * This test simulates a real user scenario:
   * 1. User logs in
   * 2. User uploads a track
   * 3. User creates a playlist
   * 4. User adds the uploaded track to the playlist
   */
  test('Complete user journey: Login → Upload → Create Playlist → Add Track', async ({ page }) => {
    test.setTimeout(180000); // 3 minutes for complete flow

    console.log('🚀 [CRITICAL FLOW] Starting complete user journey test...');

    // ========== STEP 1: LOGIN ==========
    console.log('📝 [CRITICAL FLOW] Step 1: User login...');
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`);
    await page.waitForLoadState('domcontentloaded');

    // Wait for form to be ready
    await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => { });
    await page.waitForTimeout(500);

    // Fill login form
    await fillField(
      page,
      'input[type="email"], input[name="email"]',
      TEST_USERS.default.email
    );
    await fillField(
      page,
      'input[type="password"], input[name="password"]',
      TEST_USERS.default.password
    );

    // Submit form and wait for navigation
    const navigationPromise = page.waitForURL(
      (url) => url.pathname === '/dashboard' || url.pathname === '/',
      { timeout: 15000 }
    );

    await forceSubmitForm(page, 'form');
    await navigationPromise;

    // Verify user is authenticated
    await expect(page).toHaveURL(/\/(dashboard|$)/);
    await expect(page.locator('nav[role="navigation"], aside[role="navigation"]')).toBeVisible({
      timeout: 10000,
    });

    // Wait for auth state to be persisted
    await page.waitForTimeout(1000);

    const isAuthenticated = await page.evaluate(() => {
      try {
        const authStorage = localStorage.getItem('auth-storage');
        if (authStorage) {
          const parsed = JSON.parse(authStorage);
          return parsed.state?.isAuthenticated === true;
        }
      } catch {
        return false;
      }
      return false;
    });
    expect(isAuthenticated).toBe(true);
    console.log('✅ [CRITICAL FLOW] Step 1: Login successful');

    // ========== STEP 2: UPLOAD TRACK ==========
    console.log('📤 [CRITICAL FLOW] Step 2: Uploading track...');

    // Navigate to library
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/library`);
    await page.waitForLoadState('domcontentloaded');
    await page.waitForLoadState('networkidle', { timeout: 15000 }).catch(() => {
      console.warn('⚠️ [CRITICAL FLOW] Timeout on networkidle, continuing...');
    });

    // Open upload modal
    await openModal(page, /upload/i);

    // Select and upload file
    const fileInput = page.locator('input[type="file"][accept*="audio"]').first();
    await expect(fileInput).toBeAttached({ timeout: 5000 });

    const validMp3Buffer = createMockMP3Buffer();
    await fileInput.setInputFiles({
      name: 'critical-flow-test.mp3',
      mimeType: 'audio/mpeg',
      buffer: validMp3Buffer,
    });

    console.log('✅ [CRITICAL FLOW] File selected');
    await page.waitForTimeout(1000);

    // Check for rejection errors
    const errorMessage = page.locator('[data-testid="upload-error"], [role="alert"]:has-text("Format")').first();
    const hasRejectionError = await errorMessage.isVisible().catch(() => false);

    if (hasRejectionError) {
      const errorText = await errorMessage.textContent();
      throw new Error(`File was rejected: ${errorText}`);
    }

    // Fill metadata
    await fillField(page, 'input[id="title"], input[name="title"]', 'Critical Flow Test Track');
    await fillField(page, 'input[id="artist"], input[name="artist"]', 'Test Artist');

    // Submit upload
    const uploadButton = page.locator('button:has-text("Upload"), button:has-text("Envoyer"), button[type="submit"]').first();
    await expect(uploadButton).toBeVisible({ timeout: 5000 });
    await uploadButton.click();

    // Wait for upload success
    await waitForToast(page, /success|succès|uploaded|téléchargé/i, { timeout: 60000 });
    console.log('✅ [CRITICAL FLOW] Step 2: Track uploaded successfully');

    // Close modal if still open
    const closeButton = page.locator('button[aria-label*="close"], button[aria-label*="fermer"]').first();
    if (await closeButton.isVisible().catch(() => false)) {
      await closeButton.click();
      await page.waitForTimeout(500);
    }

    // ========== STEP 3: CREATE PLAYLIST ==========
    console.log('📋 [CRITICAL FLOW] Step 3: Creating playlist...');

    // Navigate to playlists
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/playlists`, { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(500);
    await page.waitForURL(/\/playlists/, { timeout: 15000 }).catch(() => { });

    // Wait for page to load
    try {
      await Promise.race([
        page.locator('h1:has-text("Playlist"), h1:has-text("Playlists")').first().waitFor({ state: 'visible', timeout: 10000 }),
        page.locator('[data-testid="playlists-page"]').first().waitFor({ state: 'visible', timeout: 10000 }),
      ]);
    } catch {
      console.warn('⚠️ [CRITICAL FLOW] Page load check timeout, continuing...');
    }

    // Open create playlist modal
    await openModal(page, /create|créer|nouvelle/i);

    // Fill playlist form
    await fillField(
      page,
      'input[id="title"], input[name="title"]',
      'Critical Flow Test Playlist'
    );
    await fillField(
      page,
      'textarea[id="description"], textarea[name="description"]',
      'Playlist created during critical flow test'
    );

    // Submit playlist creation
    const createButton = page.locator('button:has-text("Créer"), button:has-text("Create"), button[type="submit"]').first();
    await expect(createButton).toBeVisible({ timeout: 5000 });
    await createButton.click();

    // Wait for success
    await waitForToast(page, /success|succès|created|créé/i, { timeout: 15000 });
    console.log('✅ [CRITICAL FLOW] Step 3: Playlist created successfully');

    // ========== STEP 4: VERIFY PLAYLIST EXISTS ==========
    console.log('🔍 [CRITICAL FLOW] Step 4: Verifying playlist exists...');

    // Wait for modal to close
    await page.waitForTimeout(1000);

    // Check that playlist appears in the list
    const playlistTitle = page.locator('text="Critical Flow Test Playlist"').first();
    await expect(playlistTitle).toBeVisible({ timeout: 10000 });
    console.log('✅ [CRITICAL FLOW] Step 4: Playlist verified in list');

    // ========== VERIFY NO ERRORS ==========
    console.log('🔍 [CRITICAL FLOW] Verifying no errors occurred...');

    // Check for console errors
    if (consoleErrors.length > 0) {
      console.warn('⚠️ [CRITICAL FLOW] Console errors detected:', consoleErrors);
    }

    // Check for network errors (excluding expected ones)
    const criticalNetworkErrors = networkErrors.filter(
      (error) => error.status >= 500 || (error.status >= 400 && !error.url.includes('favicon'))
    );

    if (criticalNetworkErrors.length > 0) {
      console.warn('⚠️ [CRITICAL FLOW] Network errors detected:', criticalNetworkErrors);
    }

    console.log('✅ [CRITICAL FLOW] Complete user journey test passed!');
  });

  /**
   * CRITICAL FLOW 2: Login and immediate playlist creation
   * 
   * Tests the scenario where a user logs in and immediately creates a playlist
   * without uploading anything first.
   */
  test('Login → Create Playlist (no upload)', async ({ page }) => {
    test.setTimeout(90000); // 90 seconds

    console.log('🚀 [CRITICAL FLOW] Starting login → playlist creation test...');

    // Login
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`);
    await page.waitForLoadState('domcontentloaded');
    await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => { });

    await fillField(
      page,
      'input[type="email"], input[name="email"]',
      TEST_USERS.default.email
    );
    await fillField(
      page,
      'input[type="password"], input[name="password"]',
      TEST_USERS.default.password
    );

    const navigationPromise = page.waitForURL(
      (url) => url.pathname === '/dashboard' || url.pathname === '/',
      { timeout: 15000 }
    );

    await forceSubmitForm(page, 'form');
    await navigationPromise;

    await expect(page).toHaveURL(/\/(dashboard|$)/);
    console.log('✅ [CRITICAL FLOW] Login successful');

    // Navigate to playlists
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/playlists`, { waitUntil: 'domcontentloaded' });
    await page.waitForTimeout(1000);

    // Create playlist
    await openModal(page, /create|créer|nouvelle/i);

    await fillField(
      page,
      'input[id="title"], input[name="title"]',
      'Quick Test Playlist'
    );

    const createButton = page.locator('button:has-text("Créer"), button:has-text("Create"), button[type="submit"]').first();
    await expect(createButton).toBeVisible({ timeout: 5000 });
    await createButton.click();

    await waitForToast(page, /success|succès|created|créé/i, { timeout: 15000 });
    console.log('✅ [CRITICAL FLOW] Playlist created successfully');
  });

  /**
   * CRITICAL FLOW 3: Login and upload only
   * 
   * Tests the scenario where a user logs in and uploads a track
   * without creating a playlist.
   */
  test('Login → Upload Track (no playlist)', async ({ page }) => {
    test.setTimeout(120000); // 2 minutes

    console.log('🚀 [CRITICAL FLOW] Starting login → upload test...');

    // Login
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/login`);
    await page.waitForLoadState('domcontentloaded');
    await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => { });

    await fillField(
      page,
      'input[type="email"], input[name="email"]',
      TEST_USERS.default.email
    );
    await fillField(
      page,
      'input[type="password"], input[name="password"]',
      TEST_USERS.default.password
    );

    const navigationPromise = page.waitForURL(
      (url) => url.pathname === '/dashboard' || url.pathname === '/',
      { timeout: 15000 }
    );

    await forceSubmitForm(page, 'form');
    await navigationPromise;

    await expect(page).toHaveURL(/\/(dashboard|$)/);
    console.log('✅ [CRITICAL FLOW] Login successful');

    // Navigate to library and upload
    await page.goto(`${TEST_CONFIG.FRONTEND_URL}/library`);
    await page.waitForLoadState('domcontentloaded');
    await page.waitForLoadState('networkidle', { timeout: 15000 }).catch(() => { });

    await openModal(page, /upload/i);

    const fileInput = page.locator('input[type="file"][accept*="audio"]').first();
    await expect(fileInput).toBeAttached({ timeout: 5000 });

    const validMp3Buffer = createMockMP3Buffer();
    await fileInput.setInputFiles({
      name: 'upload-only-test.mp3',
      mimeType: 'audio/mpeg',
      buffer: validMp3Buffer,
    });

    await page.waitForTimeout(1000);

    await fillField(page, 'input[id="title"], input[name="title"]', 'Upload Only Test');
    await fillField(page, 'input[id="artist"], input[name="artist"]', 'Test Artist');

    const uploadButton = page.locator('button:has-text("Upload"), button:has-text("Envoyer"), button[type="submit"]').first();
    await expect(uploadButton).toBeVisible({ timeout: 5000 });
    await uploadButton.click();

    await waitForToast(page, /success|succès|uploaded|téléchargé/i, { timeout: 60000 });
    console.log('✅ [CRITICAL FLOW] Upload successful');
  });
});

