import { useEffect, useState } from 'react'
import { Check } from 'lucide-react'
import { Sheet, SheetContent, SheetHeader, SheetTitle, SheetFooter } from '@/components/ui/sheet'
import { Label } from '@/components/ui/label'
import { Input } from '@/components/ui/input'
import { Button } from '@/components/ui/button'
import { SUPABASE_URL, SUPABASE_ANON_KEY } from '@/lib/supabase'
import { useAuth } from '@/auth/AuthContext'

// Lee el access token directamente de localStorage sin pasar por el cliente Supabase.
// Evita contención con processLock — el save de perfil no necesita refresh de token
// porque es una operación rápida y el token está fresco en sesiones activas.
//
// Clave real confirmada por diagnóstico (Sprint 6 Etapa 3, tests/e2e/auth-localStorage-key.spec.ts):
// 'supabase.auth.token' es el STORAGE_KEY default de @supabase/auth-js's GoTrueClient en
// aislamiento, pero @supabase/supabase-js's createClient() SOBRESCRIBE ese default calculando
// `sb-${projectRef}-auth-token` desde la URL del proyecto (projectRef = hostname.split('.')[0]),
// salvo que el caller pase un storageKey explícito — src/lib/supabase.ts no lo hace. El spec de
// diagnóstico confirmó empíricamente: 'supabase.auth.token' NO existe en localStorage; la única
// clave presente es `sb-${projectRef}-auth-token` con un access_token válido. Con la clave vieja,
// getAccessToken() siempre retornaba null → el persist a Supabase nunca se ejecutaba (línea 68
// silenciaba el error) — el usuario veía el cambio en UI pero no se guardaba.
function getAccessToken(): string | null {
  try {
    const projectRef = new URL(SUPABASE_URL).hostname.split('.')[0]
    const storageKey = `sb-${projectRef}-auth-token`
    const raw = localStorage.getItem(storageKey)
    if (!raw) return null
    const parsed = JSON.parse(raw) as { access_token?: string }
    return parsed.access_token ?? null
  } catch {
    return null
  }
}

interface ProfileSheetProps {
  open: boolean
  onOpenChange: (open: boolean) => void
}

export function ProfileSheet({ open, onOpenChange }: ProfileSheetProps) {
  const { user, updateUser } = useAuth()
  const [name, setName] = useState('')
  const [company, setCompany] = useState('')

  useEffect(() => {
    if (open && user) {
      setName(user.name || user.email || '')
      setCompany(user.company ?? '')
    }
    // Intencional: solo inicializar cuando el sheet se abre, no en cada cambio de `user`
    // (evita resetear el formulario mientras el usuario está editando).
    // eslint-disable-next-line react-hooks/exhaustive-deps
  }, [open])

  function handleSave() {
    if (!user || !name.trim()) return

    const savedName = name.trim()
    const savedCompany = company.trim() || undefined

    // Cerramos el Sheet y actualizamos el estado local de inmediato — actualización
    // optimista. El fix para el bug de Radix/react-remove-scroll (pointer-events:none
    // atascado en el body tras cerrar) vive en src/components/ui/sheet.tsx (useEffect
    // que observa el prop `open` y limpia el body defensivamente). El defer de 350ms
    // que existía acá era redundante una vez resuelta la causa raíz ahí.
    onOpenChange(false)
    updateUser({ name: savedName, company: savedCompany })

    // Persistir en Supabase en background — fire & forget.
    // Usamos raw fetch (no el cliente Supabase) para evitar contención con processLock.
    // getSession() interno de supabase.from().update() adquiere processLock y bloquea
    // otras queries de la página mientras espera. Raw fetch lee el token de localStorage
    // directamente — sin lock, sin overhead de auth.
    const token = getAccessToken()
    if (!token) return

    void fetch(
      `${SUPABASE_URL}/rest/v1/users?id=eq.${encodeURIComponent(user.id)}`,
      {
        method: 'PATCH',
        headers: {
          apikey: SUPABASE_ANON_KEY,
          Authorization: `Bearer ${token}`,
          'Content-Type': 'application/json',
          Prefer: 'return=minimal',
        },
        body: JSON.stringify({ name: savedName, company: savedCompany ?? null }),
        signal: AbortSignal.timeout(10000),
      }
    )
      .then((res) => {
        if (!res.ok) console.error('[ProfileSheet] Error guardando perfil:', res.status)
      })
      .catch((err) => {
        console.error('[ProfileSheet] Error guardando perfil:', err)
      })
  }

  return (
    <Sheet open={open} onOpenChange={onOpenChange}>
      <SheetContent>
        <SheetHeader>
          <SheetTitle>Editar perfil</SheetTitle>
        </SheetHeader>

        <div className="space-y-4 mt-6">
          <div className="space-y-1.5">
            <Label className="text-xs">Nombre</Label>
            <Input
              autoFocus
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="Tu nombre"
            />
          </div>

          <div className="space-y-1.5">
            <Label className="text-xs">Empresa</Label>
            <Input
              value={company}
              onChange={(e) => setCompany(e.target.value)}
              placeholder="InQuality"
            />
          </div>

          <div className="space-y-1.5">
            <Label className="text-xs">Email</Label>
            <Input value={user?.email ?? ''} readOnly className="bg-muted text-muted-foreground cursor-not-allowed" />
          </div>
        </div>

        <SheetFooter className="mt-6 flex gap-2">
          <Button variant="outline" onClick={() => onOpenChange(false)}>
            Cancelar
          </Button>
          <Button onClick={handleSave} disabled={!name.trim()} className="gap-1.5">
            <Check className="h-4 w-4" />
            Guardar
          </Button>
        </SheetFooter>
      </SheetContent>
    </Sheet>
  )
}
