// frontend/src/pages/users/UserDetail.jsx

import { useState, useEffect, useRef, useCallback } from 'react'
import { useParams, useNavigate } from 'react-router-dom'
import { createPortal } from 'react-dom'
import api from '@/lib/api'
import { useAuth } from '@/hooks/useAuth'
import { useToast } from '@/components/ui/Toast'
import { ProfilePageHeaderActions } from '@/components/ui/ProfilePageHeader'
import Button from '@/components/ui/Button'
import Card from '@/components/ui/Card'
import StatusBadge from '@/components/ui/StatusBadge'
import Spinner from '@/components/ui/Spinner'
import Select from '@/components/ui/Select'
import Icon from '@/components/ui/Icon'
import ConfirmDialog from '@/components/ui/ConfirmDialog'
import { fmtDateMedium } from '@/lib/formatters'
import DeleteUserModal from '@/modals/bellcloud/users/DeleteUserModal'
import EntryFormModal from '@/modals/crm/helpdesk/EntryFormModal'

// ─── Helpers ──────────────────────────────────────────────────────────────────

function statusVariant(status) {
  if (status === 'active')  return 'success'
  if (status === 'blocked') return 'danger'
  return 'neutral'
}

// ─── ActionMenu — primary "Actions" dropdown for page headers ─────────────────
// Reuses the existing .row-actions-menu / .row-actions-item CSS classes.

function ActionMenu({ actions = [], loading = false }) {
  const [open, setOpen] = useState(false)
  const [pos, setPos]   = useState({ top: 0, right: 0 })
  const btnRef          = useRef(null)
  const menuRef         = useRef(null)

  useEffect(() => {
    if (!open) return
    function onMouseDown(e) {
      if (btnRef.current?.contains(e.target))  return
      if (menuRef.current?.contains(e.target)) return
      setOpen(false)
    }
    function onScroll() { setOpen(false) }
    document.addEventListener('mousedown', onMouseDown)
    document.addEventListener('scroll',    onScroll, true)
    return () => {
      document.removeEventListener('mousedown', onMouseDown)
      document.removeEventListener('scroll',    onScroll, true)
    }
  }, [open])

  function handleToggle(e) {
    e.stopPropagation()
    if (!open && btnRef.current) {
      const r = btnRef.current.getBoundingClientRect()
      setPos({ top: r.bottom + 6, right: window.innerWidth - r.right })
    }
    setOpen((v) => !v)
  }

  return (
    <>
      <Button
        ref={btnRef}
        variant="primary"
        size="md"
        loading={loading}
        aria-haspopup="true"
        aria-expanded={open}
        onClick={handleToggle}
        iconRight={
          <svg
            width="13" height="13" viewBox="0 0 12 12"
            fill="none" stroke="currentColor" strokeWidth="1.75"
            strokeLinecap="round" strokeLinejoin="round" aria-hidden="true"
            style={{ transition: 'transform 0.15s', transform: open ? 'rotate(180deg)' : 'none', marginLeft: '-2px' }}
          >
            <path d="M2 4l4 4 4-4" />
          </svg>
        }
      >
        Actions
      </Button>

      {open && createPortal(
        <div
          ref={menuRef}
          role="menu"
          className="row-actions-menu"
          style={{ position: 'fixed', top: pos.top, right: pos.right, zIndex: 9999, minWidth: '180px' }}
        >
          {actions.map((action) => (
            <button
              key={action.label}
              role="menuitem"
              className="row-actions-item"
              style={{
                color:     action.color ?? 'var(--color-text-secondary)',
                borderTop: action.divider ? '1px solid var(--color-border)' : 'none',
                marginTop: action.divider ? 'var(--space-1)' : 0,
              }}
              onClick={(e) => {
                e.stopPropagation()
                setOpen(false)
                action.onClick?.()
              }}
            >
              {action.icon && <span className="row-actions-item-icon">{action.icon}</span>}
              {action.label}
            </button>
          ))}
        </div>,
        document.body
      )}
    </>
  )
}

