'use client'

/**
 * User detail drawer — opened from a Team members row. Five tabs:
 *
 *   Overview     — identity, role, status, lifecycle facts, content owned.
 *   Security     — MFA / password / lock state + admin security actions.
 *   Sessions     — active sessions with per-session + bulk revoke.
 *   Activity     — recent audit events where the user is actor or target.
 *   Permissions  — read-only effective role + permission scopes.
 *
 * Every mutating action is permission-checked and audited server-side. The
 * high-impact ones (MFA reset, Admin/Owner password reset) return a 401
 * "reauth required" which this component handles by prompting for the admin's
 * password and retrying with the `x-reauth-password` header.
 */
import * as Tabs from '@radix-ui/react-tabs'
import {
  ShieldCheck,
  ShieldAlert,
  KeyRound,
  Lock,
  Unlock,
  Ban,
  Monitor,
  LogOut,
  Activity as ActivityIcon,
  FileText,
  AlertTriangle,
  Check,
} from 'lucide-react'
import { useCallback, useState, type ReactNode } from 'react'
import { toast } from 'sonner'
import { cmsApi } from '../../lib/api.js'
import { useApiData } from '../../lib/useApiData.js'
import { Drawer } from '../../components/forms/Drawer.js'
import { Modal } from '../../components/ui/Modal.js'
import { Button } from '../../components/ui/Button.js'
import { Skeleton } from '../../components/ui/Skeleton.js'
import { EmptyState } from '../../components/ui/EmptyState.js'
import { ConfirmDialog } from '../../components/ui/ConfirmDialog.js'

// ---------------------------------------------------------------------------
// Types (mirror cms-core serialized shapes)
// ---------------------------------------------------------------------------

interface UserDetail {
  id: string
  name: string
  email: string
  avatarUrl: string | null
  initials: string
  role: string
  roleName: 'Owner' | 'Admin' | 'Editor' | 'Viewer'
  status: 'active' | 'suspended' | 'locked' | 'deactivated'
  mfaEnabled: boolean
  mfaRequired: boolean
  passwordSet: boolean
  forcePasswordReset: boolean
  failedLoginCount: number
  lockedAt: string | null
  suspendedAt: string | null
  authProvider: string | null
  oauthProviders: string[]
  ssoOnly: boolean
  emailVerified: boolean
  lastLoginAt: string | null
  lastActiveAt: string | null
  acceptedInviteAt: string | null
  createdAt: string
  invitedBy: { id: string; name: string; email: string } | null
  externalDomain: boolean
  contentOwnedCount: number
  isCurrentUser: boolean
}

interface SessionInfo {
  id: string
  deviceLabel: string
  browser: string
  os: string
  ipCountry: string | null
  createdAt: string
  lastSeenAt: string
  expiresAt: string
  revokedAt: string | null
  current: boolean
  active: boolean
}

interface ActivityEvent {
  id: string
  event: string
  role: 'actor' | 'target'
  ipAddress: string | null
  timestamp: string
  details: Record<string, unknown> | null
}

interface PermissionView {
  role: string
  roleName: string
  permissions: string[]
}

// ---------------------------------------------------------------------------
// Formatting helpers
// ---------------------------------------------------------------------------

function relativeTime(iso: string | null): string {
  if (!iso) return 'Never'
  const then = new Date(iso).getTime()
  if (Number.isNaN(then)) return '—'
  const diffMs = Date.now() - then
  const mins = Math.floor(diffMs / 60000)
  if (mins < 5) return 'Just now'
  if (mins < 60) return `${mins}m ago`
  const hours = Math.floor(mins / 60)
  if (hours < 24) return `${hours}h ago`
  const days = Math.floor(hours / 24)
  if (days === 1) return 'Yesterday'
  return `${days} days ago`
}

function formatDate(iso: string | null): string {
  if (!iso) return '—'
  const d = new Date(iso)
  if (Number.isNaN(d.getTime())) return '—'
  return d.toLocaleDateString(undefined, { year: 'numeric', month: 'short', day: 'numeric' })
}

function humanizeEvent(event: string): string {
  return event.replace(/_/g, ' ').replace(/^\w/, (c) => c.toUpperCase())
}

