// frontend/src/modals/crm/helpdesk/CreateTicketModal.jsx
// Create a new support ticket. Staff can open on behalf of a customer.

import { useState, useEffect, useRef, useCallback } from 'react'
import { createPortal } from 'react-dom'
import api from '@/lib/api'
import { useAuth } from '@/hooks/useAuth'
import { useToast } from '@/components/ui/Toast'
import Modal from '@/components/ui/Modal'
import Button from '@/components/ui/Button'
import FormField from '@/components/ui/FormField'
import Spinner from '@/components/ui/Spinner'

const PRIORITY_OPTIONS = [
  { value: '',       label: 'No priority' },
  { value: 'low',    label: 'Low'         },
  { value: 'medium', label: 'Medium'      },
  { value: 'high',   label: 'High'        },
  { value: 'urgent', label: 'Urgent'      },
]

const OPENED_VIA_OPTIONS = [
  { value: 'staff',  label: 'Staff (opened by us)'   },
  { value: 'phone',  label: 'Phone'                  },
  { value: 'email',  label: 'Email'                  },
  { value: 'app',    label: 'App'                    },
]

// ─── Magnifying glass SVG ─────────────────────────────────────────────────────

const IconSearch = () => (
  <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
    <circle cx="11" cy="11" r="8"/>
    <line x1="21" y1="21" x2="16.65" y2="16.65"/>
  </svg>
)

// ─── BrowseModal ──────────────────────────────────────────────────────────────
// Generic browse-all list modal for any entity type.