// ─── Page-internal sub-components ─────────────────────────────────────────────

function Field({ label, children, mono = false }) {
  const isEmpty = children == null || children === ''
  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-1)' }}>
      <dt className="card-field-label">{label}</dt>
      <dd
        style={{
          fontSize: 'var(--font-size-base)',
          color: isEmpty ? 'var(--color-text-muted)' : 'var(--color-text-primary)',
          fontFamily: mono ? 'var(--font-family-mono)' : 'inherit',
          fontWeight: 'var(--font-weight-medium)',
        }}
      >
        {isEmpty ? '—' : children}
      </dd>
    </div>
  )
}


// Eye / EyeOff inline SVGs — Icon component doesn't have these
function EyeIcon({ off = false, size = 16 }) {
  return off ? (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M17.94 17.94A10.07 10.07 0 0112 20c-7 0-11-8-11-8a18.45 18.45 0 015.06-5.94" />
      <path d="M9.9 4.24A9.12 9.12 0 0112 4c7 0 11 8 11 8a18.5 18.5 0 01-2.16 3.19" />
      <line x1="1" y1="1" x2="23" y2="23" />
    </svg>
  ) : (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.75" strokeLinecap="round" strokeLinejoin="round" aria-hidden="true">
      <path d="M1 12s4-8 11-8 11 8 11 8-4 8-11 8-11-8-11-8z" />
      <circle cx="12" cy="12" r="3" />
    </svg>
  )
}

function PinField({ label, value }) {
  const [revealed, setRevealed] = useState(false)
  return (
    <div
      style={{
        padding: 'var(--space-4)',
        borderRadius: 'var(--radius-lg)',
        backgroundColor: 'var(--color-bg-abyss)',
        border: '1px solid var(--color-border)',
      }}
    >
      <p className="card-field-label" style={{ marginBottom: 'var(--space-2)' }}>
        {label}
      </p>
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between' }}>
        {value ? (
          <>
            <span
              style={{
                fontFamily: 'var(--font-family-mono)',
                fontSize: 'var(--font-size-md)',
                letterSpacing: revealed ? '0.25em' : '0.4em',
                color: 'var(--color-text-primary)',
              }}
            >
              {revealed ? value : '•'.repeat(String(value).length)}
            </span>
            <button
              onClick={() => setRevealed((v) => !v)}
              aria-label={revealed ? 'Hide PIN' : 'Show PIN'}
              style={{
                background: 'none',
                border: 'none',
                cursor: 'pointer',
                color: revealed ? 'var(--color-primary)' : 'var(--color-text-muted)',
                padding: 'var(--space-1)',
                display: 'flex',
                alignItems: 'center',
                transition: 'color 0.15s',
                flexShrink: 0,
              }}
            >
              <EyeIcon off={revealed} size={16} />
            </button>
          </>
        ) : (
          <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)' }}>Not set</span>
        )}
      </div>
    </div>
  )
}

function ActivityDot({ color }) {
  return (
    <div
      style={{
        width: '8px',
        height: '8px',
        borderRadius: 'var(--radius-full)',
        backgroundColor: color,
        boxShadow: `0 0 0 4px ${color}26`,
        flexShrink: 0,
        marginTop: '4px',
      }}
    />
  )
}

function OnlineDot({ isOnline }) {
  return (
    <span
      style={{
        display: 'inline-block',
        width: '8px',
        height: '8px',
        borderRadius: 'var(--radius-full)',
        backgroundColor: isOnline ? 'var(--color-success)' : 'var(--color-bg-island)',
        boxShadow: isOnline ? '0 0 6px var(--color-success)' : 'none',
        flexShrink: 0,
      }}
      title={isOnline ? 'Online' : 'Offline'}
    />
  )
}

// ─── Status pill (reused from IssuesTab pattern) ──────────────────────────────

const STATUS_META = {
  open:        { label: 'Open',        color: 'var(--color-danger)',  bg: 'var(--color-danger-bg)'  },
  researching: { label: 'Researching', color: 'var(--color-warning)', bg: 'var(--color-warning-bg)' },
  resolved:    { label: 'Resolved',    color: 'var(--color-success)', bg: 'var(--color-success-bg)' },
}