const ROLE_PILL: Record<string, string> = {
  Owner: 'bg-brand/10 text-brand',
  Admin: 'bg-info/10 text-info',
  Editor: 'bg-accent text-accent-foreground',
  Viewer: 'bg-muted text-muted-foreground',
}

const STATUS_META: Record<UserDetail['status'], { dot: string; text: string; label: string }> = {
  active: { dot: 'bg-success', text: 'text-success', label: 'Active' },
  suspended: { dot: 'bg-muted-foreground', text: 'text-muted-foreground', label: 'Suspended' },
  locked: { dot: 'bg-destructive', text: 'text-destructive', label: 'Locked' },
  deactivated: {
    dot: 'bg-muted-foreground',
    text: 'text-muted-foreground',
    label: 'Deactivated',
  },
}

// ---------------------------------------------------------------------------
// Reauth dialog
// ---------------------------------------------------------------------------

function ReauthDialog({
  open,
  onClose,
  onSubmit,
}: {
  open: boolean
  onClose: () => void
  onSubmit: (password: string) => Promise<void>
}) {
  const [password, setPassword] = useState('')
  const [busy, setBusy] = useState(false)

  const submit = async () => {
    if (!password || busy) return
    setBusy(true)
    try {
      await onSubmit(password)
      setPassword('')
    } finally {
      setBusy(false)
    }
  }

  return (
    <Modal
      open={open}
      onClose={() => {
        setPassword('')
        onClose()
      }}
      title="Confirm it's you"
      actions={
        <>
          <Button
            variant="ghost"
            onClick={() => {
              setPassword('')
              onClose()
            }}
          >
            Cancel
          </Button>
          <Button variant="primary" loading={busy} disabled={!password || busy} onClick={submit}>
            Confirm
          </Button>
        </>
      }
    >
      <p className="text-muted-foreground mb-3 text-sm">
        This is a sensitive action. Re-enter your password to continue.
      </p>
      <label
        htmlFor="reauth-password"
        className="text-card-foreground mb-1 block text-sm font-medium"
      >
        Your password
      </label>
      <input
        id="reauth-password"
        type="password"
        value={password}
        onChange={(e) => setPassword(e.target.value)}
        onKeyDown={(e) => {
          if (e.key === 'Enter') submit()
        }}
        autoComplete="current-password"
        className="border-border bg-input-background text-foreground focus:ring-brand w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
      />
    </Modal>
  )
}

// ---------------------------------------------------------------------------
// Transfer content modal
// ---------------------------------------------------------------------------

interface TransferMember {
  id: string
  name: string
  email: string
  status: string
  isCurrentUser: boolean
}

function TransferContentModal({
  open,
  onClose,
  fromUser,
  onTransferred,
}: {
  open: boolean
  onClose: () => void
  fromUser: { id: string; name: string; contentOwnedCount: number }
  onTransferred: () => void
}) {
  // Only fetch the directory while the picker is open.
  const members = useApiData<TransferMember[]>(open ? '/users' : null)
  const [toUserId, setToUserId] = useState('')
  const [busy, setBusy] = useState(false)

  const recipients = (members.data ?? []).filter(
    (m) => m.id !== fromUser.id && m.status === 'active',
  )

  const submit = async () => {
    if (!toUserId || busy) return
    setBusy(true)
    try {
      const res = await cmsApi<{
        documents: number
        media: number
        templates: number
        total: number
      }>(`/users/${fromUser.id}/transfer-content`, {
        method: 'POST',
        body: JSON.stringify({ toUserId }),
      })
      if (res.error) {
        toast.error(res.error)
        return
      }
      const c = res.data
      toast.success(
        c && c.total > 0
          ? `Transferred ${c.total} item${c.total === 1 ? '' : 's'} (${c.documents} docs, ${c.media} media, ${c.templates} templates).`
          : 'Nothing to transfer.',
      )
      setToUserId('')
      onClose()
      onTransferred()
    } finally {
      setBusy(false)
    }
  }

  return (
    <Modal
      open={open}
      onClose={() => {
        setToUserId('')
        onClose()
      }}
      title="Transfer content ownership"
      actions={
        <>
          <Button
            variant="ghost"
            onClick={() => {
              setToUserId('')
              onClose()
            }}
          >
            Cancel
          </Button>
          <Button variant="primary" loading={busy} disabled={!toUserId || busy} onClick={submit}>
            Transfer
          </Button>
        </>
      }
    >
      <p className="text-muted-foreground mb-3 text-sm">
        Reassign {fromUser.name}&apos;s authored documents, uploaded media, and templates to another
        active member. Version history and audit records are left unchanged.
      </p>
      <label htmlFor="transfer-to" className="text-card-foreground mb-1 block text-sm font-medium">
        Transfer to
      </label>
      {members.loading ? (
        <Skeleton variant="table-row" lines={1} />
      ) : recipients.length === 0 ? (
        <p className="text-muted-foreground text-sm">
          No other active members to receive the content.
        </p>
      ) : (
        <select
          id="transfer-to"
          value={toUserId}
          onChange={(e) => setToUserId(e.target.value)}
          className="border-border bg-input-background text-foreground focus:ring-brand w-full rounded-md border px-3 py-2 text-sm focus:ring-2 focus:outline-none"
        >
          <option value="">Select a member…</option>
          {recipients.map((m) => (
            <option key={m.id} value={m.id}>
              {m.name} ({m.email})
            </option>
          ))}
        </select>
      )}
    </Modal>
  )
}