function BrowseModal({ open, entityType, onPick, onClose }) {
  const [items,   setItems]   = useState([])
  const [loading, setLoading] = useState(false)
  const [search,  setSearch]  = useState('')
  const debounceRef = useRef(null)

  const load = useCallback(async (q = '') => {
    setLoading(true)
    try {
      let data
      const qs = q ? `?search=${encodeURIComponent(q)}&limit=50` : '?limit=50'
      if (entityType === 'customer') {
        data = await api.get(`/crm/customers${qs}`)
        setItems(data.customers || data.data || [])
      } else if (entityType === 'device') {
        data = await api.get(`/devices${qs}`)
        setItems(data.devices || data.data || [])
      } else if (entityType === 'app_user') {
        data = await api.get(`/users${qs}`)
        setItems(data.users || data.data || [])
      }
    } catch { /* silent */ } finally {
      setLoading(false)
    }
  }, [entityType])

  useEffect(() => { if (open) { setSearch(''); load() } }, [open, load])

  const handleSearch = (e) => {
    const q = e.target.value
    setSearch(q)
    clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => load(q), 300)
  }

  const typeLabel = { customer: 'Customers', device: 'Devices', app_user: 'Users' }[entityType] || entityType

  const getLines = (item) => {
    if (entityType === 'customer') {
      const city = item.location?.city || item.city || ''
      return {
        primary:   [item.surname, item.name].filter(Boolean).join(' ') || item.id,
        secondary: [item.organization, city].filter(Boolean).join(' · '),
      }
    }
    if (entityType === 'device') {
      return {
        primary:   item.device_name || item.id,
        secondary: item.serial_number || '',
      }
    }
    // app_user
    return {
      primary:   item.display_name || item.email || item.id,
      secondary: item.email || '',
    }
  }

  const getPickData = (item) => {
    const lines = getLines(item)
    return { id: item.id, name: lines.primary, sub: lines.secondary }
  }

  return (
    <Modal open={open} onClose={onClose} title={`Select ${typeLabel.slice(0, -1)}`} size="md">
      <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-4)' }}>
        <input
          type="text"
          value={search}
          onChange={handleSearch}
          placeholder={`Search ${typeLabel.toLowerCase()}…`}
          autoFocus
          className="input"
          style={{ boxSizing: 'border-box' }}
        />
        <div style={{
          border: '1px solid var(--color-border)',
          borderRadius: 'var(--radius-lg)',
          overflow: 'hidden',
          maxHeight: 360,
          overflowY: 'auto',
        }}>
          {loading ? (
            <div style={{ display: 'flex', justifyContent: 'center', padding: 'var(--space-8)' }}><Spinner size="sm" /></div>
          ) : items.length === 0 ? (
            <div style={{ padding: 'var(--space-8)', textAlign: 'center', color: 'var(--color-text-muted)', fontSize: 'var(--font-size-sm)' }}>
              No {typeLabel.toLowerCase()} found.
            </div>
          ) : (
            items.map((item, i) => {
              const lines = getLines(item)
              return (
                <button
                  key={item.id || i}
                  onClick={() => { onPick(getPickData(item)); onClose() }}
                  style={{
                    display: 'flex', width: '100%', textAlign: 'left',
                    padding: 'var(--space-3) var(--space-4)',
                    background: 'none', border: 'none', cursor: 'pointer',
                    borderBottom: i < items.length - 1 ? '1px solid var(--color-border)' : 'none',
                    transition: 'background 0.1s',
                  }}
                  onMouseEnter={e => e.currentTarget.style.background = 'var(--color-bg-island)'}
                  onMouseLeave={e => e.currentTarget.style.background = 'none'}
                >
                  <div style={{ minWidth: 0 }}>
                    <p style={{ margin: 0, fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                      {lines.primary || '—'}
                    </p>
                    {lines.secondary && (
                      <p style={{ margin: 0, color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                        {lines.secondary}
                      </p>
                    )}
                  </div>
                </button>
              )
            })
          )}
        </div>
      </div>
    </Modal>
  )
}

// ─── CustomerSearchInput ──────────────────────────────────────────────────────
// Searchable customer picker with 2-line display + browse button.

function CustomerSearchInput({ value, displayName, displaySub, onChange, onBrowse }) {
  const [query,     setQuery]     = useState('')
  const [results,   setResults]   = useState([])
  const [searching, setSearching] = useState(false)
  const [open,      setOpen]      = useState(false)
  const [dropPos,   setDropPos]   = useState({ top: 0, left: 0, width: 0 })
  const debounceRef  = useRef(null)
  const wrapRef      = useRef(null)
  const inputWrapRef = useRef(null)

  useEffect(() => {
    const handler = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false)
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [])

  useEffect(() => { setQuery('') }, [value])

  const updateDropPos = () => {
    if (inputWrapRef.current) {
      const r = inputWrapRef.current.getBoundingClientRect()
      setDropPos({ top: r.bottom + 4, left: r.left, width: r.width })
    }
  }

  const search = useCallback(async (q) => {
    if (!q.trim()) { setResults([]); setOpen(false); return }
    setSearching(true)
    try {
      const data = await api.get(`/crm/customers?search=${encodeURIComponent(q)}&limit=10`)
      setResults(data.customers || data.data || [])
      updateDropPos()
      setOpen(true)
    } catch { /* silent */ } finally {
      setSearching(false)
    }
  }, [])

  const handleInput = (e) => {
    const q = e.target.value
    setQuery(q)
    if (!q.trim()) { onChange(null); setResults([]); setOpen(false); return }
    clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => search(q), 280)
  }

  const pick = (c) => {
    const name    = [c.surname, c.name].filter(Boolean).join(' ') || c.id
    const city    = c.location?.city || c.city || ''
    const subLine = [c.organization, city].filter(Boolean).join(' · ')
    onChange({ id: c.id, name, subLine })
    setQuery('')
    setResults([])
    setOpen(false)
  }

  const clear = () => { onChange(null); setQuery(''); setResults([]); setOpen(false) }

  return (
    <div ref={wrapRef}>
      <label style={{ display: 'block', fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-secondary)', marginBottom: 'var(--space-2)', lineHeight: 'var(--line-height-tight)' }}>
        Customer <span style={{ color: 'var(--color-danger)' }}>*</span>
      </label>

      <div
        ref={inputWrapRef}
        className="input"
        style={{ display: 'flex', alignItems: 'center', padding: 0, overflow: 'hidden', cursor: 'text' }}
        onFocusCapture={e => e.currentTarget.style.borderColor = 'var(--color-primary)'}
        onBlurCapture={e => e.currentTarget.style.borderColor = ''}
      >
        {value && displayName ? (
          <div style={{ flex: 1, padding: 'var(--space-3) var(--space-4)', minWidth: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 'var(--space-2)' }}>
            <div style={{ minWidth: 0 }}>
              <p style={{ margin: 0, fontSize: 'var(--font-size-base)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {displayName}
              </p>
              {displaySub && (
                <p style={{ margin: 0, fontSize: 'var(--font-size-xs)', color: 'var(--color-text-muted)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                  {displaySub}
                </p>
              )}
            </div>
            <button onClick={clear} style={{ flexShrink: 0, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--color-text-muted)', fontSize: 16, lineHeight: 1, padding: 2 }} title="Clear">×</button>
          </div>
        ) : (
          <>
            <input
              type="text"
              value={query}
              onChange={handleInput}
              placeholder="Search by name, email, phone, org…"
              style={{
                flex: 1, border: 'none', outline: 'none',
                background: 'transparent',
                padding: 'var(--space-3) var(--space-4)',
                fontSize: 'var(--font-size-base)',
                color: 'var(--color-text-primary)',
                fontFamily: 'var(--font-family-base)',
                lineHeight: 'var(--line-height-base)',
              }}
            />
            {searching && (
              <div style={{ padding: '0 var(--space-2)', display: 'flex', alignItems: 'center' }}>
                <Spinner size="xs" />
              </div>
            )}
          </>
        )}

        {/* Browse magnifying glass */}
        <button
          onClick={onBrowse}
          title="Browse all customers"
          style={{
            flexShrink: 0, padding: 'var(--space-2) var(--space-3)',
            background: 'none', border: 'none',
            borderLeft: '1px solid var(--color-border)',
            cursor: 'pointer',
            color: 'var(--color-text-muted)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'color 0.1s, background 0.1s',
            alignSelf: 'stretch',
          }}
          onMouseEnter={e => { e.currentTarget.style.color = 'var(--color-primary)'; e.currentTarget.style.background = 'var(--color-primary-subtle)' }}
          onMouseLeave={e => { e.currentTarget.style.color = 'var(--color-text-muted)'; e.currentTarget.style.background = 'none' }}
        >
          <IconSearch />
        </button>
      </div>

      {/* Portal dropdown */}
      {open && results.length > 0 && createPortal(
        <div style={{
          position: 'fixed',
          top: dropPos.top, left: dropPos.left, width: dropPos.width,
          zIndex: 9999,
          backgroundColor: 'var(--color-bg-elevated)',
          border: '1px solid var(--color-border)',
          borderRadius: 'var(--radius-lg)',
          boxShadow: 'var(--shadow-lg)',
          overflow: 'hidden',
          maxHeight: 300,
          overflowY: 'auto',
        }}>
          {results.map((c, i) => {
            const name    = [c.surname, c.name].filter(Boolean).join(' ') || '—'
            const city    = c.location?.city || c.city || ''
            const subLine = [c.organization, city].filter(Boolean).join(' · ')
            return (
              <button
                key={c.id || i}
                onClick={() => pick(c)}
                style={{
                  display: 'block', width: '100%', textAlign: 'left',
                  padding: 'var(--space-3) var(--space-4)',
                  background: 'none', border: 'none', cursor: 'pointer',
                  borderBottom: i < results.length - 1 ? '1px solid var(--color-border)' : 'none',
                  transition: 'background 0.1s',
                }}
                onMouseEnter={e => e.currentTarget.style.background = 'var(--color-bg-island)'}
                onMouseLeave={e => e.currentTarget.style.background = 'none'}
              >
                <p style={{ margin: 0, fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)' }}>
                  {name}
                </p>
                {subLine && (
                  <p style={{ margin: 0, color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)' }}>
                    {subLine}
                  </p>
                )}
              </button>
            )
          })}
        </div>,
        document.body
      )}
    </div>
  )
}

// ─── EntitySearchInput (device / user) ────────────────────────────────────────
// Reusable inline search for devices or app users, with browse button + portal dropdown.

function EntitySearchInput({ label, entityType, value, displayName, onChange, onBrowse, required }) {
  const [query,     setQuery]     = useState('')
  const [results,   setResults]   = useState([])
  const [searching, setSearching] = useState(false)
  const [open,      setOpen]      = useState(false)
  const [dropPos,   setDropPos]   = useState({ top: 0, left: 0, width: 0 })
  const debounceRef  = useRef(null)
  const wrapRef      = useRef(null)
  const inputWrapRef = useRef(null)

  useEffect(() => {
    const handler = (e) => {
      if (wrapRef.current && !wrapRef.current.contains(e.target)) setOpen(false)
    }
    document.addEventListener('mousedown', handler)
    return () => document.removeEventListener('mousedown', handler)
  }, [])

  useEffect(() => { setQuery('') }, [value])

  const updateDropPos = () => {
    if (inputWrapRef.current) {
      const r = inputWrapRef.current.getBoundingClientRect()
      setDropPos({ top: r.bottom + 4, left: r.left, width: r.width })
    }
  }

  const placeholder = entityType === 'device'
    ? 'Search by name or serial…'
    : 'Search by name or email…'

  const getLines = (item) => {
    if (entityType === 'device') {
      return {
        primary:   item.device_name || item.id,
        secondary: item.serial_number || '',
      }
    }
    // app_user
    return {
      primary:   item.display_name || item.email || item.id,
      secondary: item.email || '',
    }
  }

  const toResult = (item) => {
    const lines = getLines(item)
    return { id: item.id, name: lines.primary, sub: lines.secondary }
  }

  const search = useCallback(async (q) => {
    if (!q.trim()) { setResults([]); setOpen(false); return }
    setSearching(true)
    try {
      let data
      if (entityType === 'device') {
        data = await api.get(`/devices?search=${encodeURIComponent(q)}&limit=8`)
        setResults((data.devices || data.data || []).map(toResult))
      } else {
        data = await api.get(`/users?search=${encodeURIComponent(q)}&limit=8`)
        setResults((data.users || data.data || []).map(toResult))
      }
      updateDropPos()
      setOpen(true)
    } catch { /* silent */ } finally {
      setSearching(false)
    }
  }, [entityType]) // eslint-disable-line react-hooks/exhaustive-deps

  const handleInput = (e) => {
    const q = e.target.value
    setQuery(q)
    if (!q.trim()) { onChange(null); setResults([]); setOpen(false); return }
    clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => search(q), 280)
  }

  const pick = (item) => {
    onChange(item)
    setQuery('')
    setResults([])
    setOpen(false)
  }

  const clear = () => { onChange(null); setQuery(''); setResults([]); setOpen(false) }

  return (
    <div ref={wrapRef}>
      <label style={{ display: 'block', fontSize: 'var(--font-size-sm)', fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-secondary)', marginBottom: 'var(--space-2)', lineHeight: 'var(--line-height-tight)' }}>
        {label}{required && <span style={{ color: 'var(--color-danger)' }}> *</span>}
      </label>

      <div
        ref={inputWrapRef}
        className="input"
        style={{ display: 'flex', alignItems: 'center', padding: 0, overflow: 'hidden', cursor: 'text' }}
        onFocusCapture={e => e.currentTarget.style.borderColor = 'var(--color-primary)'}
        onBlurCapture={e => e.currentTarget.style.borderColor = ''}
      >
        {value && displayName ? (
          <div style={{ flex: 1, padding: 'var(--space-3) var(--space-4)', minWidth: 0, display: 'flex', alignItems: 'center', justifyContent: 'space-between', gap: 'var(--space-2)' }}>
            <span style={{ fontSize: 'var(--font-size-base)', color: 'var(--color-text-primary)', overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap', flex: 1 }}>
              {displayName}
            </span>
            <button onClick={clear} style={{ flexShrink: 0, background: 'none', border: 'none', cursor: 'pointer', color: 'var(--color-text-muted)', fontSize: 16, lineHeight: 1, padding: 2 }} title="Clear">×</button>
          </div>
        ) : (
          <>
            <input
              type="text"
              value={query}
              onChange={handleInput}
              placeholder={placeholder}
              style={{
                flex: 1, border: 'none', outline: 'none',
                background: 'transparent',
                padding: 'var(--space-3) var(--space-4)',
                fontSize: 'var(--font-size-base)',
                color: 'var(--color-text-primary)',
                fontFamily: 'var(--font-family-base)',
                lineHeight: 'var(--line-height-base)',
              }}
            />
            {searching && (
              <div style={{ padding: '0 var(--space-2)', display: 'flex', alignItems: 'center' }}>
                <Spinner size="xs" />
              </div>
            )}
          </>
        )}

        {/* Browse magnifying glass */}
        <button
          onClick={onBrowse}
          title={`Browse all ${entityType === 'app_user' ? 'users' : entityType + 's'}`}
          style={{
            flexShrink: 0, padding: 'var(--space-2) var(--space-3)',
            background: 'none', border: 'none',
            borderLeft: '1px solid var(--color-border)',
            cursor: 'pointer',
            color: 'var(--color-text-muted)',
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            transition: 'color 0.1s, background 0.1s',
            alignSelf: 'stretch',
          }}
          onMouseEnter={e => { e.currentTarget.style.color = 'var(--color-primary)'; e.currentTarget.style.background = 'var(--color-primary-subtle)' }}
          onMouseLeave={e => { e.currentTarget.style.color = 'var(--color-text-muted)'; e.currentTarget.style.background = 'none' }}
        >
          <IconSearch />
        </button>
      </div>

      {/* Portal dropdown */}
      {open && results.length > 0 && createPortal(
        <div style={{
          position: 'fixed',
          top: dropPos.top, left: dropPos.left, width: dropPos.width,
          zIndex: 9999,
          backgroundColor: 'var(--color-bg-elevated)',
          border: '1px solid var(--color-border)',
          borderRadius: 'var(--radius-lg)',
          boxShadow: 'var(--shadow-lg)',
          overflow: 'hidden',
          maxHeight: 260,
          overflowY: 'auto',
        }}>
          {results.map((item, i) => (
            <button
              key={item.id || i}
              onClick={() => pick(item)}
              style={{
                display: 'block', width: '100%', textAlign: 'left',
                padding: 'var(--space-3) var(--space-4)',
                background: 'none', border: 'none', cursor: 'pointer',
                borderBottom: i < results.length - 1 ? '1px solid var(--color-border)' : 'none',
                transition: 'background 0.1s',
              }}
              onMouseEnter={e => e.currentTarget.style.background = 'var(--color-bg-island)'}
              onMouseLeave={e => e.currentTarget.style.background = 'none'}
            >
              <p style={{ margin: 0, fontWeight: 'var(--font-weight-medium)', color: 'var(--color-text-primary)', fontSize: 'var(--font-size-sm)' }}>{item.name}</p>
              {item.sub && <p style={{ margin: 0, color: 'var(--color-text-muted)', fontSize: 'var(--font-size-xs)' }}>{item.sub}</p>}
            </button>
          ))}
        </div>,
        document.body
      )}
    </div>
  )
}

// ─── CreateTicketModal ────────────────────────────────────────────────────────

export default function CreateTicketModal({
  open,
  onClose,
  onCreated,
  prefillCustomerId,
  prefillCustomerName,
  prefillDeviceId,
  prefillDeviceSerial,
}) {
  const { user } = useAuth()
  const { toast } = useToast()

  const [form, setForm] = useState({
    subject:    '',
    priority:   '',
    opened_via: 'staff',
  })

  // Picker state
  const [customer,     setCustomer]    = useState(null) // { id, name, subLine }
  const [device,       setDevice]      = useState(null) // { id, name, sub }
  const [linked_user,  setLinkedUser]  = useState(null) // { id, name, sub }

  // Browse modal
  const [browseType, setBrowseType] = useState(null) // 'customer' | 'device' | 'app_user'

  const [saving, setSaving] = useState(false)
  const [error,  setError]  = useState('')

  // Seed prefills on open
  useEffect(() => {
    if (!open) return
    setForm({ subject: '', priority: '', opened_via: 'staff' })
    setError('')
    setBrowseType(null)

    if (prefillCustomerId) {
      setCustomer({ id: prefillCustomerId, name: prefillCustomerName || prefillCustomerId, subLine: '' })
    } else {
      setCustomer(null)
    }

    if (prefillDeviceId) {
      setDevice({ id: prefillDeviceId, name: prefillDeviceSerial || prefillDeviceId, sub: '' })
    } else {
      setDevice(null)
    }

    setLinkedUser(null)
  }, [open, prefillCustomerId, prefillCustomerName, prefillDeviceId, prefillDeviceSerial])

  const set = (field) => (e) => setForm(prev => ({ ...prev, [field]: e.target.value }))

  const save = async () => {
    if (!form.subject.trim())  { setError('Subject is required.');  return }
    if (!customer?.id)         { setError('Customer is required.'); return }

    setSaving(true)
    setError('')
    try {
      const payload = {
        customer_id:   customer.id,
        customer_name: customer.name || null,
        device_id:     device?.id     || null,
        device_serial: device?.name   || null,   // name holds the serial for devices
        user_id:       linked_user?.id  || null,
        user_name:     linked_user?.name || null,
        subject:       form.subject.trim(),
        priority:      form.priority  || null,
        opened_via:    form.opened_via || null,
      }
      const created = await api.post('/tickets', payload)
      toast.success('Created', 'Support ticket opened.')
      onCreated(created)
    } catch (err) {
      setError(err.message || 'Failed to create ticket.')
    } finally {
      setSaving(false)
    }
  }

  return (
    <>
      <Modal
        open={open}
        onClose={onClose}
        title="New Support Ticket"
        size="md"
        footer={
          <div style={{ display: 'flex', gap: 'var(--space-3)', justifyContent: 'flex-end', width: '100%' }}>
            <Button variant="secondary" size="md" onClick={onClose}>Cancel</Button>
            <Button variant="primary" size="md" onClick={save} loading={saving}>Open Ticket</Button>
          </div>
        }
      >
        <div style={{ display: 'flex', flexDirection: 'column', gap: 'var(--space-5)' }}>
          {error && (
            <div style={{
              padding: 'var(--space-3) var(--space-4)',
              backgroundColor: 'var(--color-danger-bg)',
              border: '1px solid var(--color-danger)',
              borderRadius: 'var(--radius-md)',
              color: 'var(--color-danger)',
              fontSize: 'var(--font-size-sm)',
            }}>
              {error}
            </div>
          )}

          {/* Customer — searchable with 2-line display */}
          <CustomerSearchInput
            value={customer?.id}
            displayName={customer?.name}
            displaySub={customer?.subLine}
            onChange={setCustomer}
            onBrowse={() => setBrowseType('customer')}
          />

          {/* Subject */}
          <FormField
            label="Subject"
            name="subject"
            type="text"
            value={form.subject}
            onChange={set('subject')}
            placeholder="Brief summary of the issue…"
            required
          />

          {/* Linked Device + Linked User — search-based */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
            <EntitySearchInput
              label="Linked Device"
              entityType="device"
              value={device?.id}
              displayName={device?.name}
              onChange={setDevice}
              onBrowse={() => setBrowseType('device')}
            />
            <EntitySearchInput
              label="Linked User"
              entityType="app_user"
              value={linked_user?.id}
              displayName={linked_user?.name}
              onChange={setLinkedUser}
              onBrowse={() => setBrowseType('app_user')}
            />
          </div>

          {/* Priority + opened via */}
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 'var(--space-4)' }}>
            <FormField label="Priority" name="priority" type="select" value={form.priority} onChange={set('priority')}>
              {PRIORITY_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
            </FormField>

            <FormField label="Opened via" name="opened_via" type="select" value={form.opened_via} onChange={set('opened_via')}>
              {OPENED_VIA_OPTIONS.map(o => <option key={o.value} value={o.value}>{o.label}</option>)}
            </FormField>
          </div>
        </div>
      </Modal>

      {/* Browse modals — rendered outside main modal to avoid z-index stacking */}
      {browseType && (
        <BrowseModal
          open
          entityType={browseType}
          onPick={(picked) => {
            if (browseType === 'customer') setCustomer({ id: picked.id, name: picked.name, subLine: picked.sub })
            else if (browseType === 'device') setDevice(picked)
            else if (browseType === 'app_user') setLinkedUser(picked)
            setBrowseType(null)
          }}
          onClose={() => setBrowseType(null)}
        />
      )}
    </>
  )
}