function StatusPill({ status }) {
  const m = STATUS_META[status] || { label: status, color: 'var(--color-text-muted)', bg: 'var(--color-bg-elevated)' }
  return (
    <span style={{
      display: 'inline-flex', alignItems: 'center', gap: 5,
      padding: '2px 8px',
      borderRadius: 'var(--radius-full)',
      backgroundColor: m.bg,
      border: `1px solid ${m.color}33`,
      fontSize: 'var(--font-size-xs)',
      fontWeight: 'var(--font-weight-semibold)',
      color: m.color,
      whiteSpace: 'nowrap',
      flexShrink: 0,
    }}>
      <span style={{ width: 5, height: 5, borderRadius: '50%', backgroundColor: m.color, flexShrink: 0 }} />
      {m.label}
    </span>
  )
}

// ─── Notes & Issues card (Postgres /notes system) ─────────────────────────────

function NotesCard({ userId, userName, canEdit }) {
  const { toast }                               = useToast()
  const [entries,      setEntries]              = useState([])
  const [loading,      setLoading]              = useState(true)
  const [entryModal,   setEntryModal]           = useState({ open: false, entry: null, defaultType: 'note' })
  const [deleteId,     setDeleteId]             = useState(null)
  const [deleting,     setDeleting]             = useState(false)

  const load = useCallback(async () => {
    setLoading(true)
    try {
      const data = await api.get(`/notes/by-entity/app_user/${userId}`)
      // newest first
      setEntries(Array.isArray(data) ? [...data].reverse() : [])
    } catch { setEntries([]) }
    finally { setLoading(false) }
  }, [userId])

  useEffect(() => { load() }, [load])

  const handleDelete = async () => {
    setDeleting(true)
    try {
      await api.delete(`/notes/${deleteId}`)
      toast.success('Deleted', 'Entry removed.')
      setDeleteId(null)
      load()
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to delete.')
    } finally { setDeleting(false) }
  }

  const openCreate = (defaultType) => setEntryModal({ open: true, entry: null, defaultType })
  const openEdit   = (entry)       => setEntryModal({ open: true, entry, defaultType: entry.type })

  const issues = entries.filter(e => e.type === 'issue')
  const notes  = entries.filter(e => e.type === 'note')
  const total  = entries.length

  return (
    <>
      <Card
        style={{ height: '100%' }}
        title={`Notes & Issues (${total})`}
        icon={<Icon name="info" size={15} color="var(--color-primary)" />}
        padding={false}
        action={canEdit && (
          <div style={{ display: 'flex', gap: 'var(--space-2)' }}>
            <Button variant="ghost" size="sm" onClick={() => openCreate('note')}>+ Note</Button>
            <Button variant="ghost" size="sm" onClick={() => openCreate('issue')}>+ Issue</Button>
          </div>
        )}
      >
        {/* card-body-flush makes this a flex:1 container — we manage all padding */}
        <div style={{ display: 'flex', flexDirection: 'column', height: '100%', overflow: 'hidden' }}>

          {/* Summary pills */}
          {issues.length > 0 && notes.length > 0 && (
            <div style={{ display: 'flex', gap: 'var(--space-2)', flexWrap: 'wrap', padding: 'var(--space-3) var(--space-8) 0' }}>
              <StatusBadge variant={issues.some(i => i.status !== 'resolved') ? 'danger' : 'success'}>
                {issues.length} issue{issues.length !== 1 ? 's' : ''}
              </StatusBadge>
              <StatusBadge variant="neutral">{notes.length} note{notes.length !== 1 ? 's' : ''}</StatusBadge>
            </div>
          )}

          {/* Scrollable list */}
          <div style={{
            flex: 1,
            overflowY: 'auto',
            display: 'flex',
            flexDirection: 'column',
            gap: 'var(--space-2)',
            minHeight: 0,
            padding: 'var(--space-3) var(--space-8) var(--space-8)',
          }}>
            {loading ? (
              <div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-6)' }}>
                <Spinner size="sm" />
              </div>
            ) : entries.length === 0 ? (
              <p style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)', textAlign: 'center', padding: 'var(--space-6) 0', fontStyle: 'italic' }}>
                No notes or issues linked to this user.
              </p>
            ) : (
              entries.map((entry) => (
                <div
                  key={entry.id}
                  onClick={() => canEdit && openEdit(entry)}
                  style={{
                    display: 'flex',
                    alignItems: 'flex-start',
                    gap: 'var(--space-3)',
                    padding: 'var(--space-3) var(--space-4)',
                    borderRadius: 'var(--radius-lg)',
                    backgroundColor: 'var(--color-bg-abyss)',
                    border: '1px solid var(--color-border)',
                    cursor: canEdit ? 'pointer' : 'default',
                    transition: 'background-color 0.15s',
                    flexShrink: 0,
                  }}
                  onMouseEnter={e => { if (canEdit) e.currentTarget.style.backgroundColor = 'var(--color-bg-elevated)' }}
                  onMouseLeave={e => { e.currentTarget.style.backgroundColor = 'var(--color-bg-abyss)' }}
                >
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-2)', marginBottom: 'var(--space-1)', flexWrap: 'wrap' }}>
                      {entry.type === 'issue'
                        ? <StatusPill status={entry.status} />
                        : <StatusBadge variant="neutral">Note</StatusBadge>
                      }
                      <span style={{
                        fontSize: 'var(--font-size-sm)',
                        fontWeight: 'var(--font-weight-semibold)',
                        color: 'var(--color-text-primary)',
                        overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap',
                      }}>
                        {entry.title}
                      </span>
                    </div>
                    {entry.body && (
                      <p style={{
                        fontSize: 'var(--font-size-sm)',
                        color: 'var(--color-text-secondary)',
                        overflow: 'hidden',
                        display: '-webkit-box',
                        WebkitLineClamp: 2,
                        WebkitBoxOrient: 'vertical',
                        marginBottom: 'var(--space-1)',
                        lineHeight: 1.5,
                        margin: '0 0 var(--space-1)',
                      }}>
                        {entry.body.replace(/<[^>]*>/g, '')}
                      </p>
                    )}
                    <p style={{ fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', margin: 0 }}>
                      {[entry.author_name, entry.created_at ? fmtDateMedium(entry.created_at) : null].filter(Boolean).join(' · ')}
                    </p>
                  </div>
                  {canEdit && (
                    <button
                      onClick={e => { e.stopPropagation(); setDeleteId(entry.id) }}
                      aria-label="Delete entry"
                      style={{
                        background: 'none', border: 'none', cursor: 'pointer',
                        color: 'var(--color-text-muted)', padding: 'var(--space-1)',
                        display: 'flex', alignItems: 'center', flexShrink: 0,
                        transition: 'color 0.15s',
                      }}
                      onMouseEnter={e => { e.currentTarget.style.color = 'var(--color-danger)' }}
                      onMouseLeave={e => { e.currentTarget.style.color = 'var(--color-text-muted)' }}
                    >
                      <Icon name="delete" size={14} color="currentColor" />
                    </button>
                  )}
                </div>
              ))
            )}
          </div>
        </div>
      </Card>

      {/* Entry form modal */}
      <EntryFormModal
        open={entryModal.open}
        entry={entryModal.entry}
        defaultType={entryModal.defaultType}
        prefilledLinks={entryModal.entry ? undefined : [{ entity_type: 'app_user', entity_id: userId, display_name: userName, locked: true }]}
        knownEntities={userId ? { [userId]: userName } : undefined}
        onClose={() => setEntryModal({ open: false, entry: null, defaultType: 'note' })}
        onSaved={() => { setEntryModal({ open: false, entry: null, defaultType: 'note' }); load() }}
        onDelete={canEdit ? (id) => { setEntryModal({ open: false, entry: null, defaultType: 'note' }); setDeleteId(id) } : null}
      />

      {/* Delete confirm */}
      <ConfirmDialog
        open={!!deleteId}
        variant="danger"
        title="Delete entry?"
        message="This entry and all its linked entities will be permanently removed."
        confirmLabel="Delete"
        onConfirm={handleDelete}
        onClose={() => setDeleteId(null)}
        loading={deleting}
      />
    </>
  )
}