// ---------------------------------------------------------------------------
// Small presentational bits
// ---------------------------------------------------------------------------

function Fact({ label, value }: { label: string; value: ReactNode }) {
  return (
    <div className="min-w-0">
      <dt className="text-muted-foreground text-xs">{label}</dt>
      <dd className="text-card-foreground mt-0.5 truncate text-sm">{value}</dd>
    </div>
  )
}

function SecurityRow({
  icon,
  title,
  description,
  action,
}: {
  icon: ReactNode
  title: string
  description: string
  action: ReactNode
}) {
  return (
    <div className="border-border flex items-center justify-between gap-3 border-b py-3 last:border-b-0">
      <div className="flex min-w-0 items-start gap-2.5">
        <span className="text-muted-foreground mt-0.5 shrink-0">{icon}</span>
        <div className="min-w-0">
          <div className="text-card-foreground text-sm font-medium">{title}</div>
          <div className="text-muted-foreground text-xs">{description}</div>
        </div>
      </div>
      <div className="shrink-0">{action}</div>
    </div>
  )
}

// ---------------------------------------------------------------------------
// Drawer
// ---------------------------------------------------------------------------

const TABS = [
  { id: 'overview', label: 'Overview' },
  { id: 'security', label: 'Security' },
  { id: 'sessions', label: 'Sessions' },
  { id: 'activity', label: 'Activity' },
  { id: 'permissions', label: 'Permissions' },
] as const

export interface UserDetailDrawerProps {
  userId: string | null
  open: boolean
  onOpenChange: (open: boolean) => void
  /** Refetch the parent table after any change to this user. */
  onChanged?: () => void
}

