'use client';

import { useState, useCallback, useMemo } from 'react';
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query';
import { useRouter } from 'next/navigation';
import { useTranslation } from 'react-i18next';
import { apiClient } from '@/infrastructure/api/api-client';
import { queryKeys } from '@/infrastructure/api/query-keys';
import { cn } from '@/lib/utils';

// ---------------------------------------------------------------------------
// Types
// ---------------------------------------------------------------------------

interface User {
  id: string;
  displayName: string;
  email: string;
  role: 'admin' | 'operator' | 'viewer';
  tenantId: string;
  tenantName: string;
  status: 'active' | 'disabled';
  lastLoginAt: string | null;
  createdAt: string;
}

type UsersResponse = { data: User[]; total: number } | User[];

interface UserFormData {
  displayName: string;
  email: string;
  password: string;
  role: 'admin' | 'operator' | 'viewer';
  tenantId: string;
}

interface EditUserFormData {
  role: 'admin' | 'operator' | 'viewer';
  status: 'active' | 'disabled';
}

// ---------------------------------------------------------------------------
// Constants
// ---------------------------------------------------------------------------

const EMPTY_FORM: UserFormData = {
  displayName: '',
  email: '',
  password: '',
  role: 'viewer',
  tenantId: '',
};

const EMPTY_EDIT_FORM: EditUserFormData = {
  role: 'viewer',
  status: 'active',
};

// ---------------------------------------------------------------------------
// Helpers
// ---------------------------------------------------------------------------

function formatDate(dateStr: string | null): string {
  if (!dateStr) return 'Never';
  try {
    return new Date(dateStr).toLocaleDateString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
    });
  } catch {
    return dateStr;
  }
}

function formatDateTime(dateStr: string | null): string {
  if (!dateStr) return 'Never';
  try {
    return new Date(dateStr).toLocaleString('en-US', {
      year: 'numeric',
      month: 'short',
      day: 'numeric',
      hour: '2-digit',
      minute: '2-digit',
    });
  } catch {
    return dateStr;
  }
}

// ---------------------------------------------------------------------------
// Role badge
// ---------------------------------------------------------------------------

function RoleBadge({ role }: { role: User['role'] }) {
  const styles: Record<User['role'], string> = {
    admin: 'bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-400',
    operator: 'bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-400',
    viewer: 'bg-gray-100 text-gray-800 dark:bg-gray-800/40 dark:text-gray-300',
  };

  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium capitalize',
        styles[role],
      )}
    >
      {role}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Status badge
// ---------------------------------------------------------------------------

function StatusBadge({ status }: { status: User['status'] }) {
  const styles: Record<User['status'], string> = {
    active: 'bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-400',
    disabled: 'bg-red-100 text-red-800 dark:bg-red-900/30 dark:text-red-400',
  };

  return (
    <span
      className={cn(
        'inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium capitalize',
        styles[status],
      )}
    >
      {status}
    </span>
  );
}

// ---------------------------------------------------------------------------
// Add user dialog
// ---------------------------------------------------------------------------

