import React, { useEffect, useMemo, useState } from 'react';
import { useNavigate } from 'react-router-dom';
import { Layout } from '../components/Layout';
import { ConfirmModal } from '../components/ConfirmModal';
import { useAuth } from '../context/AuthContext';
import * as api from '../api';
import type { Collection } from '../types';
import { Shield, UserPlus, RefreshCw, UserCog, LogIn, XCircle, Settings as SettingsIcon, KeyRound } from 'lucide-react';
import {
  ACCESS_TOKEN_KEY,
  IMPERSONATION_KEY,
  type ImpersonationState,
  readImpersonationState,
  REFRESH_TOKEN_KEY,
  stopImpersonation as restoreImpersonation,
  USER_KEY,
} from '../utils/impersonation';

type AdminUser = {
  id: string;
  username: string | null;
  email: string;
  name: string;
  role: 'ADMIN' | 'USER' | string;
  mustResetPassword: boolean;
  isActive: boolean;
  createdAt: string;
  updatedAt: string;
};

export const Admin: React.FC = () => {
  const navigate = useNavigate();
  const { user: authUser, authEnabled } = useAuth();
  const isAdmin = authUser?.role === 'ADMIN';

  const [collections, setCollections] = useState<Collection[]>([]);
  const [users, setUsers] = useState<AdminUser[]>([]);
  const [loadingUsers, setLoadingUsers] = useState(false);
  const [error, setError] = useState('');
  const [success, setSuccess] = useState('');

  const [createOpen, setCreateOpen] = useState(false);
  const [createEmail, setCreateEmail] = useState('');
  const [createName, setCreateName] = useState('');
  const [createUsername, setCreateUsername] = useState('');
  const [createPassword, setCreatePassword] = useState('');
  const [createRole, setCreateRole] = useState<'ADMIN' | 'USER'>('USER');
  const [createMustReset, setCreateMustReset] = useState(true);
  const [createActive, setCreateActive] = useState(true);

  const [impersonateTarget, setImpersonateTarget] = useState<AdminUser | null>(null);
  const [resetPasswordLoadingId, setResetPasswordLoadingId] = useState<string | null>(null);
  const [resetPasswordResult, setResetPasswordResult] = useState<{ email: string; tempPassword: string } | null>(null);

  const [loginRateLimitLoading, setLoginRateLimitLoading] = useState(false);
  const [loginRateLimitSaving, setLoginRateLimitSaving] = useState(false);
  const [loginRateLimitEnabled, setLoginRateLimitEnabled] = useState(true);
  const [loginRateLimitWindowMinutes, setLoginRateLimitWindowMinutes] = useState(15);
  const [loginRateLimitMax, setLoginRateLimitMax] = useState(20);
  const [resetIdentifier, setResetIdentifier] = useState('');
  const [resetLoading, setResetLoading] = useState(false);

  const impersonation = useMemo(() => {
    if (!authEnabled) return null;
    return readImpersonationState();
  }, [authEnabled]);

  useEffect(() => {
    if (authEnabled === false) {
      navigate('/settings', { replace: true });
      return;
    }
    if (authEnabled && !isAdmin) {
      navigate('/', { replace: true });
      return;
    }
  }, [authEnabled, isAdmin, navigate]);

  const loadCollections = async () => {
    try {
      const data = await api.getCollections();
      setCollections(data);
    } catch (err) {
      console.error('Failed to fetch collections:', err);
    }
  };

  const loadUsers = async () => {
    setLoadingUsers(true);
    setError('');
    try {
      const response = await api.api.get<{ users: AdminUser[] }>('/auth/users');
      setUsers(response.data.users || []);
    } catch (err: unknown) {
      let message = 'Failed to load users';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    } finally {
      setLoadingUsers(false);
    }
  };

  const generateTempPassword = async (target: AdminUser) => {
    setResetPasswordLoadingId(target.id);
    setError('');
    setSuccess('');
    try {
      const response = await api.api.post<{ tempPassword: string; user: { id: string; email: string } }>(
        `/auth/users/${target.id}/reset-password`
      );
      setResetPasswordResult({ email: response.data.user?.email || target.email, tempPassword: response.data.tempPassword });
      setSuccess(`Temporary password generated for ${target.email}`);
      await loadUsers();
    } catch (err: unknown) {
      let message = 'Failed to reset password';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    } finally {
      setResetPasswordLoadingId(null);
    }
  };

  const loadLoginRateLimitConfig = async () => {
    setLoginRateLimitLoading(true);
    setError('');
    try {
      const response = await api.api.get<{
        config: { enabled: boolean; windowMs: number; max: number };
      }>('/auth/rate-limit/login');
      const cfg = response.data.config;
      setLoginRateLimitEnabled(Boolean(cfg.enabled));
      setLoginRateLimitMax(Number(cfg.max));
      setLoginRateLimitWindowMinutes(Math.max(1, Math.round(Number(cfg.windowMs) / 60000)));
    } catch (err: unknown) {
      let message = 'Failed to load rate limit config';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    } finally {
      setLoginRateLimitLoading(false);
    }
  };

  const saveLoginRateLimitConfig = async () => {
    setLoginRateLimitSaving(true);
    setError('');
    setSuccess('');
    try {
      const payload = {
        enabled: loginRateLimitEnabled,
        windowMs: Math.max(10_000, Math.round(loginRateLimitWindowMinutes * 60_000)),
        max: Math.max(1, Math.round(loginRateLimitMax)),
      };
      const response = await api.api.put<{
        config: { enabled: boolean; windowMs: number; max: number };
      }>('/auth/rate-limit/login', payload);

      const cfg = response.data.config;
      setLoginRateLimitEnabled(Boolean(cfg.enabled));
      setLoginRateLimitMax(Number(cfg.max));
      setLoginRateLimitWindowMinutes(Math.max(1, Math.round(Number(cfg.windowMs) / 60000)));
      setSuccess('Login rate limit updated');
    } catch (err: unknown) {
      let message = 'Failed to save rate limit config';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    } finally {
      setLoginRateLimitSaving(false);
    }
  };

  const resetLoginRateLimit = async () => {
    const identifier = resetIdentifier.trim();
    if (!identifier) {
      setError('Enter an email/username to reset');
      return;
    }
    setResetLoading(true);
    setError('');
    setSuccess('');
    try {
      await api.api.post('/auth/rate-limit/login/reset', { identifier });
      setSuccess(`Reset login rate limit for ${identifier}`);
      setResetIdentifier('');
    } catch (err: unknown) {
      let message = 'Failed to reset rate limit';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    } finally {
      setResetLoading(false);
    }
  };

  useEffect(() => {
    if (!authEnabled || !isAdmin) return;
    void loadCollections();
    void loadUsers();
    void loadLoginRateLimitConfig();
  }, [authEnabled, isAdmin]);

  const handleSelectCollection = (id: string | null | undefined) => {
    if (id === undefined) navigate('/');
    else if (id === null) navigate('/collections?id=unorganized');
    else navigate(`/collections?id=${id}`);
  };

  const handleCreateCollection = async (name: string) => {
    await api.createCollection(name);
    const newCollections = await api.getCollections();
    setCollections(newCollections);
  };

  const handleEditCollection = async (id: string, name: string) => {
    setCollections(prev => prev.map(c => (c.id === id ? { ...c, name } : c)));
    await api.updateCollection(id, name);
  };

  const handleDeleteCollection = async (id: string) => {
    setCollections(prev => prev.filter(c => c.id !== id));
    await api.deleteCollection(id);
  };

  const handleCreateUser = async (e: React.FormEvent) => {
    e.preventDefault();
    setError('');
    setSuccess('');

    try {
      const payload = {
        email: createEmail.trim().toLowerCase(),
        name: createName.trim(),
        username: createUsername.trim() ? createUsername.trim() : undefined,
        password: createPassword,
        role: createRole,
        mustResetPassword: createMustReset,
        isActive: createActive,
      };

      const response = await api.api.post<{ user: AdminUser }>('/auth/users', payload);
      setUsers(prev => [...prev, response.data.user].sort((a, b) => a.createdAt.localeCompare(b.createdAt)));
      setSuccess('User created');
      setCreateEmail('');
      setCreateName('');
      setCreateUsername('');
      setCreatePassword('');
      setCreateRole('USER');
      setCreateMustReset(true);
      setCreateActive(true);
      setCreateOpen(false);
    } catch (err: unknown) {
      let message = 'Failed to create user';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    }
  };

  const patchUser = async (id: string, data: Partial<Pick<AdminUser, 'username' | 'name' | 'role' | 'mustResetPassword' | 'isActive'>>) => {
    setError('');
    setSuccess('');
    try {
      const response = await api.api.patch<{ user: AdminUser }>(`/auth/users/${id}`, data);
      setUsers(prev => prev.map(u => (u.id === id ? response.data.user : u)));
      setSuccess('User updated');
    } catch (err: unknown) {
      let message = 'Failed to update user';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    }
  };

  const startImpersonation = async (target: AdminUser) => {
    setError('');
    setSuccess('');

    if (readImpersonationState()) {
      setError('Stop the current impersonation before starting a new one.');
      return;
    }

    const originalAccessToken = localStorage.getItem(ACCESS_TOKEN_KEY);
    const originalRefreshToken = localStorage.getItem(REFRESH_TOKEN_KEY);
    const originalUser = localStorage.getItem(USER_KEY);
    if (!originalAccessToken || !originalRefreshToken || !originalUser) {
      setError('Missing current session tokens.');
      return;
    }

    try {
      const response = await api.api.post<{
        user: { id: string; email: string; name: string };
        accessToken: string;
        refreshToken: string;
      }>('/auth/impersonate', { userId: target.id });

      const state: ImpersonationState = {
        original: {
          accessToken: originalAccessToken,
          refreshToken: originalRefreshToken,
          user: JSON.parse(originalUser),
        },
        impersonator: {
          id: authUser?.id || 'unknown',
          email: authUser?.email || 'unknown',
          name: authUser?.name || 'Unknown Admin',
        },
        target: {
          id: response.data.user.id,
          email: response.data.user.email,
          name: response.data.user.name,
        },
        startedAt: new Date().toISOString(),
      };

      localStorage.setItem(IMPERSONATION_KEY, JSON.stringify(state));
      localStorage.setItem(ACCESS_TOKEN_KEY, response.data.accessToken);
      localStorage.setItem(REFRESH_TOKEN_KEY, response.data.refreshToken);
      localStorage.setItem(USER_KEY, JSON.stringify(response.data.user));

      window.location.href = '/';
    } catch (err: unknown) {
      let message = 'Failed to impersonate user';
      if (api.isAxiosError(err)) {
        message = err.response?.data?.message || err.response?.data?.error || message;
      }
      setError(message);
    }
  };

  const stopImpersonation = () => {
    if (!restoreImpersonation()) return;
    window.location.href = '/admin';
  };

  if (authEnabled === null) {
    return (
      <div className="min-h-screen flex items-center justify-center">
        <div className="text-gray-600 dark:text-gray-400">Loading...</div>
      </div>
    );
  }

  return (
    <Layout
      collections={collections}
      selectedCollectionId="ADMIN"
      onSelectCollection={handleSelectCollection}
      onCreateCollection={handleCreateCollection}
      onEditCollection={handleEditCollection}
      onDeleteCollection={handleDeleteCollection}
    >
      <div className="flex flex-col sm:flex-row sm:items-start justify-between gap-4 mb-6 sm:mb-8 min-w-0">
        <div className="min-w-0">
          <h1 className="text-3xl sm:text-5xl text-slate-900 dark:text-white pl-1" style={{ fontFamily: 'Excalifont' }}>
            Admin
          </h1>
          <p className="mt-2 text-sm text-slate-600 dark:text-neutral-400 font-medium">
            User management and impersonation
          </p>
        </div>

        <div className="flex items-center gap-2 flex-wrap">
          <button
            onClick={() => loadUsers()}
            disabled={loadingUsers}
            className="inline-flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200 shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)] hover:-translate-y-0.5 transition-all disabled:opacity-60"
          >
            <RefreshCw size={16} />
            Refresh
          </button>
          <button
            onClick={() => setCreateOpen(v => !v)}
            className="inline-flex items-center gap-2 px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-indigo-600 text-white shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-0.5 transition-all"
          >
            <UserPlus size={16} />
            New User
          </button>
        </div>
      </div>

      {impersonation && (
        <div className="mb-6 p-4 bg-amber-50 dark:bg-amber-900/20 border-2 border-amber-200 dark:border-amber-800 rounded-xl flex items-start justify-between gap-4">
          <div>
            <div className="font-bold text-amber-900 dark:text-amber-200 flex items-center gap-2">
              <LogIn size={16} />
              Impersonating {impersonation.target.email}
            </div>
            <div className="text-sm text-amber-800 dark:text-amber-200/80 font-medium mt-1">
              Stop impersonation to return to {impersonation.impersonator.email}.
            </div>
          </div>
          <button
            onClick={stopImpersonation}
            className="inline-flex items-center gap-2 px-3 py-2 text-sm font-bold rounded-xl border-2 border-amber-300 dark:border-amber-700 bg-white dark:bg-neutral-900 text-amber-800 dark:text-amber-200 hover:bg-amber-100 dark:hover:bg-amber-900/30 transition-all"
          >
            <XCircle size={16} />
            Stop
          </button>
        </div>
      )}

      {success && (
        <div className="mb-6 p-4 bg-green-50 dark:bg-green-900/20 border-2 border-green-200 dark:border-green-800 rounded-xl">
          <p className="text-green-800 dark:text-green-200 font-medium">{success}</p>
        </div>
      )}
      {error && (
        <div className="mb-6 p-4 bg-red-50 dark:bg-red-900/20 border-2 border-red-200 dark:border-red-800 rounded-xl">
          <p className="text-red-800 dark:text-red-200 font-medium">{error}</p>
        </div>
      )}

      {createOpen && (
        <div className="mb-6 bg-white dark:bg-neutral-900 border-2 border-black dark:border-neutral-700 rounded-2xl shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] dark:shadow-[4px_4px_0px_0px_rgba(255,255,255,0.2)] p-4 sm:p-6">
          <div className="flex items-center gap-3 mb-4">
            <div className="w-12 h-12 bg-indigo-50 dark:bg-neutral-800 rounded-xl flex items-center justify-center border-2 border-indigo-100 dark:border-neutral-700">
              <UserCog size={24} className="text-indigo-600 dark:text-indigo-400" />
            </div>
            <h2 className="text-2xl font-bold text-slate-900 dark:text-white">Create User</h2>
          </div>

          <form onSubmit={handleCreateUser} className="grid grid-cols-1 md:grid-cols-2 gap-4">
            <div>
              <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Email</label>
              <input
                type="email"
                value={createEmail}
                onChange={e => setCreateEmail(e.target.value)}
                required
                className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
              />
            </div>

            <div>
              <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Name</label>
              <input
                type="text"
                value={createName}
                onChange={e => setCreateName(e.target.value)}
                required
                className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
              />
            </div>

            <div>
              <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Username (optional)</label>
              <input
                type="text"
                value={createUsername}
                onChange={e => setCreateUsername(e.target.value)}
                className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
              />
            </div>

            <div>
              <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Temporary Password</label>
              <input
                type="password"
                value={createPassword}
                onChange={e => setCreatePassword(e.target.value)}
                minLength={8}
                required
                className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
              />
            </div>

            <div>
              <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Role</label>
              <select
                value={createRole}
                onChange={e => setCreateRole(e.target.value as 'ADMIN' | 'USER')}
                className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
              >
                <option value="USER">USER</option>
                <option value="ADMIN">ADMIN</option>
              </select>
            </div>

            <div className="flex items-center gap-3 pt-8">
              <label className="inline-flex items-center gap-2 text-sm font-bold text-slate-700 dark:text-neutral-300">
                <input
                  type="checkbox"
                  checked={createMustReset}
                  onChange={e => setCreateMustReset(e.target.checked)}
                />
                Must reset password
              </label>
              <label className="inline-flex items-center gap-2 text-sm font-bold text-slate-700 dark:text-neutral-300">
                <input
                  type="checkbox"
                  checked={createActive}
                  onChange={e => setCreateActive(e.target.checked)}
                />
                Active
              </label>
            </div>

            <div className="md:col-span-2 flex items-center justify-end gap-3 pt-2">
              <button
                type="button"
                onClick={() => setCreateOpen(false)}
                className="px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200"
              >
                Cancel
              </button>
              <button
                type="submit"
                className="px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-indigo-600 text-white shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-0.5 transition-all"
              >
                Create
              </button>
            </div>
          </form>
        </div>
      )}

      <div className="mb-6 bg-white dark:bg-neutral-900 border-2 border-black dark:border-neutral-700 rounded-2xl shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] dark:shadow-[4px_4px_0px_0px_rgba(255,255,255,0.2)] p-4 sm:p-6">
        <div className="flex items-center gap-3 mb-4">
          <div className="w-12 h-12 bg-slate-50 dark:bg-neutral-800 rounded-xl flex items-center justify-center border-2 border-slate-200 dark:border-neutral-700">
            <SettingsIcon size={24} className="text-slate-700 dark:text-neutral-200" />
          </div>
          <div className="min-w-0">
            <h2 className="text-2xl font-bold text-slate-900 dark:text-white">Login Rate Limiting</h2>
            <p className="text-sm text-slate-600 dark:text-neutral-400 font-medium">
              Reduce brute-force attacks; disable only for trusted environments.
            </p>
          </div>
          {loginRateLimitLoading && (
            <span className="ml-auto text-sm text-slate-500 dark:text-neutral-500 font-medium">Loading…</span>
          )}
        </div>

        <div className="grid grid-cols-1 lg:grid-cols-3 gap-4">
          <div className="flex items-center gap-3 pt-1">
            <label className="inline-flex items-center gap-2 text-sm font-bold text-slate-700 dark:text-neutral-300">
              <input
                type="checkbox"
                checked={loginRateLimitEnabled}
                onChange={e => setLoginRateLimitEnabled(e.target.checked)}
              />
              Enabled
            </label>
          </div>
          <div>
            <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Window (minutes)</label>
            <input
              type="number"
              min={1}
              value={loginRateLimitWindowMinutes}
              onChange={e => setLoginRateLimitWindowMinutes(Number(e.target.value))}
              className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
            />
          </div>
          <div>
            <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">Max attempts</label>
            <input
              type="number"
              min={1}
              value={loginRateLimitMax}
              onChange={e => setLoginRateLimitMax(Number(e.target.value))}
              className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
            />
          </div>
        </div>

        <div className="mt-4 flex flex-col lg:flex-row lg:items-end justify-between gap-4">
          <div className="min-w-0 flex-1">
            <label className="block text-sm font-bold text-slate-700 dark:text-neutral-300 mb-2">
              Reset lockout (email/username)
            </label>
            <input
              list="admin-user-identifiers"
              value={resetIdentifier}
              onChange={e => setResetIdentifier(e.target.value)}
              placeholder="user@example.com"
              className="w-full px-4 py-3 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl text-slate-900 dark:text-white outline-none"
            />
            <datalist id="admin-user-identifiers">
              {users.map(u => (
                <option key={u.id} value={u.email} />
              ))}
            </datalist>
          </div>
          <div className="flex items-center gap-3 flex-shrink-0">
            <button
              onClick={() => void resetLoginRateLimit()}
              disabled={resetLoading}
              className="px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200 shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)] hover:-translate-y-0.5 transition-all disabled:opacity-60"
            >
              {resetLoading ? 'Resetting…' : 'Reset'}
            </button>
            <button
              onClick={() => void saveLoginRateLimitConfig()}
              disabled={loginRateLimitSaving}
              className="px-4 py-2 text-sm font-bold rounded-xl border-2 border-black dark:border-neutral-700 bg-indigo-600 text-white shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] hover:-translate-y-0.5 transition-all disabled:opacity-60"
            >
              {loginRateLimitSaving ? 'Saving…' : 'Save'}
            </button>
          </div>
        </div>
      </div>

      <div className="bg-white dark:bg-neutral-900 border-2 border-black dark:border-neutral-700 rounded-2xl shadow-[4px_4px_0px_0px_rgba(0,0,0,1)] dark:shadow-[4px_4px_0px_0px_rgba(255,255,255,0.2)] overflow-hidden">
        <div className="px-4 sm:px-6 py-4 border-b-2 border-slate-200 dark:border-neutral-700 flex items-center gap-3">
          <div className="w-10 h-10 bg-indigo-50 dark:bg-neutral-800 rounded-xl flex items-center justify-center border-2 border-indigo-100 dark:border-neutral-700">
            <Shield size={20} className="text-indigo-600 dark:text-indigo-400" />
          </div>
          <h2 className="text-xl font-bold text-slate-900 dark:text-white">Users</h2>
          {loadingUsers && <span className="text-sm text-slate-500 dark:text-neutral-500 font-medium">Loading…</span>}
        </div>

        <div className="overflow-x-auto">
          <table className="min-w-full text-sm">
            <thead className="bg-slate-50 dark:bg-neutral-800/70">
              <tr className="text-left">
                <th className="px-4 sm:px-6 py-3 font-bold text-slate-600 dark:text-neutral-300">User</th>
                <th className="px-4 sm:px-6 py-3 font-bold text-slate-600 dark:text-neutral-300">Role</th>
                <th className="px-4 sm:px-6 py-3 font-bold text-slate-600 dark:text-neutral-300">Active</th>
                <th className="px-4 sm:px-6 py-3 font-bold text-slate-600 dark:text-neutral-300">Must Reset</th>
                <th className="px-4 sm:px-6 py-3 font-bold text-slate-600 dark:text-neutral-300">Actions</th>
              </tr>
            </thead>
            <tbody>
              {users.map(u => (
                <tr key={u.id} className="border-t border-slate-100 dark:border-neutral-800">
                  <td className="px-4 sm:px-6 py-4 min-w-[220px]">
                    <div className="font-bold text-slate-900 dark:text-white truncate">{u.name}</div>
                    <div className="text-slate-500 dark:text-neutral-400 truncate">{u.email}</div>
                    {u.username && <div className="text-xs text-slate-400 dark:text-neutral-500">@{u.username}</div>}
                  </td>
                  <td className="px-4 sm:px-6 py-4">
                    <select
                      value={u.role}
                      onChange={e => patchUser(u.id, { role: e.target.value })}
                      disabled={u.id === authUser?.id}
                      className="px-3 py-2 bg-white dark:bg-neutral-800 border-2 border-slate-200 dark:border-neutral-700 rounded-xl font-bold text-slate-900 dark:text-white"
                    >
                      <option value="USER">USER</option>
                      <option value="ADMIN">ADMIN</option>
                    </select>
                  </td>
                  <td className="px-4 sm:px-6 py-4">
                    <button
                      onClick={() => patchUser(u.id, { isActive: !u.isActive })}
                      disabled={u.id === authUser?.id}
                      className={`inline-flex items-center gap-2 px-3 py-2 rounded-xl border-2 font-bold ${
                        u.isActive
                          ? 'border-emerald-300 dark:border-emerald-700 bg-emerald-50 dark:bg-emerald-900/20 text-emerald-700 dark:text-emerald-300'
                          : 'border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-600 dark:text-neutral-300'
                      }`}
                    >
                      {u.isActive ? 'Active' : 'Inactive'}
                    </button>
                  </td>
                  <td className="px-4 sm:px-6 py-4">
                    <button
                      onClick={() => patchUser(u.id, { mustResetPassword: !u.mustResetPassword })}
                      className={`inline-flex items-center gap-2 px-3 py-2 rounded-xl border-2 font-bold ${
                        u.mustResetPassword
                          ? 'border-amber-300 dark:border-amber-700 bg-amber-50 dark:bg-amber-900/20 text-amber-800 dark:text-amber-200'
                          : 'border-slate-200 dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-600 dark:text-neutral-300'
                      }`}
                    >
                      {u.mustResetPassword ? 'Yes' : 'No'}
                    </button>
                  </td>
                  <td className="px-4 sm:px-6 py-4">
                    <div className="flex flex-wrap items-center gap-2">
                      <button
                        onClick={() => setImpersonateTarget(u)}
                        className="inline-flex items-center gap-2 px-3 py-2 rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200 font-bold shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)] hover:-translate-y-0.5 transition-all"
                      >
                        <LogIn size={16} />
                        Impersonate
                      </button>
                      <button
                        onClick={() => void generateTempPassword(u)}
                        disabled={u.id === authUser?.id || resetPasswordLoadingId === u.id}
                        className="inline-flex items-center gap-2 px-3 py-2 rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 text-slate-900 dark:text-neutral-200 font-bold shadow-[2px_2px_0px_0px_rgba(0,0,0,1)] dark:shadow-[2px_2px_0px_0px_rgba(255,255,255,0.2)] hover:-translate-y-0.5 transition-all disabled:opacity-60 disabled:hover:translate-y-0"
                        title={u.id === authUser?.id ? 'Use Profile → Change Password for your own account' : 'Generate a temporary password'}
                      >
                        <KeyRound size={16} />
                        {resetPasswordLoadingId === u.id ? 'Generating…' : 'Reset Password'}
                      </button>
                    </div>
                  </td>
                </tr>
              ))}
              {users.length === 0 && !loadingUsers && (
                <tr>
                  <td colSpan={5} className="px-6 py-6 text-slate-500 dark:text-neutral-500 font-medium">
                    No users found.
                  </td>
                </tr>
              )}
            </tbody>
          </table>
        </div>
      </div>

      <ConfirmModal
        isOpen={!!impersonateTarget}
        title="Start impersonation?"
        message={
          impersonateTarget
            ? `You will act as ${impersonateTarget.email} until you stop impersonation. Continue?`
            : ''
        }
        confirmText="Impersonate"
        onConfirm={() => {
          if (impersonateTarget) {
            void startImpersonation(impersonateTarget);
          }
          setImpersonateTarget(null);
        }}
        onCancel={() => setImpersonateTarget(null)}
      />

      <ConfirmModal
        isOpen={!!resetPasswordResult}
        title="Temporary password"
        message={
          resetPasswordResult ? (
            <div className="space-y-3">
              <div className="text-xs">
                Temporary password for <span className="font-bold text-slate-900 dark:text-neutral-100">{resetPasswordResult.email}</span>. They will be prompted to set a new password after signing in.
              </div>
              <div className="px-3 py-2 rounded-xl border-2 border-black dark:border-neutral-700 bg-white dark:bg-neutral-900 font-mono text-sm text-slate-900 dark:text-neutral-100 break-all">
                {resetPasswordResult.tempPassword}
              </div>
            </div>
          ) : (
            ''
          )
        }
        confirmText="Copy"
        cancelText="Close"
        isDangerous={false}
        variant="success"
        onConfirm={() => {
          if (!resetPasswordResult) return;
          void navigator.clipboard?.writeText(resetPasswordResult.tempPassword);
          setResetPasswordResult(null);
        }}
        onCancel={() => setResetPasswordResult(null)}
      />
    </Layout>
  );
};