export function UserDetailDrawer({ userId, open, onOpenChange, onChanged }: UserDetailDrawerProps) {
  const [tab, setTab] = useState<string>('overview')

  const detailEp = open && userId ? `/users/${userId}` : null
  const detail = useApiData<UserDetail>(detailEp)

  const sessionsEp = open && userId && tab === 'sessions' ? `/users/${userId}/sessions` : null
  const sessions = useApiData<SessionInfo[]>(sessionsEp)

  const activityEp = open && userId && tab === 'activity' ? `/users/${userId}/activity` : null
  const activity = useApiData<ActivityEvent[]>(activityEp)

  const permsEp = open && userId && tab === 'permissions' ? `/users/${userId}/permissions` : null
  const perms = useApiData<PermissionView>(permsEp)

  const [reauth, setReauth] = useState<{ run: (password: string) => Promise<void> } | null>(null)
  const [confirm, setConfirm] = useState<{
    title: string
    description: string
    confirmLabel: string
    destructive?: boolean
    onConfirm: () => void
  } | null>(null)
  const [pending, setPending] = useState<string | null>(null)
  const [showTransfer, setShowTransfer] = useState(false)

  const refreshAfterChange = useCallback(() => {
    detail.refetch()
    onChanged?.()
  }, [detail, onChanged])

  /**
   * Run a mutating action. If the server demands reauthentication (401), prompt
   * for the password and retry once with the `x-reauth-password` header.
   */
  const runAction = useCallback(
    async (
      key: string,
      path: string,
      options: RequestInit,
      { successMsg, after }: { successMsg: string; after?: () => void },
    ) => {
      setPending(key)
      try {
        const res = await cmsApi(path, options)
        if (res.status === 401 && /re-?authenticat/i.test(res.error ?? '')) {
          setReauth({
            run: async (password: string) => {
              const retry = await cmsApi(path, {
                ...options,
                headers: { ...(options.headers ?? {}), 'x-reauth-password': password },
              })
              if (retry.error) {
                toast.error(retry.error)
                return
              }
              toast.success(successMsg)
              setReauth(null)
              after?.()
            },
          })
          return
        }
        if (res.error) {
          toast.error(res.error)
          return
        }
        toast.success(successMsg)
        after?.()
      } finally {
        setPending(null)
      }
    },
    [],
  )

  const u = detail.data

  return (
    <>
      <Drawer
        open={open}
        onOpenChange={onOpenChange}
        width="max-w-xl"
        title={u ? u.name : detail.loading ? 'Loading…' : 'User'}
        description={u?.email}
        headerExtra={
          u ? (
            <span
              className={`mr-1 inline-flex items-center rounded-full px-2 py-0.5 text-xs font-medium ${
                ROLE_PILL[u.roleName] ?? ROLE_PILL.Viewer
              }`}
            >
              {u.roleName}
            </span>
          ) : undefined
        }
      >
        {detail.loading ? (
          <div className="space-y-3">
            <Skeleton variant="card" />
            <Skeleton variant="table-row" lines={4} />
          </div>
        ) : detail.error || !u ? (
          <div className="flex items-center gap-3 py-6">
            <AlertTriangle size={18} className="text-destructive shrink-0" aria-hidden />
            <span className="text-destructive flex-1 text-sm">
              {detail.error ?? 'User not found.'}
            </span>
            <Button variant="outline" size="sm" onClick={() => detail.refetch()}>
              Retry
            </Button>
          </div>
        ) : (
          <Tabs.Root value={tab} onValueChange={setTab}>
            <Tabs.List
              className="border-border mb-4 flex gap-1 overflow-x-auto border-b"
              aria-label="User detail sections"
            >
              {TABS.map((t) => (
                <Tabs.Trigger
                  key={t.id}
                  value={t.id}
                  className="text-muted-foreground hover:text-foreground data-[state=active]:text-foreground data-[state=active]:border-brand focus-visible:ring-ring -mb-px shrink-0 border-b-2 border-transparent px-3 py-2 text-sm font-medium transition-colors focus-visible:ring-2 focus-visible:outline-none"
                >
                  {t.label}
                </Tabs.Trigger>
              ))}
            </Tabs.List>

            {/* Overview ----------------------------------------------------- */}
            <Tabs.Content value="overview" tabIndex={-1} className="focus:outline-none">
              <div className="mb-4 flex items-center gap-2">
                <span
                  className={`inline-flex items-center gap-1.5 text-sm ${STATUS_META[u.status].text}`}
                >
                  <span
                    className={`h-2 w-2 rounded-full ${STATUS_META[u.status].dot}`}
                    aria-hidden
                  />
                  {STATUS_META[u.status].label}
                </span>
                {u.isCurrentUser && (
                  <span className="bg-muted text-muted-foreground rounded px-1.5 py-0.5 text-xs">
                    You
                  </span>
                )}
                {u.externalDomain && (
                  <span className="bg-warning/10 text-warning rounded px-1.5 py-0.5 text-xs">
                    External domain
                  </span>
                )}
              </div>
              <dl className="grid grid-cols-2 gap-x-4 gap-y-4">
                <Fact label="Role" value={u.roleName} />
                <Fact label="Status" value={STATUS_META[u.status].label} />
                <Fact label="Last active" value={relativeTime(u.lastActiveAt)} />
                <Fact label="Last sign-in" value={relativeTime(u.lastLoginAt)} />
                <Fact label="Created" value={formatDate(u.createdAt)} />
                <Fact label="Accepted invite" value={formatDate(u.acceptedInviteAt)} />
                <Fact
                  label="Invited by"
                  value={
                    u.invitedBy ? (
                      u.invitedBy.name
                    ) : (
                      <span className="text-muted-foreground">—</span>
                    )
                  }
                />
                <Fact label="Email domain" value={u.email.split('@')[1] ?? '—'} />
                <Fact
                  label="Content owned"
                  value={`${u.contentOwnedCount} ${u.contentOwnedCount === 1 ? 'item' : 'items'}`}
                />
                <Fact
                  label="Email verified"
                  value={u.emailVerified ? 'Yes' : <span className="text-warning">No</span>}
                />
                {u.authProvider && <Fact label="Auth provider" value={u.authProvider} />}
                {u.oauthProviders.length > 0 && (
                  <Fact label="Connected accounts" value={u.oauthProviders.join(', ')} />
                )}
              </dl>
              {u.contentOwnedCount > 0 && (
                <div className="border-info/30 bg-info/5 mt-4 flex items-start gap-2 rounded-md border p-3">
                  <FileText size={14} className="text-info mt-0.5 shrink-0" aria-hidden />
                  <div className="min-w-0 flex-1">
                    <p className="text-muted-foreground text-xs">
                      This user owns {u.contentOwnedCount} content{' '}
                      {u.contentOwnedCount === 1 ? 'item' : 'items'}. Revoking access suspends the
                      account and preserves their content and authorship — or reassign it to another
                      member first.
                    </p>
                    <Button
                      size="sm"
                      variant="outline"
                      className="mt-2"
                      leftIcon={<FileText size={14} aria-hidden />}
                      onClick={() => setShowTransfer(true)}
                    >
                      Transfer content
                    </Button>
                  </div>
                </div>
              )}
            </Tabs.Content>

            {/* Security ----------------------------------------------------- */}
            <Tabs.Content value="security" tabIndex={-1} className="focus:outline-none">
              <SecurityRow
                icon={u.mfaEnabled ? <ShieldCheck size={16} /> : <ShieldAlert size={16} />}
                title="Multi-factor authentication"
                description={
                  u.mfaEnabled
                    ? 'Enabled for this account.'
                    : u.mfaRequired
                      ? 'Required but not yet enrolled.'
                      : 'Not enabled.'
                }
                action={
                  <div className="flex items-center gap-2">
                    {!u.mfaRequired && (
                      <Button
                        size="sm"
                        variant="outline"
                        loading={pending === 'require-mfa'}
                        onClick={() =>
                          runAction(
                            'require-mfa',
                            `/users/${u.id}/require-mfa`,
                            { method: 'POST', body: JSON.stringify({ required: true }) },
                            {
                              successMsg: 'MFA is now required for this user.',
                              after: refreshAfterChange,
                            },
                          )
                        }
                      >
                        Require MFA
                      </Button>
                    )}
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={!u.mfaEnabled}
                      title={!u.mfaEnabled ? 'No MFA enrolment to reset' : undefined}
                      loading={pending === 'mfa-reset'}
                      onClick={() =>
                        setConfirm({
                          title: 'Reset MFA enrolment',
                          description: `This clears ${u.name}'s authenticator and backup codes and signs them out everywhere. Resetting MFA temporarily lowers account protection until the user re-enrols. You'll be asked to confirm your password.`,
                          confirmLabel: 'Reset MFA',
                          destructive: true,
                          onConfirm: () =>
                            runAction(
                              'mfa-reset',
                              `/users/${u.id}/mfa-reset`,
                              { method: 'POST' },
                              { successMsg: 'MFA enrolment reset.', after: refreshAfterChange },
                            ),
                        })
                      }
                    >
                      Reset MFA
                    </Button>
                  </div>
                }
              />
              <SecurityRow
                icon={<KeyRound size={16} />}
                title="Password"
                description={
                  u.ssoOnly
                    ? 'Signs in via an external identity provider — no local password.'
                    : u.forcePasswordReset
                      ? 'Must set a new password on next sign-in.'
                      : u.passwordSet
                        ? 'A password is set.'
                        : 'No password set yet.'
                }
                action={
                  <div className="flex items-center gap-2">
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={u.ssoOnly || !u.passwordSet}
                      title={
                        u.ssoOnly ? 'External identity provider — no password to reset' : undefined
                      }
                      loading={pending === 'password-reset'}
                      onClick={() =>
                        runAction(
                          'password-reset',
                          `/users/${u.id}/password-reset`,
                          { method: 'POST' },
                          { successMsg: `Password reset email sent to ${u.email}.` },
                        )
                      }
                    >
                      Send reset
                    </Button>
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={u.ssoOnly}
                      loading={pending === 'force-reset'}
                      onClick={() =>
                        runAction(
                          'force-reset',
                          `/users/${u.id}/force-password-reset`,
                          {
                            method: 'POST',
                            body: JSON.stringify({ enabled: !u.forcePasswordReset }),
                          },
                          {
                            successMsg: u.forcePasswordReset
                              ? 'Forced reset cleared.'
                              : 'User must reset password on next sign-in.',
                            after: refreshAfterChange,
                          },
                        )
                      }
                    >
                      {u.forcePasswordReset ? 'Clear forced reset' : 'Force reset'}
                    </Button>
                  </div>
                }
              />
              <SecurityRow
                icon={<ShieldAlert size={16} />}
                title="Failed sign-ins"
                description={`${u.failedLoginCount} failed ${u.failedLoginCount === 1 ? 'attempt' : 'attempts'} on record.`}
                action={null}
              />
              <SecurityRow
                icon={u.status === 'locked' ? <Lock size={16} /> : <Unlock size={16} />}
                title="Account lock"
                description={
                  u.status === 'locked' ? 'Locked by a security policy or an admin.' : 'Not locked.'
                }
                action={
                  u.status === 'locked' ? (
                    <Button
                      size="sm"
                      variant="outline"
                      loading={pending === 'unlock'}
                      onClick={() =>
                        runAction(
                          'unlock',
                          `/users/${u.id}/unlock`,
                          { method: 'POST' },
                          { successMsg: 'Account unlocked.', after: refreshAfterChange },
                        )
                      }
                    >
                      Unlock
                    </Button>
                  ) : (
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={u.isCurrentUser}
                      title={u.isCurrentUser ? 'You cannot lock your own account' : undefined}
                      loading={pending === 'lock'}
                      onClick={() =>
                        setConfirm({
                          title: 'Lock account',
                          description: `${u.name} will be blocked from signing in and all their sessions will be revoked until you unlock the account.`,
                          confirmLabel: 'Lock account',
                          destructive: true,
                          onConfirm: () =>
                            runAction(
                              'lock',
                              `/users/${u.id}/lock`,
                              { method: 'POST' },
                              { successMsg: 'Account locked.', after: refreshAfterChange },
                            ),
                        })
                      }
                    >
                      Lock
                    </Button>
                  )
                }
              />
              <SecurityRow
                icon={<Ban size={16} />}
                title="Account access"
                description={
                  u.status === 'suspended'
                    ? 'Suspended — cannot sign in, history preserved.'
                    : 'Active — can sign in.'
                }
                action={
                  u.status === 'suspended' || u.status === 'deactivated' ? (
                    <Button
                      size="sm"
                      variant="outline"
                      loading={pending === 'reactivate'}
                      onClick={() =>
                        runAction(
                          'reactivate',
                          `/users/${u.id}/reactivate`,
                          { method: 'POST' },
                          { successMsg: 'Access restored.', after: refreshAfterChange },
                        )
                      }
                    >
                      Reactivate
                    </Button>
                  ) : (
                    <Button
                      size="sm"
                      variant="outline"
                      disabled={u.isCurrentUser}
                      title={u.isCurrentUser ? 'You cannot suspend your own account' : undefined}
                      loading={pending === 'suspend'}
                      onClick={() =>
                        setConfirm({
                          title: 'Suspend user',
                          description: `${u.name} will be blocked from signing in and signed out everywhere. Their content and history are preserved, and you can reactivate them later.`,
                          confirmLabel: 'Suspend',
                          destructive: true,
                          onConfirm: () =>
                            runAction(
                              'suspend',
                              `/users/${u.id}/suspend`,
                              { method: 'POST' },
                              { successMsg: 'User suspended.', after: refreshAfterChange },
                            ),
                        })
                      }
                    >
                      Suspend
                    </Button>
                  )
                }
              />
            </Tabs.Content>

            {/* Sessions ----------------------------------------------------- */}
            <Tabs.Content value="sessions" tabIndex={-1} className="focus:outline-none">
              {sessions.loading ? (
                <Skeleton variant="table-row" lines={3} />
              ) : sessions.error ? (
                <div className="flex items-center gap-3 py-4">
                  <AlertTriangle size={16} className="text-destructive shrink-0" aria-hidden />
                  <span className="text-destructive flex-1 text-sm">{sessions.error}</span>
                  <Button variant="outline" size="sm" onClick={() => sessions.refetch()}>
                    Retry
                  </Button>
                </div>
              ) : (sessions.data?.filter((s) => s.active).length ?? 0) === 0 ? (
                <EmptyState
                  icon={<Monitor size={24} aria-hidden />}
                  title="No active sessions"
                  description="This user isn't signed in on any device."
                />
              ) : (
                <>
                  <div className="mb-3 flex justify-end">
                    <Button
                      size="sm"
                      variant="outline"
                      loading={pending === 'revoke-all'}
                      leftIcon={<LogOut size={14} aria-hidden />}
                      onClick={() =>
                        setConfirm({
                          title: 'Revoke all sessions',
                          description: `${u.name} will be signed out of every device${
                            u.isCurrentUser ? ' except this one' : ''
                          }.`,
                          confirmLabel: 'Revoke all',
                          destructive: true,
                          onConfirm: () =>
                            runAction(
                              'revoke-all',
                              `/users/${u.id}/sessions/revoke-all`,
                              { method: 'POST' },
                              { successMsg: 'Sessions revoked.', after: () => sessions.refetch() },
                            ),
                        })
                      }
                    >
                      Revoke all
                    </Button>
                  </div>
                  <ul className="space-y-2">
                    {sessions.data
                      ?.filter((s) => s.active)
                      .map((s) => (
                        <li
                          key={s.id}
                          className="border-border flex items-center justify-between gap-3 rounded-md border p-3"
                        >
                          <div className="flex min-w-0 items-center gap-2.5">
                            <Monitor
                              size={16}
                              className="text-muted-foreground shrink-0"
                              aria-hidden
                            />
                            <div className="min-w-0">
                              <div className="text-card-foreground flex items-center gap-1.5 text-sm">
                                <span className="truncate">{s.deviceLabel}</span>
                                {s.current && (
                                  <span className="bg-success/10 text-success rounded px-1 text-[10px]">
                                    This device
                                  </span>
                                )}
                              </div>
                              <div className="text-muted-foreground text-xs">
                                Signed in {relativeTime(s.createdAt)} · expires{' '}
                                {formatDate(s.expiresAt)}
                              </div>
                            </div>
                          </div>
                          <button
                            type="button"
                            disabled={pending === `revoke-${s.id}`}
                            onClick={() =>
                              runAction(
                                `revoke-${s.id}`,
                                `/users/${u.id}/sessions/${s.id}`,
                                { method: 'DELETE' },
                                { successMsg: 'Session revoked.', after: () => sessions.refetch() },
                              )
                            }
                            className="text-muted-foreground hover:text-destructive shrink-0 text-xs font-medium transition-colors disabled:opacity-50"
                          >
                            Revoke
                          </button>
                        </li>
                      ))}
                  </ul>
                </>
              )}
            </Tabs.Content>

            {/* Activity ----------------------------------------------------- */}
            <Tabs.Content value="activity" tabIndex={-1} className="focus:outline-none">
              {activity.loading ? (
                <Skeleton variant="table-row" lines={4} />
              ) : activity.error ? (
                <div className="flex items-center gap-3 py-4">
                  <AlertTriangle size={16} className="text-destructive shrink-0" aria-hidden />
                  <span className="text-destructive flex-1 text-sm">{activity.error}</span>
                  <Button variant="outline" size="sm" onClick={() => activity.refetch()}>
                    Retry
                  </Button>
                </div>
              ) : (activity.data?.length ?? 0) === 0 ? (
                <EmptyState
                  icon={<ActivityIcon size={24} aria-hidden />}
                  title="No recent activity"
                  description="Audit events for this user will appear here."
                />
              ) : (
                <ul className="space-y-1">
                  {activity.data?.map((e) => (
                    <li
                      key={e.id}
                      className="hover:bg-accent/30 flex items-center justify-between gap-3 rounded-md px-2 py-2"
                    >
                      <div className="flex min-w-0 items-center gap-2.5">
                        <ActivityIcon
                          size={14}
                          className="text-muted-foreground shrink-0"
                          aria-hidden
                        />
                        <div className="min-w-0">
                          <div className="text-card-foreground truncate text-sm">
                            {humanizeEvent(e.event)}
                          </div>
                          <div className="text-muted-foreground text-xs">
                            {e.role === 'target' ? 'Affected this user' : 'Performed by this user'}
                            {e.ipAddress ? ` · ${e.ipAddress}` : ''}
                          </div>
                        </div>
                      </div>
                      <span className="text-muted-foreground shrink-0 text-xs">
                        {relativeTime(e.timestamp)}
                      </span>
                    </li>
                  ))}
                </ul>
              )}
            </Tabs.Content>

            {/* Permissions -------------------------------------------------- */}
            <Tabs.Content value="permissions" tabIndex={-1} className="focus:outline-none">
              {perms.loading ? (
                <Skeleton variant="table-row" lines={4} />
              ) : perms.error ? (
                <div className="flex items-center gap-3 py-4">
                  <AlertTriangle size={16} className="text-destructive shrink-0" aria-hidden />
                  <span className="text-destructive flex-1 text-sm">{perms.error}</span>
                  <Button variant="outline" size="sm" onClick={() => perms.refetch()}>
                    Retry
                  </Button>
                </div>
              ) : perms.data ? (
                <>
                  <p className="text-muted-foreground mb-3 text-sm">
                    Effective role{' '}
                    <span className="text-card-foreground font-medium">{perms.data.roleName}</span>{' '}
                    grants {perms.data.permissions.length} permission
                    {perms.data.permissions.length === 1 ? '' : 's'}. Permissions are derived from
                    the role and managed in configuration.
                  </p>
                  <ul className="flex flex-wrap gap-1.5">
                    {perms.data.permissions.map((p) => (
                      <li
                        key={p}
                        className="border-border bg-muted/50 text-card-foreground inline-flex items-center gap-1 rounded-md border px-2 py-1 text-xs"
                      >
                        <Check size={12} className="text-success" aria-hidden />
                        {p}
                      </li>
                    ))}
                  </ul>
                </>
              ) : null}
            </Tabs.Content>
          </Tabs.Root>
        )}

        {/* Auxiliary dialogs live inside the Drawer subtree so Radix's focus
            scope and aria-hidden management treat them as part of the active
            dialog rather than hiding them as background content. */}
        {confirm && (
          <ConfirmDialog
            open={!!confirm}
            onClose={() => setConfirm(null)}
            onConfirm={confirm.onConfirm}
            title={confirm.title}
            description={confirm.description}
            confirmLabel={confirm.confirmLabel}
            destructive={confirm.destructive}
          />
        )}

        <ReauthDialog
          open={!!reauth}
          onClose={() => setReauth(null)}
          onSubmit={async (password) => {
            if (reauth) await reauth.run(password)
          }}
        />

        {u && (
          <TransferContentModal
            open={showTransfer}
            onClose={() => setShowTransfer(false)}
            fromUser={{ id: u.id, name: u.name, contentOwnedCount: u.contentOwnedCount }}
            onTransferred={refreshAfterChange}
          />
        )}
      </Drawer>
    </>
  )
}