function AddUserDialog({
  open,
  form,
  errors,
  saving,
  onClose,
  onChange,
  onSubmit,
}: {
  open: boolean;
  form: UserFormData;
  errors: Partial<Record<keyof UserFormData, string>>;
  saving: boolean;
  onClose: () => void;
  onChange: (field: keyof UserFormData, value: string) => void;
  onSubmit: () => void;
}) {
  const { t } = useTranslation('users');
  const { t: tc } = useTranslation('common');

  if (!open) return null;

  const ROLES: { value: User['role']; label: string }[] = [
    { value: 'admin', label: t('roles.admin') },
    { value: 'operator', label: t('roles.operator') },
    { value: 'viewer', label: t('roles.viewer') },
  ];

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />

      <div className="relative z-10 w-full max-w-lg bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-4">{t('createDialog.title')}</h2>

        <div className="space-y-4 max-h-[70vh] overflow-y-auto pr-1">
          {/* displayName */}
          <div>
            <label className="block text-sm font-medium mb-1">
              {t('form.displayName')} <span className="text-destructive">*</span>
            </label>
            <input
              type="text"
              value={form.displayName}
              onChange={(e) => onChange('displayName', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.displayName ? 'border-destructive' : 'border-input',
              )}
              placeholder="John Doe"
            />
            {errors.displayName && (
              <p className="text-xs text-destructive mt-1">{errors.displayName}</p>
            )}
          </div>

          {/* email */}
          <div>
            <label className="block text-sm font-medium mb-1">
              {t('form.email')} <span className="text-destructive">*</span>
            </label>
            <input
              type="email"
              value={form.email}
              onChange={(e) => onChange('email', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.email ? 'border-destructive' : 'border-input',
              )}
              placeholder="john@example.com"
            />
            {errors.email && (
              <p className="text-xs text-destructive mt-1">{errors.email}</p>
            )}
          </div>

          {/* password */}
          <div>
            <label className="block text-sm font-medium mb-1">
              {t('form.password')} <span className="text-destructive">*</span>
            </label>
            <input
              type="password"
              value={form.password}
              onChange={(e) => onChange('password', e.target.value)}
              className={cn(
                'w-full px-3 py-2 rounded-md border bg-background text-sm',
                errors.password ? 'border-destructive' : 'border-input',
              )}
              placeholder="Enter password"
            />
            {errors.password && (
              <p className="text-xs text-destructive mt-1">{errors.password}</p>
            )}
          </div>

          {/* role */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('form.role')}</label>
            <select
              value={form.role}
              onChange={(e) => onChange('role', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            >
              {ROLES.map((r) => (
                <option key={r.value} value={r.value}>
                  {r.label}
                </option>
              ))}
            </select>
          </div>

          {/* tenantId */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('form.tenantId')}</label>
            <input
              type="text"
              value={form.tenantId}
              onChange={(e) => onChange('tenantId', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
              placeholder="Optional tenant ID"
            />
          </div>
        </div>

        <div className="flex justify-end gap-3 mt-6 pt-4 border-t">
          <button
            type="button"
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
            disabled={saving}
          >
            {tc('cancel')}
          </button>
          <button
            type="button"
            onClick={onSubmit}
            disabled={saving}
            className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
          >
            {saving ? t('createDialog.creating') : t('createDialog.create')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Edit user dialog
// ---------------------------------------------------------------------------

function EditUserDialog({
  open,
  userName,
  form,
  saving,
  onClose,
  onChange,
  onSubmit,
}: {
  open: boolean;
  userName: string;
  form: EditUserFormData;
  saving: boolean;
  onClose: () => void;
  onChange: (field: keyof EditUserFormData, value: string) => void;
  onSubmit: () => void;
}) {
  const { t } = useTranslation('users');
  const { t: tc } = useTranslation('common');

  if (!open) return null;

  const ROLES: { value: User['role']; label: string }[] = [
    { value: 'admin', label: t('roles.admin') },
    { value: 'operator', label: t('roles.operator') },
    { value: 'viewer', label: t('roles.viewer') },
  ];

  const STATUSES: { value: User['status']; label: string }[] = [
    { value: 'active', label: t('statuses.active') },
    { value: 'disabled', label: t('statuses.disabled') },
  ];

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />

      <div className="relative z-10 w-full max-w-lg bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-4">
          {t('editDialog.title')} <span className="text-muted-foreground">{userName}</span>
        </h2>

        <div className="space-y-4">
          {/* role */}
          <div>
            <label className="block text-sm font-medium mb-1">{t('form.role')}</label>
            <select
              value={form.role}
              onChange={(e) => onChange('role', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            >
              {ROLES.map((r) => (
                <option key={r.value} value={r.value}>
                  {r.label}
                </option>
              ))}
            </select>
          </div>

          {/* status */}
          <div>
            <label className="block text-sm font-medium mb-1">{tc('status')}</label>
            <select
              value={form.status}
              onChange={(e) => onChange('status', e.target.value)}
              className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            >
              {STATUSES.map((s) => (
                <option key={s.value} value={s.value}>
                  {s.label}
                </option>
              ))}
            </select>
          </div>
        </div>

        <div className="flex justify-end gap-3 mt-6 pt-4 border-t">
          <button
            type="button"
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
            disabled={saving}
          >
            {tc('cancel')}
          </button>
          <button
            type="button"
            onClick={onSubmit}
            disabled={saving}
            className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50"
          >
            {saving ? t('editDialog.saving') : t('editDialog.save')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Delete user confirmation dialog
// ---------------------------------------------------------------------------

function DeleteUserDialog({
  open,
  userName,
  deleting,
  onClose,
  onConfirm,
}: {
  open: boolean;
  userName: string;
  deleting: boolean;
  onClose: () => void;
  onConfirm: () => void;
}) {
  const { t } = useTranslation('users');
  const { t: tc } = useTranslation('common');

  if (!open) return null;

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center">
      <div className="absolute inset-0 bg-black/50" onClick={onClose} />
      <div className="relative z-10 w-full max-w-sm bg-card border rounded-lg shadow-lg p-6 mx-4">
        <h2 className="text-lg font-semibold mb-2">{t('deleteDialog.title')}</h2>
        <p className="text-sm text-muted-foreground mb-4">
          {t('deleteDialog.message')}
        </p>

        <div className="p-3 mb-4 rounded-md bg-muted text-xs text-muted-foreground">
          {t('deleteDialog.warning')}
        </div>

        <div className="flex justify-end gap-3">
          <button
            onClick={onClose}
            className="px-4 py-2 text-sm rounded-md border border-input hover:bg-accent"
            disabled={deleting}
          >
            {tc('cancel')}
          </button>
          <button
            onClick={onConfirm}
            disabled={deleting}
            className="px-4 py-2 text-sm rounded-md bg-destructive text-destructive-foreground hover:bg-destructive/90 disabled:opacity-50"
          >
            {deleting ? tc('deleting') : tc('delete')}
          </button>
        </div>
      </div>
    </div>
  );
}

// ---------------------------------------------------------------------------
// Main page component
// ---------------------------------------------------------------------------

export default function UsersPage() {
  const { t } = useTranslation('users');
  const { t: tc } = useTranslation('common');
  const queryClient = useQueryClient();
  const router = useRouter();

  // State ----------------------------------------------------------------
  const [addDialogOpen, setAddDialogOpen] = useState(false);
  const [editingUser, setEditingUser] = useState<User | null>(null);
  const [deleteTarget, setDeleteTarget] = useState<User | null>(null);
  const [form, setForm] = useState<UserFormData>({ ...EMPTY_FORM });
  const [editForm, setEditForm] = useState<EditUserFormData>({ ...EMPTY_EDIT_FORM });
  const [errors, setErrors] = useState<Partial<Record<keyof UserFormData, string>>>({});

  // Filters
  const [search, setSearch] = useState('');
  const [roleFilter, setRoleFilter] = useState<string>('all');
  const [statusFilter, setStatusFilter] = useState<string>('all');

  const ROLES: { value: User['role']; label: string }[] = [
    { value: 'admin', label: t('roles.admin') },
    { value: 'operator', label: t('roles.operator') },
    { value: 'viewer', label: t('roles.viewer') },
  ];

  const STATUSES: { value: User['status']; label: string }[] = [
    { value: 'active', label: t('statuses.active') },
    { value: 'disabled', label: t('statuses.disabled') },
  ];

  // Queries --------------------------------------------------------------
  const { data: usersData, isLoading, error } = useQuery({
    queryKey: queryKeys.users.list(),
    queryFn: () => apiClient<UsersResponse>('/api/v1/auth/users'),
  });

  const allUsers: User[] = Array.isArray(usersData)
    ? usersData
    : (usersData as { data: User[] } | undefined)?.data ?? [];

  // Filter ---------------------------------------------------------------
  const filteredUsers = useMemo(() => {
    let result = allUsers;

    if (search.trim()) {
      const q = search.toLowerCase().trim();
      result = result.filter(
        (u) =>
          u.displayName.toLowerCase().includes(q) ||
          u.email.toLowerCase().includes(q),
      );
    }

    if (roleFilter !== 'all') {
      result = result.filter((u) => u.role === roleFilter);
    }

    if (statusFilter !== 'all') {
      result = result.filter((u) => u.status === statusFilter);
    }

    return result;
  }, [allUsers, search, roleFilter, statusFilter]);

  // Mutations ------------------------------------------------------------
  const createMutation = useMutation({
    mutationFn: (body: Record<string, unknown>) =>
      apiClient<User>('/api/v1/auth/users', { method: 'POST', body }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
      closeAddDialog();
    },
  });

  const updateMutation = useMutation({
    mutationFn: ({ id, body }: { id: string; body: Record<string, unknown> }) =>
      apiClient<User>(`/api/v1/auth/users/${id}`, { method: 'PUT', body }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
      closeEditDialog();
    },
  });

  const deleteMutation = useMutation({
    mutationFn: (id: string) =>
      apiClient<void>(`/api/v1/auth/users/${id}`, { method: 'DELETE' }),
    onSuccess: () => {
      queryClient.invalidateQueries({ queryKey: queryKeys.users.all });
      setDeleteTarget(null);
    },
  });

  // Helpers --------------------------------------------------------------
  const validateAdd = useCallback((): boolean => {
    const next: Partial<Record<keyof UserFormData, string>> = {};
    if (!form.displayName.trim()) next.displayName = t('validation.displayNameRequired');
    if (!form.email.trim()) next.email = t('validation.emailRequired');
    if (!form.password.trim()) next.password = t('validation.passwordRequired');
    if (form.password.trim() && form.password.trim().length < 8)
      next.password = 'Password must be at least 8 characters';
    setErrors(next);
    return Object.keys(next).length === 0;
  }, [form, t]);

  const closeAddDialog = useCallback(() => {
    setAddDialogOpen(false);
    setForm({ ...EMPTY_FORM });
    setErrors({});
  }, []);

  const closeEditDialog = useCallback(() => {
    setEditingUser(null);
    setEditForm({ ...EMPTY_EDIT_FORM });
  }, []);

  const openAdd = useCallback(() => {
    setForm({ ...EMPTY_FORM });
    setErrors({});
    setAddDialogOpen(true);
  }, []);

  const openEdit = useCallback((user: User) => {
    setEditingUser(user);
    setEditForm({
      role: user.role,
      status: user.status,
    });
  }, []);

  const handleAddChange = useCallback(
    (field: keyof UserFormData, value: string) => {
      setForm((prev) => ({ ...prev, [field]: value }));
      setErrors((prev) => {
        const next = { ...prev };
        delete next[field];
        return next;
      });
    },
    [],
  );

  const handleEditChange = useCallback(
    (field: keyof EditUserFormData, value: string) => {
      setEditForm((prev) => ({ ...prev, [field]: value }));
    },
    [],
  );

  const handleAddSubmit = useCallback(() => {
    if (!validateAdd()) return;
    const body: Record<string, unknown> = {
      displayName: form.displayName.trim(),
      email: form.email.trim(),
      password: form.password,
      role: form.role,
    };
    if (form.tenantId.trim()) {
      body.tenantId = form.tenantId.trim();
    }
    createMutation.mutate(body);
  }, [form, validateAdd, createMutation]);

  const handleEditSubmit = useCallback(() => {
    if (!editingUser) return;
    const body: Record<string, unknown> = {
      role: editForm.role,
      status: editForm.status,
    };
    updateMutation.mutate({ id: editingUser.id, body });
  }, [editForm, editingUser, updateMutation]);

  // Render ---------------------------------------------------------------
  return (
    <div>
      {/* Header */}
      <div className="flex flex-col sm:flex-row sm:items-center sm:justify-between gap-4 mb-6">
        <div>
          <h1 className="text-2xl font-bold">{t('title')}</h1>
          <p className="text-sm text-muted-foreground mt-1">
            {t('subtitle')}
          </p>
        </div>
        <button
          onClick={openAdd}
          className="px-4 py-2 text-sm rounded-md bg-primary text-primary-foreground hover:bg-primary/90 whitespace-nowrap"
        >
          {t('addUser')}
        </button>
      </div>

      {/* Filters */}
      <div className="flex flex-col sm:flex-row sm:items-center gap-4 mb-6">
        {/* Search */}
        <div className="flex-1 max-w-sm">
          <input
            type="text"
            value={search}
            onChange={(e) => setSearch(e.target.value)}
            className="w-full px-3 py-2 rounded-md border border-input bg-background text-sm"
            placeholder={t('searchPlaceholder')}
          />
        </div>

        {/* Role filter */}
        <div className="flex gap-1 p-1 bg-muted rounded-lg">
          <button
            onClick={() => setRoleFilter('all')}
            className={cn(
              'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
              roleFilter === 'all'
                ? 'bg-background text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground',
            )}
          >
            {t('allRoles')}
          </button>
          {ROLES.map((r) => (
            <button
              key={r.value}
              onClick={() => setRoleFilter(r.value)}
              className={cn(
                'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
                roleFilter === r.value
                  ? 'bg-background text-foreground shadow-sm'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              {r.label}
            </button>
          ))}
        </div>

        {/* Status filter */}
        <div className="flex gap-1 p-1 bg-muted rounded-lg">
          <button
            onClick={() => setStatusFilter('all')}
            className={cn(
              'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
              statusFilter === 'all'
                ? 'bg-background text-foreground shadow-sm'
                : 'text-muted-foreground hover:text-foreground',
            )}
          >
            {tc('all')}
          </button>
          {STATUSES.map((s) => (
            <button
              key={s.value}
              onClick={() => setStatusFilter(s.value)}
              className={cn(
                'px-3 py-1.5 text-sm rounded-md font-medium transition-colors',
                statusFilter === s.value
                  ? 'bg-background text-foreground shadow-sm'
                  : 'text-muted-foreground hover:text-foreground',
              )}
            >
              {s.label}
            </button>
          ))}
        </div>
      </div>

      {/* Error state */}
      {error && (
        <div className="p-4 mb-4 rounded-md border border-destructive/50 bg-destructive/10 text-destructive text-sm">
          {t('loadError')} {(error as Error).message}
        </div>
      )}

      {/* Loading state */}
      {isLoading && (
        <div className="text-sm text-muted-foreground py-12 text-center">
          {t('loading')}
        </div>
      )}

      {/* Users table */}
      {!isLoading && !error && (
        <div className="border rounded-lg overflow-hidden">
          <div className="overflow-x-auto">
            <table className="w-full text-sm">
              <thead>
                <tr className="border-b bg-muted/50">
                  <th className="text-left px-4 py-3 font-medium">{t('table.name')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.email')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.role')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.tenant')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.status')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.lastLogin')}</th>
                  <th className="text-left px-4 py-3 font-medium">{t('table.created')}</th>
                  <th className="text-right px-4 py-3 font-medium">{t('table.actions')}</th>
                </tr>
              </thead>
              <tbody>
                {filteredUsers.length === 0 ? (
                  <tr>
                    <td
                      colSpan={8}
                      className="text-center text-muted-foreground py-12"
                    >
                      {allUsers.length === 0
                        ? t('empty')
                        : t('noMatchingFilters')}
                    </td>
                  </tr>
                ) : (
                  filteredUsers.map((user) => (
                    <tr
                      key={user.id}
                      className="border-b last:border-b-0 hover:bg-muted/30 transition-colors"
                    >
                      <td className="px-4 py-3">
                        <button
                          onClick={() => router.push(`/users/${user.id}`)}
                          className="font-medium hover:text-primary transition-colors text-left"
                        >
                          {user.displayName}
                        </button>
                      </td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {user.email}
                      </td>
                      <td className="px-4 py-3">
                        <RoleBadge role={user.role} />
                      </td>
                      <td className="px-4 py-3 text-muted-foreground">
                        {user.tenantName || '--'}
                      </td>
                      <td className="px-4 py-3">
                        <StatusBadge status={user.status} />
                      </td>
                      <td className="px-4 py-3 text-muted-foreground text-xs">
                        {formatDateTime(user.lastLoginAt)}
                      </td>
                      <td className="px-4 py-3 text-muted-foreground text-xs">
                        {formatDate(user.createdAt)}
                      </td>
                      <td className="px-4 py-3 text-right">
                        <div className="flex items-center justify-end gap-2">
                          <button
                            onClick={() => router.push(`/users/${user.id}`)}
                            className="px-3 py-1 text-xs rounded-md border border-input hover:bg-accent transition-colors"
                          >
                            {tc('view')}
                          </button>
                          <button
                            onClick={() => openEdit(user)}
                            className="px-3 py-1 text-xs rounded-md border border-input hover:bg-accent transition-colors"
                          >
                            {tc('edit')}
                          </button>
                          <button
                            onClick={() => setDeleteTarget(user)}
                            className="px-3 py-1 text-xs rounded-md border border-destructive/50 text-destructive hover:bg-destructive/10 transition-colors"
                          >
                            {tc('delete')}
                          </button>
                        </div>
                      </td>
                    </tr>
                  ))
                )}
              </tbody>
            </table>
          </div>
        </div>
      )}

      {/* Results count */}
      {!isLoading && !error && allUsers.length > 0 && (
        <div className="mt-3 text-xs text-muted-foreground">
          {t('showing', { count: filteredUsers.length, total: allUsers.length })}
        </div>
      )}

      {/* Add user dialog */}
      <AddUserDialog
        open={addDialogOpen}
        form={form}
        errors={errors}
        saving={createMutation.isPending}
        onClose={closeAddDialog}
        onChange={handleAddChange}
        onSubmit={handleAddSubmit}
      />

      {/* Edit user dialog */}
      <EditUserDialog
        open={!!editingUser}
        userName={editingUser?.displayName ?? ''}
        form={editForm}
        saving={updateMutation.isPending}
        onClose={closeEditDialog}
        onChange={handleEditChange}
        onSubmit={handleEditSubmit}
      />

      {/* Delete user dialog */}
      <DeleteUserDialog
        open={!!deleteTarget}
        userName={deleteTarget?.displayName ?? ''}
        deleting={deleteMutation.isPending}
        onClose={() => setDeleteTarget(null)}
        onConfirm={() => {
          if (deleteTarget) deleteMutation.mutate(deleteTarget.id);
        }}
      />
    </div>
  );
}
