/**
 * Limitaciones conocidas:
 * - "Reactivar" restaura siempre a 'client_editor' — no se guarda el rol previo a la suspensión.
 */
import { useEffect, useState } from 'react'
import * as DialogPrimitive from '@radix-ui/react-dialog'
import { UserX, UserPlus, MoreVertical, Trash2 } from 'lucide-react'
import { supabase } from '@/lib/supabase'
import { useAuth } from '@/auth/AuthContext'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { Skeleton } from '@/components/ui/skeleton'
import {
  Sheet,
  SheetContent,
  SheetHeader,
  SheetTitle,
  SheetFooter,
} from '@/components/ui/sheet'
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from '@/components/ui/select'
import {
  DropdownMenu,
  DropdownMenuContent,
  DropdownMenuItem,
  DropdownMenuSeparator,
  DropdownMenuTrigger,
} from '@/components/ui/dropdown-menu'
import { useToast } from '@/components/ui/use-toast'
import { RoleBadge } from './RoleBadge'

interface AdminUser {
  id: string
  name: string | null
  company: string | null
  platform_role: string
  org_id: string | null
  avatar_url: string | null
  organization: { name: string; is_provider: boolean } | null
  email?: string | null
}

interface OrgOption {
  id: string
  name: string
}

// ─── ConfirmDialog usando @radix-ui/react-dialog (sin @radix-ui/react-alert-dialog) ──

interface ConfirmDialogProps {
  open: boolean
  onOpenChange: (open: boolean) => void
  title: string
  description: string
  confirmLabel?: string
  onConfirm: () => void
  loading?: boolean
  destructive?: boolean
}

function ConfirmDialog({
  open, onOpenChange, title, description,
  confirmLabel = 'Confirmar',
  onConfirm, loading = false, destructive = false,
}: ConfirmDialogProps) {
  return (
    <DialogPrimitive.Root open={open} onOpenChange={onOpenChange}>
      <DialogPrimitive.Portal>
        <DialogPrimitive.Overlay className="fixed inset-0 z-50 bg-black/40 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0" />
        <DialogPrimitive.Content
          className="fixed left-1/2 top-1/2 z-50 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-white rounded-xl shadow-xl p-6 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
          onInteractOutside={(e) => e.preventDefault()}
        >
          <DialogPrimitive.Title className="text-base font-semibold text-slate-900">
            {title}
          </DialogPrimitive.Title>
          <DialogPrimitive.Description className="mt-2 text-sm text-slate-600">
            {description}
          </DialogPrimitive.Description>
          <div className="flex justify-end gap-2 mt-6">
            <Button
              variant="outline"
              size="sm"
              onClick={() => onOpenChange(false)}
              disabled={loading}
            >
              Cancelar
            </Button>
            <Button
              size="sm"
              variant={destructive ? 'destructive' : 'default'}
              onClick={onConfirm}
              disabled={loading}
            >
              {loading ? 'Procesando…' : confirmLabel}
            </Button>
          </div>
        </DialogPrimitive.Content>
      </DialogPrimitive.Portal>
    </DialogPrimitive.Root>
  )
}

// ─── Página principal ─────────────────────────────────────────────────────────

const INVITE_ROLES = ['client_editor', 'client_viewer', 'member'] as const
type InviteRole = typeof INVITE_ROLES[number]

const CHANGE_ROLES = ['platform_admin', 'member', 'client_editor', 'client_viewer', 'guest'] as const

