// Global setup de Playwright — Sprint 4 Etapa 8.
//
// Decisión tomada: Opción A (sesión real contra Supabase con usuario de test
// email/password, platform_role='platform_admin' en public.users). Permite que
// los specs E2E ejerciten el flujo real de auth + RLS + queries, no un mock.
//
// Usuario de test creado manualmente en Supabase Studio (no vía signup automático).
// Credenciales en .env.test (gitignored) — ver .env.example para el formato.
//
// Genera tests/e2e/setup/auth-state.json: storageState de Playwright con la
// sesión inyectada en localStorage bajo la clave sb-{project_ref}-auth-token,
// el mismo formato que usa supabase-js v2 y que AuthContext.getUserFromStorage()
// espera leer. Los specs que necesitan auth usan:
//   test.use({ storageState: 'tests/e2e/setup/auth-state.json' })

import { chromium } from '@playwright/test'
import { createClient } from '@supabase/supabase-js'
import { readFileSync, existsSync } from 'fs'
import { resolve } from 'path'
import { fileURLToPath } from 'url'

const __dirname = fileURLToPath(new URL('.', import.meta.url))
const ROOT = resolve(__dirname, '../../..')
const STATE_PATH = resolve(__dirname, 'auth-state.json')

function loadEnvFile(filename: string): Record<string, string> {
  const path = resolve(ROOT, filename)
  if (!existsSync(path)) return {}
  const out: Record<string, string> = {}
  for (const line of readFileSync(path, 'utf-8').split('\n')) {
    const trimmed = line.trim()
    if (!trimmed || trimmed.startsWith('#')) continue
    const idx = trimmed.indexOf('=')
    if (idx === -1) continue
    out[trimmed.slice(0, idx)] = trimmed.slice(idx + 1)
  }
  return out
}

async function globalSetup() {
  const local = loadEnvFile('.env.local')
  const test = loadEnvFile('.env.test')

  const supabaseUrl = local.VITE_SUPABASE_URL
  const supabaseAnonKey = local.VITE_SUPABASE_ANON_KEY
  const email = test.TEST_USER_EMAIL
  const password = test.TEST_USER_PASSWORD

  if (!supabaseUrl || !supabaseAnonKey) {
    console.warn('[auth-setup] VITE_SUPABASE_URL/ANON_KEY no encontradas en .env.local — specs con auth se saltarán storageState')
    return
  }
  if (!email || !password) {
    console.warn('[auth-setup] TEST_USER_EMAIL/PASSWORD no encontradas en .env.test — specs con auth se saltarán storageState')
    return
  }

  const supabase = createClient(supabaseUrl, supabaseAnonKey)
  const { data, error } = await supabase.auth.signInWithPassword({ email, password })
  if (error || !data.session) {
    console.error('[auth-setup] Login de usuario de test falló:', error?.message)
    return
  }

  // Diagnóstico Sprint 5 Etapa 6a-extra: @supabase/auth-js v2 define STORAGE_KEY =
  // 'supabase.auth.token' como default de GoTrueClient (constants.js), pero
  // @supabase/supabase-js's createClient() SOBRESCRIBE ese default calculando
  // `sb-${projectRef}-auth-token` a partir de la URL (ver SupabaseClient constructor:
  // `i = sb-${hostname.split('.')[0]}-auth-token`, mergeado en `auth.storageKey`),
  // salvo que el caller pase un storageKey explícito. src/lib/supabase.ts no lo hace,
  // así que esta es la clave REAL que usa la app. Confirmado empíricamente: el test
  // "app header shows user avatar" (sprint-4-smoke.spec.ts) requiere que AuthContext
  // encuentre una sesión real bajo esta clave — pasa, y auth-state.json generado
  // contiene exactamente `sb-${projectRef}-auth-token`. No es un bug.
  const projectRef = new URL(supabaseUrl).hostname.split('.')[0]
  const storageKey = `sb-${projectRef}-auth-token`

  const browser = await chromium.launch()
  const page = await browser.newPage()
  await page.goto('http://localhost:4173/login')
  await page.evaluate(
    ([key, session]) => {
      window.localStorage.setItem(key, JSON.stringify(session))
    },
    [storageKey, data.session] as const
  )
  await page.context().storageState({ path: STATE_PATH })
  await browser.close()

  console.log(`[auth-setup] Sesión de test guardada en ${STATE_PATH}`)
}

export default globalSetup
