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

/**
 * Diagnostic Test - Full Stack Compatibility Check
 * 
 * Ce test vérifie l'intégration Frontend-Backend après le refactoring de l'authentification.
 * Il capture toutes les erreurs réseau, console, CORS et vérifie le stockage des tokens.
 */

// Configuration
const FRONTEND_URL = process.env.PLAYWRIGHT_BASE_URL || 'http://localhost:3000';
const TEST_EMAIL = process.env.TEST_EMAIL || 'user@example.com';
const TEST_PASSWORD = process.env.TEST_PASSWORD || 'password123';

// Collecteurs d'erreurs
interface DiagnosticReport {
  networkErrors: Array<{
    url: string;
    status: number;
    method: string;
    error: string;
  }>;
  consoleErrors: Array<{
    type: string;
    message: string;
    stack?: string;
  }>;
  corsErrors: Array<{
    url: string;
    reason: string;
  }>;
  localStorage: Record<string, string>;
  navigationSuccess: boolean;
  finalUrl: string;
  formVisible: boolean;
  errorMessage?: string;
}

test.describe('Full Stack Compatibility Diagnostic', () => {
  let report: DiagnosticReport;

  test.beforeEach(() => {
    report = {
      networkErrors: [],
      consoleErrors: [],
      corsErrors: [],
      localStorage: {},
      navigationSuccess: false,
      finalUrl: '',
      formVisible: false,
    };
  });

  test('Login Flow - Complete Diagnostic', async ({ page }) => {
    // Setup: Écouter les erreurs console AVANT toute navigation
    const consoleMessages: Array<{ type: string; text: string }> = [];
    page.on('console', (msg) => {
      const type = msg.type();
      const text = msg.text();
      consoleMessages.push({ type, text });

      if (type === 'error' || type === 'warning') {
        report.consoleErrors.push({
          type,
          message: text,
          stack: msg.location()?.url,
        });
        console.log(`🔴 [CONSOLE ${type.toUpperCase()}] ${text}`);
      }
    });

    // Setup: Écouter les erreurs de page (uncaught exceptions)
    page.on('pageerror', (error) => {
      report.consoleErrors.push({
        type: 'pageerror',
        message: error.message,
        stack: error.stack,
      });
      console.log(`🔴 [PAGE ERROR] ${error.message}`);
    });

    // Setup: Écouter les requêtes réseau échouées
    page.on('response', (response) => {
      const status = response.status();
      const url = response.url();

      // Capturer les erreurs 4xx et 5xx
      if (status >= 400) {
        report.networkErrors.push({
          url,
          status,
          method: response.request().method(),
          error: `HTTP ${status}`,
        });

        // Détecter les erreurs CORS potentielles
        if (status === 0 || url.includes('localhost:8080')) {
          const headers = response.headers();
          if (!headers['access-control-allow-origin']) {
            report.corsErrors.push({
              url,
              reason: 'Missing CORS headers',
            });
          }
        }
      }
    });

    // Setup: Écouter les requêtes échouées (network errors)
    page.on('requestfailed', (request) => {
      const failure = request.failure();
      if (failure) {
        report.networkErrors.push({
          url: request.url(),
          status: 0,
          method: request.method(),
          error: failure.errorText || 'Network error',
        });

        // Détecter les erreurs CORS
        if (failure.errorText?.includes('CORS') || failure.errorText?.includes('Access-Control')) {
          report.corsErrors.push({
            url: request.url(),
            reason: failure.errorText,
          });
        }
      }
    });

    // Étape 1: Aller sur la page de login
    console.log('🔍 [DIAGNOSTIC] Navigation vers /login...');
    try {
      await page.goto(`${FRONTEND_URL}/login`, { waitUntil: 'domcontentloaded', timeout: 30000 });
    } catch (error) {
      console.error('❌ [DIAGNOSTIC] Erreur lors de la navigation:', error);
      report.finalUrl = page.url();
      return;
    }

    // Attendre que la page soit chargée
    await page.waitForLoadState('networkidle', { timeout: 10000 }).catch(() => {
      console.warn('⚠️ [DIAGNOSTIC] Timeout sur networkidle, continuation...');
    });

    // Prendre une capture d'écran pour debug
    await page.screenshot({ path: 'e2e/diagnostic-login-page.png', fullPage: true });

    // Attendre que le formulaire soit chargé (plusieurs stratégies)
    try {
      // Essayer d'attendre un élément de formulaire
      await page.waitForSelector('form, input[type="email"], input[type="password"]', { timeout: 10000 });
    } catch {
      console.warn('⚠️ [DIAGNOSTIC] Timeout en attendant le formulaire');
    }

    // Attendre un peu pour que React hydrate
    await page.waitForTimeout(3000);

    // Vérifier que le formulaire est visible avec plusieurs sélecteurs possibles
    const emailInput = page.locator('input[type="email"], input[name="email"], input[placeholder*="email" i]').first();
    const passwordInput = page.locator('input[type="password"], input[name="password"]').first();
    const submitButton = page.locator('button[type="submit"], button:has-text("connecter"), button:has-text("login"), button:has-text("Se connecter")').first();

    // Vérifier aussi avec des sélecteurs plus génériques
    const allInputs = await page.locator('input').count();
    const allButtons = await page.locator('button').count();
    console.log('📄 [DIAGNOSTIC] Nombre d\'inputs sur la page:', allInputs);
    console.log('📄 [DIAGNOSTIC] Nombre de boutons sur la page:', allButtons);

    const emailVisible = await emailInput.isVisible().catch(() => false);
    const passwordVisible = await passwordInput.isVisible().catch(() => false);
    const submitVisible = await submitButton.isVisible().catch(() => false);

    report.formVisible = emailVisible && passwordVisible;

    // Logger le contenu de la page pour debug
    const pageContent = await page.content();
    const hasForm = pageContent.includes('form') || pageContent.includes('email') || pageContent.includes('password');

    console.log('📄 [DIAGNOSTIC] Page title:', await page.title());
    console.log('📄 [DIAGNOSTIC] URL actuelle:', page.url());
    console.log('📄 [DIAGNOSTIC] Email input visible:', emailVisible);
    console.log('📄 [DIAGNOSTIC] Password input visible:', passwordVisible);
    console.log('📄 [DIAGNOSTIC] Submit button visible:', submitVisible);
    console.log('📄 [DIAGNOSTIC] Page contient "form":', hasForm);

    if (!report.formVisible) {
      console.error('❌ [DIAGNOSTIC] Le formulaire de login n\'est pas visible');

      // Logger le HTML pour debug
      const bodyText = await page.locator('body').textContent();
      console.log('📄 [DIAGNOSTIC] Contenu de la page (premiers 500 chars):', bodyText?.substring(0, 500));

      // Logger toutes les erreurs console capturées
      if (consoleMessages.length > 0) {
        console.log('\n🔴 [DIAGNOSTIC] Messages console capturés:');
        consoleMessages.forEach((msg) => {
          console.log(`  [${msg.type}] ${msg.text}`);
        });
      }

      // Vérifier s'il y a des scripts qui ont échoué à charger
      const failedResources = await page.evaluate(() => {
        const resources: Array<{ url: string; error: string }> = [];
        const scripts = document.querySelectorAll('script[src]');
        scripts.forEach((script) => {
          const src = script.getAttribute('src');
           
          if (src && !(script as any).loaded) {
            resources.push({ url: src, error: 'Script not loaded' });
          }
        });
        return resources;
      });

      if (failedResources.length > 0) {
        console.log('🔴 [DIAGNOSTIC] Scripts non chargés:', failedResources);
      }

      // Sauvegarder le rapport même en cas d'échec
      await page.evaluate((report) => {
         
        (window as any).__diagnosticReport = report;
      }, report);

      return;
    }

    console.log('✅ [DIAGNOSTIC] Formulaire de login visible');

    // Étape 2: Remplir le formulaire
    console.log('🔍 [DIAGNOSTIC] Remplissage du formulaire...');
    await emailInput.fill(TEST_EMAIL);
    await passwordInput.fill(TEST_PASSWORD);

    // Vérifier si checkbox "remember me" existe
    const rememberMeCheckbox = page.locator('input[type="checkbox"][id*="remember"]');
    if (await rememberMeCheckbox.count() > 0) {
      await rememberMeCheckbox.check();
    }

    // Étape 3: Cliquer sur le bouton de connexion
    console.log('🔍 [DIAGNOSTIC] Clic sur le bouton de connexion...');

    // Attendre la navigation ou un message d'erreur
    const navigationPromise = page.waitForURL(
      (url) => url.pathname === '/dashboard' || url.pathname === '/',
      { timeout: 10000 }
    ).catch(() => null);

    const errorMessagePromise = page
      .waitForSelector('.bg-red-100, [role="alert"], .text-red-700', { timeout: 5000 })
      .catch(() => null);

    await submitButton.click();

    // Attendre soit la navigation, soit un message d'erreur
    const navigationResult = await navigationPromise;
    const errorElement = await errorMessagePromise;

    if (navigationResult) {
      report.navigationSuccess = true;
      report.finalUrl = page.url();
      console.log('✅ [DIAGNOSTIC] Navigation réussie vers:', report.finalUrl);
    } else if (errorElement) {
      report.errorMessage = await errorElement.textContent() || 'Erreur inconnue';
      console.log('❌ [DIAGNOSTIC] Message d\'erreur détecté:', report.errorMessage);
    } else {
      // Attendre un peu plus pour voir si quelque chose se passe
      await page.waitForTimeout(2000);
      report.finalUrl = page.url();
      console.log('⚠️ [DIAGNOSTIC] Pas de navigation ni d\'erreur visible. URL actuelle:', report.finalUrl);
    }

    // Étape 4: Vérifier le localStorage
    console.log('🔍 [DIAGNOSTIC] Vérification du localStorage...');
    const localStorageItems = await page.evaluate(() => {
      const items: Record<string, string> = {};
      for (let i = 0; i < localStorage.length; i++) {
        const key = localStorage.key(i);
        if (key) {
          items[key] = localStorage.getItem(key) || '';
        }
      }
      return items;
    });

    report.localStorage = localStorageItems;

    // Vérifier spécifiquement les tokens
    const hasAccessToken = 'access_token' in localStorageItems ||
      'veza_access_token' in localStorageItems ||
      localStorageItems['access_token'] !== undefined ||
      localStorageItems['veza_access_token'] !== undefined;

    console.log('📦 [DIAGNOSTIC] LocalStorage:', Object.keys(localStorageItems));
    console.log(hasAccessToken ? '✅ [DIAGNOSTIC] Token d\'accès présent' : '❌ [DIAGNOSTIC] Token d\'accès absent');

    // Générer le rapport
    console.log('\n📊 [DIAGNOSTIC] === RAPPORT DE DIAGNOSTIC ===');
    console.log('Erreurs réseau:', report.networkErrors.length);
    console.log('Erreurs console:', report.consoleErrors.length);
    console.log('Erreurs CORS:', report.corsErrors.length);
    console.log('Navigation réussie:', report.navigationSuccess);
    console.log('Token présent:', hasAccessToken);

    // Afficher les détails des erreurs
    if (report.networkErrors.length > 0) {
      console.log('\n🔴 Erreurs réseau:');
      report.networkErrors.forEach((err) => {
        console.log(`  - ${err.method} ${err.url}: ${err.error}`);
      });
    }

    if (report.consoleErrors.length > 0) {
      console.log('\n🔴 Erreurs console:');
      report.consoleErrors.forEach((err) => {
        console.log(`  - [${err.type}] ${err.message}`);
      });
    }

    if (report.corsErrors.length > 0) {
      console.log('\n🟠 Erreurs CORS:');
      report.corsErrors.forEach((err) => {
        console.log(`  - ${err.url}: ${err.reason}`);
      });
    }

    // Sauvegarder le rapport pour l'analyse
    await page.evaluate((report) => {
       
      (window as any).__diagnosticReport = report;
    }, report);
  });

  test.afterEach(async ({ page }) => {
    // Récupérer le rapport depuis la page si disponible
    const savedReport = await page.evaluate(() => {
       
      return (window as any).__diagnosticReport;
    }).catch(() => null);

    if (savedReport) {
      report = savedReport;
    }
  });
});