export function UsersPage() {
  const { user: adminUser } = useAuth()
  const { toast } = useToast()

  const [users, setUsers] = useState<AdminUser[]>([])
  const [orgs, setOrgs] = useState<OrgOption[]>([])
  const [loadingUsers, setLoadingUsers] = useState(true)
  const [filterOrgId, setFilterOrgId] = useState<string>('all')

  // Invite sheet
  const [inviteOpen, setInviteOpen] = useState(false)
  const [inviteName, setInviteName] = useState('')
  const [inviteEmail, setInviteEmail] = useState('')
  const [inviteRole, setInviteRole] = useState<InviteRole>('client_editor')
  const [inviteOrgName, setInviteOrgName] = useState('')
  const [inviteError, setInviteError] = useState<string | null>(null)
  const [inviteSuccess, setInviteSuccess] = useState<string | null>(null)
  const [inviting, setInviting] = useState(false)

  // Change role sheet
  const [changeRoleUser, setChangeRoleUser] = useState<AdminUser | null>(null)
  const [changeRoleOpen, setChangeRoleOpen] = useState(false)
  const [newRole, setNewRole] = useState<string>('')
  const [changingRole, setChangingRole] = useState(false)
  const [changeRoleError, setChangeRoleError] = useState<string | null>(null)

  // Confirmations
  const [suspendTarget, setSuspendTarget] = useState<AdminUser | null>(null)
  const [suspending, setSuspending] = useState(false)
  const [deleteTarget, setDeleteTarget] = useState<AdminUser | null>(null)
  const [deleting, setDeleting] = useState(false)
  const [reactivateTarget, setReactivateTarget] = useState<AdminUser | null>(null)
  const [reactivating, setReactivating] = useState(false)

  const fetchUsers = async () => {
    const query = supabase
      .from('users')
      .select('id, name, company, platform_role, org_id, avatar_url, organization:organizations(name, is_provider)')
      .order('name')
    const finalQuery = filterOrgId !== 'all'
      ? query.eq('org_id', filterOrgId)
      : query

    const [{ data }, { data: emailData }] = await Promise.all([
      finalQuery,
      supabase.functions.invoke('list-users'),
    ])

    const emailMap = new Map<string, string | null>()
    if (emailData) {
      for (const u of (emailData as Array<{ id: string; email: string | null }>) ?? []) {
        emailMap.set(u.id, u.email ?? null)
      }
    }

    const usersWithEmail = ((data as AdminUser[] | null) ?? []).map((u) => ({
      ...u,
      email: emailMap.get(u.id) ?? null,
    }))

    setUsers(usersWithEmail)
    setLoadingUsers(false)
  }

  const fetchOrgs = async () => {
    const { data } = await supabase
      .from('organizations')
      .select('id, name')
      .order('name')
    setOrgs((data as OrgOption[] | null) ?? [])
  }

  useEffect(() => {
    void fetchOrgs()
  }, [])

  useEffect(() => {
    setLoadingUsers(true)
    void fetchUsers()
  }, [filterOrgId]) // eslint-disable-line react-hooks/exhaustive-deps

  // ── Invite user ──────────────────────────────────────────────────────────

  const openInvite = () => {
    setInviteName('')
    setInviteEmail('')
    setInviteRole('client_editor')
    setInviteOrgName('')
    setInviteError(null)
    setInviteSuccess(null)
    setInviteOpen(true)
  }

  const handleInvite = async (e: React.FormEvent) => {
    e.preventDefault()
    setInviteError(null)
    setInviteSuccess(null)
    if (!inviteName.trim()) { setInviteError('El nombre es requerido'); return }
    if (!inviteEmail.trim() || !inviteEmail.includes('@')) { setInviteError('Email inválido'); return }
    if ((inviteRole === 'client_editor' || inviteRole === 'client_viewer') && !inviteOrgName.trim()) {
      setInviteError('La organización es requerida para este rol')
      return
    }
    setInviting(true)
    const { error } = await supabase.functions.invoke('invite-user', {
      body: {
        email: inviteEmail.trim(),
        name: inviteName.trim(),
        platform_role: inviteRole,
        org_name: inviteRole === 'member' ? 'InQuality' : inviteOrgName.trim(),
      },
    })
    if (error) {
      setInviteError(typeof error === 'object' && 'message' in error ? String(error.message) : String(error))
      setInviting(false)
    } else {
      setInviteSuccess(`Invitación enviada a ${inviteEmail.trim()}`)
      setInviting(false)
      void fetchUsers()
    }
  }

  // ── Change role ──────────────────────────────────────────────────────────

  const openChangeRole = (u: AdminUser) => {
    setChangeRoleUser(u)
    setNewRole(u.platform_role)
    setChangeRoleError(null)
    setChangeRoleOpen(true)
  }

  const handleChangeRole = async () => {
    if (!changeRoleUser || !newRole) return
    setChangingRole(true)
    const { error } = await supabase
      .from('users')
      .update({ platform_role: newRole })
      .eq('id', changeRoleUser.id)
    if (error) {
      setChangeRoleError(error.message)
      setChangingRole(false)
    } else {
      setChangeRoleOpen(false)
      setChangingRole(false)
      void fetchUsers()
    }
  }

  // ── Suspend (revoke-user vía Edge Function) ───────────────────────────────

  const handleSuspend = async () => {
    if (!suspendTarget) return
    setSuspending(true)
    const { error } = await supabase.functions.invoke('revoke-user', {
      body: { userId: suspendTarget.id },
    })
    if (error) {
      console.error('Error al suspender usuario:', error)
    }
    setSuspendTarget(null)
    setSuspending(false)
    void fetchUsers()
  }

  // ── Hard delete vía Edge Function delete-user ─────────────────────────────

  const handleDelete = async () => {
    if (!deleteTarget) return
    setDeleting(true)
    const { error } = await supabase.functions.invoke('delete-user', {
      body: { userId: deleteTarget.id },
    })
    if (error) {
      toast({
        title: 'Error al eliminar usuario',
        description: typeof error === 'object' && 'message' in error
          ? String(error.message)
          : 'Ocurrió un error inesperado.',
        variant: 'destructive',
      })
    } else {
      toast({ title: 'Usuario eliminado permanentemente' })
    }
    setDeleteTarget(null)
    setDeleting(false)
    void fetchUsers()
  }

  // ── Reactivate (restore to client_editor — rol previo no se guarda) ───────

  const handleReactivate = async () => {
    if (!reactivateTarget) return
    setReactivating(true)
    await supabase
      .from('users')
      .update({ platform_role: 'client_editor' })
      .eq('id', reactivateTarget.id)
    setReactivateTarget(null)
    setReactivating(false)
    void fetchUsers()
  }

  // ─────────────────────────────────────────────────────────────────────────

  const displayedUsers = users

  return (
    <>
      <div className="flex items-center justify-between mb-5">
        <div className="flex items-center gap-3">
          <h2 className="text-lg font-semibold text-slate-900">Usuarios</h2>
          <Select value={filterOrgId} onValueChange={setFilterOrgId}>
            <SelectTrigger className="w-48 h-8 text-xs">
              <SelectValue placeholder="Filtrar por org" />
            </SelectTrigger>
            <SelectContent>
              <SelectItem value="all">Todas las organizaciones</SelectItem>
              {orgs.map((o) => (
                <SelectItem key={o.id} value={o.id}>{o.name}</SelectItem>
              ))}
            </SelectContent>
          </Select>
        </div>
        <Button size="sm" onClick={openInvite}>
          <UserPlus className="h-4 w-4 mr-1.5" />
          Invitar usuario
        </Button>
      </div>

      {loadingUsers ? (
        <TableSkeleton rows={6} />
      ) : displayedUsers.length === 0 ? (
        <EmptyState
          icon={<UserX className="h-10 w-10 text-slate-300" />}
          message={
            filterOrgId !== 'all'
              ? 'No hay usuarios en esta organización.'
              : 'No hay usuarios registrados aún.'
          }
        />
      ) : (
        <div className="rounded-lg border border-slate-200 overflow-hidden bg-white">
          <table className="w-full text-sm">
            <thead className="bg-slate-50 border-b border-slate-200">
              <tr>
                <th className="text-left py-2.5 px-4 font-medium text-slate-600">Nombre</th>
                <th className="text-left py-2.5 px-4 font-medium text-slate-600">Email</th>
                <th className="text-left py-2.5 px-4 font-medium text-slate-600">Rol</th>
                <th className="text-left py-2.5 px-4 font-medium text-slate-600">Organización</th>
                <th className="py-2.5 px-4" />
              </tr>
            </thead>
            <tbody>
              {displayedUsers.map((u) => {
                const isSelf = adminUser?.id === u.id
                const isPending = !u.name && !u.avatar_url

                return (
                  <tr key={u.id} className="border-b border-slate-100 last:border-0 hover:bg-slate-50/50">
                    <td className="py-3 px-4">
                      <div className="flex items-center gap-2">
                        <span className={`font-medium ${u.platform_role === 'guest' ? 'text-slate-400' : 'text-slate-900'}`}>
                          {u.name || <span className="italic text-slate-400">Sin nombre</span>}
                        </span>
                        {isPending && (
                          <span className="text-[10px] font-medium px-1.5 py-0.5 rounded bg-amber-50 text-amber-700 border border-amber-200">
                            Invitación pendiente
                          </span>
                        )}
                        {isSelf && (
                          <span className="text-[10px] font-medium px-1.5 py-0.5 rounded bg-slate-100 text-slate-500">
                            Tú
                          </span>
                        )}
                      </div>
                    </td>
                    <td className="py-3 px-4 text-slate-500 text-xs font-mono">
                      {u.email ?? '—'}
                    </td>
                    <td className="py-3 px-4">
                      <RoleBadge role={u.platform_role} />
                    </td>
                    <td className="py-3 px-4 text-slate-500">
                      {u.organization?.name ?? '—'}
                    </td>
                    <td className="py-3 px-4 text-right">
                      <DropdownMenu>
                        <DropdownMenuTrigger asChild>
                          <Button
                            variant="ghost"
                            size="icon"
                            className="h-7 w-7"
                            disabled={isSelf}
                            title={isSelf ? 'No puedes modificar tu propio usuario' : undefined}
                          >
                            <MoreVertical className="h-4 w-4" />
                          </Button>
                        </DropdownMenuTrigger>
                        <DropdownMenuContent align="end">
                          <DropdownMenuItem onClick={() => openChangeRole(u)}>
                            Cambiar rol
                          </DropdownMenuItem>
                          <DropdownMenuSeparator />
                          {u.platform_role === 'guest' ? (
                            <DropdownMenuItem onClick={() => setReactivateTarget(u)}>
                              Reactivar usuario
                            </DropdownMenuItem>
                          ) : (
                            <DropdownMenuItem
                              className="text-amber-600 focus:text-amber-600"
                              onClick={() => setSuspendTarget(u)}
                            >
                              Suspender
                            </DropdownMenuItem>
                          )}
                          <DropdownMenuItem
                            className="text-destructive focus:text-destructive"
                            onClick={() => setDeleteTarget(u)}
                          >
                            <Trash2 className="h-3.5 w-3.5 mr-2" />
                            Eliminar permanentemente
                          </DropdownMenuItem>
                        </DropdownMenuContent>
                      </DropdownMenu>
                    </td>
                  </tr>
                )
              })}
            </tbody>
          </table>
        </div>
      )}

      {/* ─── Sheet: Invitar usuario ──────────────────────────────────────── */}
      <Sheet open={inviteOpen} onOpenChange={setInviteOpen}>
        <SheetContent>
          <SheetHeader>
            <SheetTitle>Invitar usuario</SheetTitle>
          </SheetHeader>
          <form onSubmit={handleInvite} className="mt-5 flex flex-col gap-4">
            <Field label="Nombre completo" id="invite-name">
              <Input
                id="invite-name"
                value={inviteName}
                onChange={(e) => setInviteName(e.target.value)}
                placeholder="Ej. Ana Martínez"
                disabled={inviting}
                autoFocus
              />
            </Field>

            <Field label="Email" id="invite-email">
              <Input
                id="invite-email"
                type="email"
                value={inviteEmail}
                onChange={(e) => setInviteEmail(e.target.value)}
                placeholder="ana@empresa.com"
                disabled={inviting}
              />
            </Field>

            <Field label="Rol" id="invite-role">
              <Select
                value={inviteRole}
                onValueChange={(v) => setInviteRole(v as InviteRole)}
                disabled={inviting}
              >
                <SelectTrigger id="invite-role">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  <SelectItem value="client_editor">Client Editor</SelectItem>
                  <SelectItem value="client_viewer">Client Viewer</SelectItem>
                  <SelectItem value="member">Member (InQuality)</SelectItem>
                </SelectContent>
              </Select>
            </Field>

            {inviteRole === 'member' ? (
              <Field label="Organización" id="invite-org-member">
                <Input id="invite-org-member" value="InQuality" disabled />
              </Field>
            ) : (
              <Field label="Organización" id="invite-org">
                <Input
                  id="invite-org"
                  list="orgs-datalist"
                  value={inviteOrgName}
                  onChange={(e) => setInviteOrgName(e.target.value)}
                  placeholder="Nombre de la organización"
                  disabled={inviting}
                />
                <datalist id="orgs-datalist">
                  {orgs.map((o) => (
                    <option key={o.id} value={o.name} />
                  ))}
                </datalist>
              </Field>
            )}

            {inviteError && <p className="text-xs text-red-600">{inviteError}</p>}
            {inviteSuccess && <p className="text-xs text-emerald-600 font-medium">{inviteSuccess}</p>}

            <SheetFooter className="mt-2">
              <Button type="submit" disabled={inviting}>
                {inviting ? 'Enviando invitación…' : 'Enviar invitación'}
              </Button>
            </SheetFooter>
          </form>
        </SheetContent>
      </Sheet>

      {/* ─── Sheet: Cambiar rol ──────────────────────────────────────────── */}
      <Sheet open={changeRoleOpen} onOpenChange={setChangeRoleOpen}>
        <SheetContent>
          <SheetHeader>
            <SheetTitle>Cambiar rol — {changeRoleUser?.name}</SheetTitle>
          </SheetHeader>
          <div className="mt-5 flex flex-col gap-4">
            <Field label="Nuevo rol" id="change-role-select">
              <Select value={newRole} onValueChange={setNewRole} disabled={changingRole}>
                <SelectTrigger id="change-role-select">
                  <SelectValue />
                </SelectTrigger>
                <SelectContent>
                  {CHANGE_ROLES.map((r) => (
                    <SelectItem key={r} value={r}>{r}</SelectItem>
                  ))}
                </SelectContent>
              </Select>
            </Field>
            {changeRoleError && <p className="text-xs text-red-600">{changeRoleError}</p>}
            <SheetFooter className="mt-2">
              <Button onClick={handleChangeRole} disabled={changingRole}>
                {changingRole ? 'Guardando…' : 'Guardar rol'}
              </Button>
            </SheetFooter>
          </div>
        </SheetContent>
      </Sheet>

      {/* ─── ConfirmDialog: Suspender ────────────────────────────────────── */}
      <ConfirmDialog
        open={!!suspendTarget}
        onOpenChange={(open) => !open && setSuspendTarget(null)}
        title={`¿Suspender a ${suspendTarget?.name ?? 'este usuario'}?`}
        description="No podrá acceder a la plataforma mientras esté suspendido. Podés reactivarlo después."
        confirmLabel="Suspender"
        onConfirm={handleSuspend}
        loading={suspending}
        destructive
      />

      {/* ─── ConfirmDialog: Eliminar permanentemente ────────────────────── */}
      <ConfirmDialog
        open={!!deleteTarget}
        onOpenChange={(open) => !open && setDeleteTarget(null)}
        title={`¿Eliminar permanentemente a ${deleteTarget?.name ?? 'este usuario'}?`}
        description="Esta acción no puede deshacerse. El usuario perderá acceso inmediatamente y sus datos de autenticación serán eliminados de forma permanente."
        confirmLabel="Eliminar permanentemente"
        onConfirm={handleDelete}
        loading={deleting}
        destructive
      />

      {/* ─── ConfirmDialog: Reactivar ────────────────────────────────────── */}
      <ConfirmDialog
        open={!!reactivateTarget}
        onOpenChange={(open) => !open && setReactivateTarget(null)}
        title={`¿Reactivar a ${reactivateTarget?.name ?? 'este usuario'}?`}
        description="Se le asignará el rol Client Editor. (Nota: el rol original no se conservó al momento de la suspensión.)"
        confirmLabel="Reactivar"
        onConfirm={handleReactivate}
        loading={reactivating}
      />
    </>
  )
}

function Field({ label, id, children }: { label: string; id: string; children: React.ReactNode }) {
  return (
    <div className="flex flex-col gap-1.5">
      <Label htmlFor={id}>{label}</Label>
      {children}
    </div>
  )
}

function TableSkeleton({ rows }: { rows: number }) {
  return (
    <div className="rounded-lg border border-slate-200 overflow-hidden">
      <div className="bg-slate-50 border-b border-slate-200 h-10" />
      <div className="flex flex-col divide-y divide-slate-100">
        {Array.from({ length: rows }).map((_, i) => (
          <div key={i} className="flex gap-4 px-4 py-3 bg-white items-center">
            <Skeleton className="h-4 flex-1" />
            <Skeleton className="h-4 w-40" />
            <Skeleton className="h-5 w-20 rounded" />
            <Skeleton className="h-4 w-28" />
            <Skeleton className="h-6 w-6 rounded" />
          </div>
        ))}
      </div>
    </div>
  )
}

function EmptyState({ icon, message }: { icon: React.ReactNode; message: string }) {
  return (
    <div className="flex flex-col items-center justify-center py-20 gap-3 text-center">
      {icon}
      <p className="text-sm text-slate-500 max-w-xs">{message}</p>
    </div>
  )
}
