import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
import { getSupabaseAdmin } from '@/lib/supabase'
import { formatDate } from '../responses/admin-format'
import { AdminNavBar } from '@/components/admin-nav-bar'
import { InviteForm } from './invite-form'

export const dynamic = 'force-dynamic'

interface OrgOption {
  id: string
  name: string
}

interface RoleRow {
  user_id: string
  app_role: string
  org_id: string | null
  organizations: { name: string } | null
}

interface UserDisplayRow {
  userId: string
  email: string
  orgName: string
  role: string
  createdAt: string
}

async function getSupabaseSession() {
  const cookieStore = await cookies()
  return createServerClient(
    process.env.NEXT_PUBLIC_SUPABASE_URL!,
    process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
    {
      cookies: {
        getAll() {
          return cookieStore.getAll()
        },
        setAll(cookiesToSet) {
          try {
            cookiesToSet.forEach(({ name, value, options }) =>
              cookieStore.set(name, value, options)
            )
          } catch {
            // Server Component — no puede mutar cookies, se ignora
          }
        },
      },
    }
  )
}

// auth.users no está expuesto vía PostgREST (no es schema público) — no hay
// forma de hacer un .from('auth.users') ni un join SQL directo desde
// supabase-js. listUsers() es la API admin soportada para resolver el email;
// pagina hasta agotar resultados (tope defensivo de 2000 usuarios).
async function fetchAllUsersMap(admin: ReturnType<typeof getSupabaseAdmin>) {
  const map = new Map<string, { email: string; createdAt: string }>()
  const perPage = 200
  for (let page = 1; page <= 10; page++) {
    const { data, error } = await admin.auth.admin.listUsers({ page, perPage })
    if (error || !data) break
    data.users.forEach((u) => {
      map.set(u.id, { email: u.email ?? '—', createdAt: u.created_at })
    })
    if (data.users.length < perPage) break
  }
  return map
}

export default async function AdminUsuariosPage() {
  const supabase = await getSupabaseSession()

  // 1. Identificar a quien llama — defensivo, el middleware ya debería haber
  // redirigido a /login si no hay sesión.
  const { data: { user } } = await supabase.auth.getUser()
  if (!user) {
    return (
      <div className="admin-page" role="main">
        <h1 className="admin-title">Acceso restringido</h1>
        <p className="admin-error">No se encontró una sesión activa.</p>
        <a href="/login" className="admin-back-link">← Iniciar sesión</a>
      </div>
    )
  }

  // 2. Verificar platform_admin leyendo la fila REAL en user_roles — esta
  // página usa getSupabaseAdmin() más abajo (bypasa RLS por completo), así
  // que el gate de autorización tiene que ir acá, no delegarse a las policies.
  const { data: callerRole } = await supabase
    .from('user_roles')
    .select('app_role')
    .eq('user_id', user.id)
    .maybeSingle()

  if (callerRole?.app_role !== 'platform_admin') {
    return (
      <div className="admin-page" role="main">
        <h1 className="admin-title">Acceso restringido</h1>
        <p className="admin-error">
          Esta sección es exclusiva para administradores de plataforma.
        </p>
        <a href="/admin/responses" className="admin-back-link">← Volver</a>
      </div>
    )
  }

  // 3. Datos — admin client para todo a partir de acá. La autorización ya
  // quedó probada en el paso 2 con una lectura directa a la DB; usar admin
  // para el resto evita depender de policies/claims del JWT que podrían
  // haber quedado stale.
  const admin = getSupabaseAdmin()

  const [{ data: orgsData, error: orgsError }, { data: rolesData, error: rolesError }] =
    await Promise.all([
      admin.from('organizations').select('id, name').order('name'),
      admin.from('user_roles').select('user_id, app_role, org_id, organizations(name)'),
    ])

  if (orgsError || rolesError) {
    return (
      <div className="admin-page" role="main">
        <h1 className="admin-title">Usuarios</h1>
        <p className="admin-error">No fue posible conectarse a la base de datos.</p>
        <pre className="admin-error-detail">
          {(orgsError ?? rolesError)?.message}
        </pre>
      </div>
    )
  }

  const organizations = (orgsData ?? []) as OrgOption[]
  const roles = (rolesData ?? []) as unknown as RoleRow[]
  const usersMap = await fetchAllUsersMap(admin)

  const userRows: UserDisplayRow[] = roles.map((r) => {
    const u = usersMap.get(r.user_id)
    return {
      userId: r.user_id,
      email: u?.email ?? '—',
      orgName: r.organizations?.name ?? '—',
      role: r.app_role,
      createdAt: u?.createdAt ? formatDate(u.createdAt) : '—',
    }
  })

  return (
    <>
      <AdminNavBar active="usuarios" />
      <div className="admin-page" role="main">
      <header className="admin-header">
        <div>
          <h1 className="admin-title">Usuarios</h1>
          <p className="admin-subtitle">{userRows.length} usuarios registrados</p>
        </div>
      </header>

      <section className="admin-detail-section">
        <h2 className="admin-detail-section-title">Invitar usuario</h2>
        <InviteForm organizations={organizations} />
      </section>

      <section className="admin-detail-section">
        <h2 className="admin-detail-section-title">Usuarios existentes</h2>
        <div className="admin-table-wrapper">
          <table className="admin-table">
            <thead>
              <tr>
                <th>Email</th>
                <th>Organización</th>
                <th>Rol</th>
                <th>Fecha de creación</th>
              </tr>
            </thead>
            <tbody>
              {userRows.map((row) => (
                <tr key={row.userId}>
                  <td>{row.email}</td>
                  <td>{row.orgName}</td>
                  <td>{row.role}</td>
                  <td>{row.createdAt}</td>
                </tr>
              ))}
            </tbody>
          </table>
          {userRows.length === 0 && (
            <p className="admin-empty">Todavía no hay usuarios invitados.</p>
          )}
        </div>
      </section>
      </div>
    </>
  )
}