// ─── UserDetail ───────────────────────────────────────────────────────────────

export default function UserDetail() {
  const { id } = useParams()
  const navigate = useNavigate()
  const { hasPermission } = useAuth()
  const { toast } = useToast()
  const canEdit = hasPermission('app_users', 'edit')
  const photoInputRef = useRef(null)

  const [user, setUser]               = useState(null)
  const [devices, setDevices]         = useState([])
  const [allDevices, setAllDevices]   = useState([])
  const [loading, setLoading]         = useState(true)
  const [error, setError]             = useState('')
  const [blocking, setBlocking]       = useState(false)
  const [showDelete, setShowDelete]   = useState(false)
  const [deleteError, setDeleteError] = useState('')
  const [uploadingPhoto, setUploadingPhoto] = useState(false)

  // Device assignment
  const [showAssignPanel, setShowAssignPanel]   = useState(false)
  const [selectedDeviceId, setSelectedDeviceId] = useState('')
  const [assigningDevice, setAssigningDevice]   = useState(false)

  // ── Load ───────────────────────────────────────────────────────────────────
  const loadData = useCallback(async () => {
    setLoading(true)
    setError('')
    try {
      const [u, d] = await Promise.all([
        api.get(`/users/${id}`),
        api.get(`/users/${id}/devices`),
      ])
      setUser(u)
      setDevices(Array.isArray(d) ? d : [])
    } catch (err) {
      setError(err.message || 'Failed to load user.')
    } finally {
      setLoading(false)
    }
  }, [id])

  useEffect(() => { loadData() }, [loadData])

  const loadAllDevices = async () => {
    try {
      const data = await api.get('/devices')
      setAllDevices(data.devices ?? [])
    } catch { /* silent */ }
  }

  // ── Actions ────────────────────────────────────────────────────────────────
  const handleDelete = async () => {
    setDeleteError('')
    try {
      await api.delete(`/users/${id}`)
      toast.success('User deleted')
      navigate('/users')
    } catch (err) {
      setDeleteError(err.message || 'Failed to delete user.')
    }
  }

  const handleBlockToggle = async () => {
    setBlocking(true)
    try {
      const endpoint = user.status === 'blocked' ? `/users/${id}/unblock` : `/users/${id}/block`
      const updated = await api.post(endpoint)
      setUser(updated)
      toast.success(user.status === 'blocked' ? 'User unblocked' : 'User blocked')
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to update user status.')
    } finally {
      setBlocking(false)
    }
  }

  const handleAssignDevice = async () => {
    if (!selectedDeviceId) return
    setAssigningDevice(true)
    try {
      await api.post(`/users/${id}/devices/${selectedDeviceId}`)
      const d = await api.get(`/users/${id}/devices`)
      setDevices(Array.isArray(d) ? d : [])
      setSelectedDeviceId('')
      setShowAssignPanel(false)
      toast.success('Device assigned')
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to assign device.')
    } finally {
      setAssigningDevice(false)
    }
  }

  const handleUnassignDevice = async (deviceId) => {
    try {
      await api.delete(`/users/${id}/devices/${deviceId}`)
      const d = await api.get(`/users/${id}/devices`)
      setDevices(Array.isArray(d) ? d : [])
      toast.success('Device removed')
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to remove device.')
    }
  }

  const handlePhotoUpload = async (e) => {
    const file = e.target.files?.[0]
    if (!file) return
    setUploadingPhoto(true)
    try {
      const result = await api.upload(`/users/${id}/photo`, file)
      setUser((prev) => ({ ...prev, photo_url: result.photo_url }))
      toast.success('Photo updated')
    } catch (err) {
      toast.danger('Error', err.message || 'Failed to upload photo.')
    } finally {
      setUploadingPhoto(false)
      if (photoInputRef.current) photoInputRef.current.value = ''
    }
  }

  // ── Loading / error states ─────────────────────────────────────────────────
  if (loading) {
    return (
      <div className="page-wrapper">
        <div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-16)' }}>
          <Spinner size="lg" />
        </div>
      </div>
    )
  }

  if (error && !user) {
    return (
      <div className="page-wrapper">
        <div role="alert" style={{ backgroundColor: 'var(--color-danger-bg)', border: '1px solid var(--color-danger)', borderRadius: 'var(--radius-md)', padding: 'var(--space-4)', color: 'var(--color-danger)', fontSize: 'var(--font-size-sm)' }}>
          {error}
        </div>
      </div>
    )
  }

  if (!user) return null

  const isBlocked         = user.status === 'blocked'
  const assignedDeviceIds = new Set(devices.map((d) => d.id))
  const availableDevices  = allDevices.filter((d) => !assignedDeviceIds.has(d.id))
  const friendCount       = user.friendsList?.length ?? 0
  const invitedCount      = user.friendsInvited?.length ?? 0

  // Actions menu items
  const actionItems = canEdit ? [
    {
      label: isBlocked ? 'Unblock User' : 'Block User',
      icon: <Icon name={isBlocked ? 'check' : 'warning'} size={14} />,
      onClick: handleBlockToggle,
    },
    {
      label: 'Edit User',
      icon: <Icon name="edit" size={14} />,
      onClick: () => navigate(`/users/${id}/edit`),
    },
    {
      label: 'Change Photo',
      icon: <Icon name="upload" size={14} />,
      onClick: () => photoInputRef.current?.click(),
    },
    {
      label: 'Delete User',
      icon: <Icon name="delete" size={14} />,
      color: 'var(--color-danger)',
      divider: true,
      onClick: () => { setDeleteError(''); setShowDelete(true) },
    },
  ] : []

  return (
    <div className="page-wrapper">

      {/* Page header — no breadcrumbs */}
      <ProfilePageHeaderActions
        name={user.display_name || 'Unnamed User'}
        subtitle={[user.userTitle, user.email].filter(Boolean).join(' • ') || undefined}
        photoUrl={user.photo_url}
        onPhotoClick={canEdit ? () => photoInputRef.current?.click() : undefined}
        badge={
          <StatusBadge variant={statusVariant(user.status)} dot={false}>
            {user.status ? user.status.charAt(0).toUpperCase() + user.status.slice(1) : 'Unknown'}
          </StatusBadge>
        }
      >
        {canEdit && <ActionMenu actions={actionItems} loading={blocking} />}
      </ProfilePageHeaderActions>

      {/* Hidden photo input */}
      <input
        ref={photoInputRef}
        type="file"
        accept="image/*"
        onChange={handlePhotoUpload}
        style={{ display: 'none' }}
      />

      {/* Inline error banner */}
      {error && (
        <div role="alert" style={{ backgroundColor: 'var(--color-danger-bg)', border: '1px solid var(--color-danger)', borderRadius: 'var(--radius-md)', padding: 'var(--space-3) var(--space-4)', color: 'var(--color-danger)', fontSize: 'var(--font-size-sm)' }}>
          {error}
        </div>
      )}

      {/* ── Layout grid ────────────────────────────────────────────────────── */}
      <div
        className="user-detail-grid"
        style={{
          display: 'grid',
          gridTemplateColumns: 'repeat(3, 1fr)',
          gridTemplateRows: 'auto 320px auto',
          gap: 'var(--space-6)',
          alignItems: 'stretch',
        }}
      >

        {/* ── ROW 1 ── Account Information (span 2) + Security Access (span 1) */}
        {/* Both cells use display:flex+flex-col+height:100% to match heights    */}

        <div style={{ gridColumn: 'span 2', display: 'flex', flexDirection: 'column' }}>
          <Card style={{ flex: 1 }} title="Account Information" icon={<Icon name="staff" size={15} color="var(--color-primary)" />}>
            <dl
              style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(2, 1fr)',
                gap: 'var(--space-5)',
              }}
            >
              <Field label="Phone Number">{user.phone_number}</Field>
              <Field label="Login Email">{user.email}</Field>
              <Field label="Title">{user.userTitle}</Field>
              <Field label="Unique Identifier (UID)">
                <span
                  style={{
                    fontFamily: 'var(--font-family-mono)',
                    fontSize: 'var(--font-size-sm)',
                    color: 'var(--color-primary)',
                    backgroundColor: 'var(--color-primary-subtle)',
                    padding: '2px var(--space-2)',
                    borderRadius: 'var(--radius-sm)',
                  }}
                >
                  {user.uid || user.id || '—'}
                </span>
              </Field>
              {/* Bio — always present, full width, 3rd row */}
              <div style={{ gridColumn: 'span 2' }}>
                <Field label="Bio">
                  {user.bio ? (
                    <span style={{ fontSize: 'var(--font-size-sm)', lineHeight: '1.6', color: 'var(--color-text-secondary)', fontWeight: 'var(--font-weight-normal)' }}>
                      {user.bio}
                    </span>
                  ) : (
                    <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)', fontStyle: 'italic', fontWeight: 'var(--font-weight-normal)' }}>
                      No bio
                    </span>
                  )}
                </Field>
              </div>
            </dl>
          </Card>
        </div>

        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Card style={{ flex: 1 }} title="Security Access" icon={<Icon name="settings" size={15} color="var(--color-primary)" />}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
              <PinField label="Master Settings PIN" value={user.settingsPIN} />
              <PinField label="Quick Settings PIN"  value={user.quickSettingsPIN} />
            </div>
          </Card>
        </div>

        {/* ── ROW 2 ── System Activity (span 1) + Notes (span 2, scrollable) ── */}

        <div style={{ display: 'flex', flexDirection: 'column' }}>
          <Card style={{ flex: 1 }} title="System Activity" icon={<Icon name="refresh" size={15} color="var(--color-primary)" />}>
            <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
              <div style={{ display: 'flex', gap: 'var(--space-4)', alignItems: 'flex-start' }}>
                <ActivityDot color="var(--color-primary)" />
                <div>
                  <p className="card-field-label" style={{ marginBottom: 'var(--space-1)' }}>
                    Created
                  </p>
                  <p style={{ fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)' }}>
                    {user.created_time || user.createdAt || '—'}
                  </p>
                </div>
              </div>
              <div style={{ display: 'flex', gap: 'var(--space-4)', alignItems: 'flex-start' }}>
                <ActivityDot color="var(--color-success)" />
                <div>
                  <p className="card-field-label" style={{ marginBottom: 'var(--space-1)' }}>
                    Last Active
                  </p>
                  <p style={{ fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)' }}>
                    {user.lastActive || '—'}
                  </p>
                </div>
              </div>
            </div>
          </Card>
        </div>

        {/* Notes — spans 2 cols, row 2 is 320px tall, card fills and scrolls */}
        <div style={{ gridColumn: 'span 2' }}>
          <NotesCard userId={id} userName={user?.display_name || user?.email || ''} canEdit={canEdit} />
        </div>

        {/* ── ROW 3 ── Social (span 1) + Linked Devices (span 2) ─────────────── */}

        <Card title="Social" icon={<Icon name="customers" size={15} color="var(--color-primary)" />}>
          <div style={{ display: 'flex', justifyContent: 'flex-end', marginBottom: 'var(--space-4)' }}>
            <span style={{ fontSize: 'var(--font-size-xl)', fontWeight: 'var(--font-weight-bold)', fontFamily: 'var(--font-family-display)', color: 'var(--color-primary)', lineHeight: 1 }}>
              {friendCount}
            </span>
          </div>
          <div style={{ paddingTop: 'var(--space-4)', borderTop: '1px solid var(--color-border)', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <span style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)' }}>Invited Members</span>
            <span style={{ fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)' }}>{invitedCount}</span>
          </div>
        </Card>

        <div style={{ gridColumn: 'span 2' }}>
          <Card
            title={`Linked Devices (${devices.length})`}
            icon={<Icon name="devices" size={15} color="var(--color-primary)" />}
            action={canEdit && (
              <Button variant="ghost" size="sm" onClick={() => { setShowAssignPanel((v) => !v); if (!showAssignPanel) loadAllDevices() }}>
                {showAssignPanel ? 'Cancel' : 'Assign Device'}
              </Button>
            )}
          >

            {/* Assign device inline panel */}
            {showAssignPanel && (
              <div
                style={{
                  marginBottom: 'var(--space-4)',
                  padding: 'var(--space-4)',
                  borderRadius: 'var(--radius-lg)',
                  backgroundColor: 'var(--color-bg-abyss)',
                  border: '1px solid var(--color-border)',
                  display: 'flex',
                  gap: 'var(--space-3)',
                  alignItems: 'flex-end',
                }}
              >
                <div style={{ flex: 1 }}>
                  <Select value={selectedDeviceId} onChange={(e) => setSelectedDeviceId(e.target.value)} placeholder="Choose a device…">
                    <option value="">Choose a device…</option>
                    {availableDevices.map((d) => (
                      <option key={d.id} value={d.id}>
                        {d.device_name || 'Unnamed'} ({d.device_id || d.id})
                      </option>
                    ))}
                  </Select>
                </div>
                <Button variant="primary" size="sm" loading={assigningDevice} disabled={!selectedDeviceId} onClick={handleAssignDevice}>
                  Assign
                </Button>
              </div>
            )}

            {/* Device list */}
            {devices.length === 0 ? (
              <p style={{ fontSize: 'var(--font-size-sm)', color: 'var(--color-text-muted)' }}>No devices assigned.</p>
            ) : (
              <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-3)' }}>
                {devices.map((device) => (
                  <div
                    key={device.id}
                    style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: 'var(--space-3)', borderRadius: 'var(--radius-lg)', backgroundColor: 'var(--color-bg-abyss)', border: '1px solid var(--color-border)' }}
                  >
                    <div style={{ display: 'flex', alignItems: 'center', gap: 'var(--space-3)', minWidth: 0 }}>
                      <OnlineDot isOnline={device.is_Online} />
                      <div style={{ minWidth: 0 }}>
                        <button
                          onClick={() => navigate(`/devices/${device.id}`)}
                          style={{ background: 'none', border: 'none', cursor: 'pointer', padding: 0, fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-semibold)', color: 'var(--color-text-accent)', textAlign: 'left', display: 'block', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', maxWidth: '160px' }}
                        >
                          {device.device_name || 'Unnamed Device'}
                        </button>
                        <p style={{ fontFamily: 'var(--font-family-mono)', fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', marginTop: '2px' }}>
                          {device.device_id || device.id}
                        </p>
                      </div>
                    </div>
                    {canEdit && (
                      <Button variant="danger" size="sm" onClick={() => handleUnassignDevice(device.id)}>Remove</Button>
                    )}
                  </div>
                ))}
              </div>
            )}
          </Card>
        </div>

      </div>

      {/* Responsive grid */}
      <style>{`
        @media (max-width: 1024px) {
          .user-detail-grid { grid-template-columns: repeat(2, 1fr) !important; }
          .user-detail-grid > [style*="span 2"] { grid-column: span 2 !important; }
        }
        @media (max-width: 768px) {
          .user-detail-grid { grid-template-columns: 1fr !important; }
          .user-detail-grid > [style*="span 2"] { grid-column: span 1 !important; }
        }
      `}</style>

      {/* Delete modal */}
      <DeleteUserModal
        user={showDelete ? user : null}
        onConfirm={handleDelete}
        onCancel={() => { setShowDelete(false); setDeleteError('') }}
        error={deleteError}
      />

    </div>
  )
}
