import { useState, useEffect, useRef } from 'react'
import { api } from '../api'

function AutocompleteInput({ value, onChange, onEnter, suggestions = [], className, placeholder }) {
  const [open, setOpen] = useState(false)
  const [highlighted, setHighlighted] = useState(0)
  const [dropPos, setDropPos] = useState(null)
  const inputRef = useRef()
  const listRef = useRef()
  const filtered = value
    ? suggestions.filter(s => s.toLowerCase().includes(value.toLowerCase()))
    : suggestions

  function openList() {
    if (inputRef.current) {
      const r = inputRef.current.getBoundingClientRect()
      setDropPos({ top: r.bottom + 2, left: r.left, minWidth: r.width })
    }
    setOpen(true)
    setHighlighted(0)
  }

  function select(val) { onChange(val); setOpen(false); inputRef.current?.focus() }

  function handleKeyDown(e) {
    if (e.altKey && e.key === 'ArrowDown') { e.preventDefault(); openList(); return }
    if (open && filtered.length > 0) {
      if (e.key === 'Tab')       { e.preventDefault(); setHighlighted(h => (h + 1) % filtered.length); return }
      if (e.key === 'ArrowDown') { e.preventDefault(); setHighlighted(h => Math.min(h + 1, filtered.length - 1)); return }
      if (e.key === 'ArrowUp')   { e.preventDefault(); setHighlighted(h => Math.max(h - 1, 0)); return }
      if (e.key === 'Enter')     { e.preventDefault(); select(filtered[highlighted]); return }
      if (e.key === 'Escape')    { setOpen(false); return }
    }
    if (e.key === 'Enter') onEnter?.()
  }

  useEffect(() => {
    if (!open || !listRef.current) return
    listRef.current.children[highlighted]?.scrollIntoView({ block: 'nearest' })
  }, [highlighted, open])

  return (
    <div className="relative">
      <input ref={inputRef} className={className} value={value} placeholder={placeholder}
        onChange={e => { onChange(e.target.value); if (e.target.value) openList() }}
        onKeyDown={handleKeyDown}
        onBlur={e => { if (!listRef.current?.contains(e.relatedTarget)) setOpen(false) }}
      />
      {open && filtered.length > 0 && dropPos && (
        <div ref={listRef}
          style={{ position: 'fixed', top: dropPos.top, left: dropPos.left, minWidth: dropPos.minWidth, zIndex: 9999 }}
          className="bg-white border border-gray-200 rounded shadow-lg max-h-40 overflow-y-auto">
          {filtered.map((s, i) => (
            <div key={s}
              className={`px-2 py-1 text-xs cursor-pointer whitespace-nowrap ${i === highlighted ? 'bg-blue-50 text-blue-700' : 'text-gray-700 hover:bg-gray-50'}`}
              onMouseDown={e => { e.preventDefault(); select(s) }}>{s}</div>
          ))}
        </div>
      )}
    </div>
  )
}

const DATE_RE = /^\d{4}-\d{2}-\d{2}(T[\d:.Z+-]+)?$/
// Hidden everywhere a field can be edited as an override — you can't override an id
const HIDDEN_COLS = new Set(['id', '_overridden'])
// The grid and its filters keep id: it's the only handle on a specific row
const GRID_HIDDEN_COLS = new Set(['_overridden'])

// id first, then the rest in view order
function gridCols(keys) {
  const visible = keys.filter(c => !GRID_HIDDEN_COLS.has(c))
  return visible.includes('id') ? ['id', ...visible.filter(c => c !== 'id')] : visible
}

function formatVal(val) {
  if (val === null || val === undefined) return null
  const s = String(val)
  if (DATE_RE.test(s)) {
    const d = new Date(s)
    if (!isNaN(d)) {
      const y = d.getUTCFullYear()
      const m = String(d.getUTCMonth() + 1).padStart(2, '0')
      const day = String(d.getUTCDate()).padStart(2, '0')
      return `${y}-${m}-${day}`
    }
  }
  return s
}

export default function Records({ source }) {
  const [rows, setRows] = useState([])
  const [cols, setCols] = useState([])
  const [exists, setExists] = useState(null)
  const [offset, setOffset] = useState(0)
  const [loading, setLoading] = useState(false)
  const [viewError, setViewError] = useState(null)
  const [sort, setSort] = useState({ col: null, dir: 'asc' })
  const [filters, setFilters] = useState([])  // DB sort/filter queries
  const [rowFilter, setRowFilter] = useState('')  // regex filter for selecting rows
  const [selected, setSelected] = useState(new Set())  // row IDs selected for bulk override
  const [bulkDraft, setBulkDraft] = useState({})  // bulk override values
  const LIMIT = 100

  // Override cols — loaded from DB once per source, extended by user via +
  const [overrideCols, setOverrideCols] = useState([])   // keys seen in overrides across all records
  const [extraCols, setExtraCols] = useState([])         // new cols added this session via +
  const [globalValues, setGlobalValues] = useState({})   // picklist suggestions

  // Override panel
  const [panelOpen, setPanelOpen] = useState(false)
  const [selectedRow, setSelectedRow] = useState(null)
  const [selectedRecord, setSelectedRecord] = useState(null)
  const [overrideDraft, setOverrideDraft] = useState({})
  const [panelLoading, setPanelLoading] = useState(false)
  const [panelSaving, setPanelSaving] = useState(false)
  const [panelMsg, setPanelMsg] = useState(null)
  const debounceRef = useRef(null)

  useEffect(() => {
    if (!source) return
    setOffset(0)
    setSort({ col: null, dir: 'asc' })
    setFilters([])
    setViewError(null)
    setSelectedRecord(null)
    setSelectedRow(null)
    setPanelOpen(false)
    setOverrideCols([])
    setExtraCols([])
    // Default to newest first on the source's first date field, if it has one
    api.getSource(source)
      .then(src => (src?.config?.fields || []).find(f => f.type === 'date')?.name || null)
      .catch(() => null)
      .then(dateCol => {
        if (dateCol) setSort({ col: dateCol, dir: 'desc' })
        load(0, dateCol, 'desc', [])
      })
    api.getOverrideKeys(source).then(setOverrideCols).catch(() => {})
    api.getGlobalValues().then(setGlobalValues).catch(() => {})
    setSelected(new Set())
    setBulkDraft({})
    setRowFilter('')
  }, [source])

  // Auto-select all rows matching the regex filter when it changes
  useEffect(() => {
    if (!rowFilter) return
    let re = null
    try { re = new RegExp(rowFilter, 'i') } catch { return }
    const matches = rows.filter(r => {
      for (const col of displayCols) {
        const val = r[col]
        if (val != null && re.test(String(val))) return true
      }
      return false
    })
    setSelected(new Set(matches.map(r => r.id)))
  }, [rowFilter, rows])

  async function load(off, col, dir, filt) {
    setLoading(true)
    try {
      const active = (filt || []).filter(f => f.col && f.pattern)
      const res = await api.getViewData(source, LIMIT, off, col, dir, active)
      setExists(res.exists)
      setRows(res.rows)
      if (res.rows.length > 0) setCols(Object.keys(res.rows[0]))
    } catch (err) {
      setViewError(err.message)
    } finally {
      setLoading(false)
    }
  }

  function triggerLoad(off, col, dir, filt) {
    clearTimeout(debounceRef.current)
    debounceRef.current = setTimeout(() => load(off, col, dir, filt), 350)
  }

  function toggleSort(col) {
    const next = sort.col === col
      ? { col, dir: sort.dir === 'asc' ? 'desc' : 'asc' }
      : { col, dir: 'asc' }
    setSort(next)
    setOffset(0)
    load(0, next.col, next.dir, filters)
  }

  function addFilter() {
    // id is filterable but a poor default — start on the first data column
    const visCols = gridCols(cols).filter(c => c !== 'id')
    setFilters(f => [...f, { col: visCols[0] || '', pattern: '' }])
  }

  function removeFilter(i) {
    const next = filters.filter((_, idx) => idx !== i)
    setFilters(next)
    setSelected(new Set())
    setOffset(0)
    load(0, sort.col, sort.dir, next)
  }

  function updateFilter(i, key, val) {
    const next = filters.map((f, idx) => idx === i ? { ...f, [key]: val } : f)
    setFilters(next)
    setSelected(new Set())
    setOffset(0)
    triggerLoad(0, sort.col, sort.dir, next)
  }

  function prev() { const o = Math.max(0, offset - LIMIT); setOffset(o); setSelected(new Set()); load(o, sort.col, sort.dir, filters) }
  function next() { const o = offset + LIMIT; setOffset(o); setSelected(new Set()); load(o, sort.col, sort.dir, filters) }

  async function openPanel(row) {
    setPanelOpen(true)
    setSelectedRow(row)
    setSelectedRecord(null)
    setOverrideDraft({})
    setPanelMsg(null)

    const id = row.id
    if (!id) {
      setPanelMsg({ text: 'No record ID — regenerate the view in Sources.', ok: false })
      return
    }

    setPanelLoading(true)
    try {
      const rec = await api.getRecord(id)
      setSelectedRecord(rec)
      setOverrideDraft(rec.overrides || {})
    } catch (err) {
      setPanelMsg({ text: err.message, ok: false })
    } finally {
      setPanelLoading(false)
    }
  }

  function closePanel() {
    setPanelOpen(false)
    setSelectedRow(null)
    setSelectedRecord(null)
    setOverrideDraft({})
    setPanelMsg(null)
  }

  async function handleSaveOverrides() {
    if (!selectedRecord) return
    setPanelSaving(true)
    setPanelMsg(null)
    try {
      const toSave = { ...overrideDraft }
      const updated = await api.setRecordOverrides(selectedRecord.id, toSave)
      setSelectedRecord(updated)
      setOverrideDraft(updated.overrides || {})
      // Merge any new cols from extraCols into overrideCols
      setOverrideCols(prev => [...new Set([...prev, ...extraCols.filter(c => c.trim())])])
      setExtraCols([])
      setPanelMsg({ text: 'Saved.', ok: true })
      load(offset, sort.col, sort.dir, filters)
    } catch (err) {
      setPanelMsg({ text: err.message, ok: false })
    } finally {
      setPanelSaving(false)
    }
  }

  async function handleClearOverrides() {
    if (!selectedRecord) return
    setPanelSaving(true)
    setPanelMsg(null)
    try {
      const updated = await api.clearRecordOverrides(selectedRecord.id)
      setSelectedRecord(updated)
      setOverrideDraft({})
      setPanelMsg({ text: 'Cleared.', ok: true })
      load(offset, sort.col, sort.dir, filters)
    } catch (err) {
      setPanelMsg({ text: err.message, ok: false })
    } finally {
      setPanelSaving(false)
    }
  }

  if (!source) return <div className="p-6 text-sm text-gray-400">Select a source first.</div>

  const displayCols = gridCols(rows.length > 0 ? Object.keys(rows[0]) : cols)
  const visCols = gridCols(cols)

  // For bulk bar: only established override keys
  const allOverrideCols = [...new Set([...overrideCols, ...extraCols])]

  const savedOverrides = selectedRecord?.overrides || {}
  const isDirty = Object.values(overrideDraft).some(v => String(v).trim())
    || extraCols.some(c => c.trim())
    || Object.keys(savedOverrides).some(k => !String(overrideDraft[k] ?? '').trim())

  return (
    <div className="flex h-full min-h-0 overflow-hidden">
      <div className="flex-1 overflow-auto p-6 min-w-0">
        <div className="flex items-center justify-between mb-4">
          <h1 className="text-xl font-semibold text-gray-800">Records — {source}</h1>
          {exists && rows.length > 0 && (
            <span className="text-xs text-gray-400 font-mono">dfv.{source}</span>
          )}
        </div>

        {/* Filter bar */}
        {exists !== false && visCols.length > 0 && (
          <div className="mb-4 flex flex-wrap gap-2 items-center">
            <span className="text-xs text-gray-400 font-medium mr-1">DB query:</span>
            {filters.map((f, i) => (
              <div key={i} className="flex items-center gap-1 bg-white border border-gray-200 rounded px-2 py-1">
                <select
                  className="text-xs text-gray-600 border-0 focus:outline-none bg-transparent"
                  value={f.col}
                  onChange={e => updateFilter(i, 'col', e.target.value)}
                >
                  {visCols.map(c => <option key={c} value={c}>{c}</option>)}
                </select>
                <span className="text-xs text-gray-300 mx-0.5">~*</span>
                <input
                  className="text-xs font-mono border-0 focus:outline-none w-36 bg-transparent"
                  placeholder="regex…"
                  value={f.pattern}
                  onChange={e => updateFilter(i, 'pattern', e.target.value)}
                />
                <button onClick={() => removeFilter(i)} className="text-gray-300 hover:text-gray-500 ml-1 leading-none">×</button>
              </div>
            ))}
            <button onClick={addFilter}
              className="text-xs text-gray-400 hover:text-gray-600 border border-dashed border-gray-200 rounded px-2 py-1">
              + filter
            </button>
            {filters.length > 0 && (
              <button onClick={() => { setFilters([]); setOffset(0); load(0, sort.col, sort.dir, []) }}
                className="text-xs text-gray-400 hover:text-red-500">clear</button>
            )}
          </div>
        )}

        {/* Bulk select + override bar */}
        {exists && visCols.length > 0 && (
          <div className="mb-4 flex flex-wrap gap-2 items-center">
            <span className="text-xs text-gray-400 font-medium mr-1">Bulk select:</span>
            <input
              className={`text-xs font-mono border rounded px-2 py-1.5 w-44 focus:outline-none focus:border-blue-400 ${
                rowFilter ? 'border-blue-300' : 'border-gray-200'
              }`}
              placeholder="regex on loaded rows…"
              value={rowFilter}
              onChange={e => setRowFilter(e.target.value)}
            />
            {rowFilter && (
              <span className="text-xs text-gray-400">{selected.size} of {rows.length} rows selected</span>
            )}
            {selected.size > 0 && (
              <div className="flex items-center gap-2 ml-4 p-2 bg-blue-50 border border-blue-200 rounded flex-wrap">
                {allOverrideCols.map(col => (
                  <AutocompleteInput
                    key={col}
                    className="border border-blue-300 rounded px-2 py-1 text-xs min-w-24 focus:outline-none focus:border-blue-500 bg-white"
                    placeholder={col}
                    value={bulkDraft[col] || ''}
                    onChange={v => setBulkDraft(d => ({ ...d, [col]: v }))}
                    suggestions={[...(globalValues[col] || [])].sort()}
                  />
                ))}
                <button
                  onClick={async () => {
                    const overrides = Object.fromEntries(
                      Object.entries(bulkDraft).filter(([, v]) => v.trim())
                    )
                    if (Object.keys(overrides).length === 0) return
                    if (selected.size === 0) return
                    setPanelSaving(true)
                    setPanelMsg(null)
                    try {
                      const res = await api.setBulkRecordOverrides(source, [...selected], overrides)
                      setSelected(new Set())
                      setBulkDraft({})
                      setPanelMsg({ text: `Updated ${res.updated} records.`, ok: true })
                      load(offset, sort.col, sort.dir, filters)
                    } catch (err) {
                      setPanelMsg({ text: err.message, ok: false })
                    } finally {
                      setPanelSaving(false)
                    }
                  }}
                  disabled={panelSaving || selected.size === 0 || Object.values(bulkDraft).every(v => !v.trim())}
                  className="text-xs bg-blue-600 text-white px-3 py-1 rounded hover:bg-blue-700 disabled:opacity-40 whitespace-nowrap"
                >
                  Apply to {selected.size}
                </button>
                <button
                  onClick={() => { setSelected(new Set()); setBulkDraft({}); setRowFilter('') }}
                  className="text-xs text-blue-400 hover:text-blue-600"
                >
                  cancel
                </button>
              </div>
            )}
          </div>
        )}

        {loading && <p className="text-sm text-gray-400">Loading…</p>}
        {!loading && viewError && <p className="text-sm text-red-500">View error: {viewError} — check field types in Sources.</p>}
        {!loading && exists === false && (
          <p className="text-sm text-gray-400">
            No view generated yet. Go to <span className="font-medium text-gray-600">Sources</span>, check fields as <span className="font-medium text-gray-600">In view</span>, then click <span className="font-medium text-gray-600">Generate view</span>.
          </p>
        )}
        {!loading && exists && rows.length === 0 && (
          <p className="text-sm text-gray-400">
            {filters.some(f => f.col && f.pattern) ? 'No records match the current filters.' : 'View exists but no transformed records yet. Import data and run a transform first.'}
          </p>
        )}

        {!loading && exists && rows.length > 0 && (
          <>
            <div className="bg-white border border-gray-200 rounded overflow-auto mb-4">
              <table className="w-full text-sm">
                <thead>
                  <tr className="text-left text-xs text-gray-400 border-b border-gray-100 bg-gray-50">
                    <th className="px-2 py-2 w-8">
                      <input
                        type="checkbox"
                        className="cursor-pointer"
                        checked={rows.length > 0 && rows.every(r => selected.has(r.id))}
                        onChange={e => {
                          if (e.target.checked) setSelected(new Set(rows.map(r => r.id)))
                          else setSelected(new Set())
                        }}
                      />
                    </th>
                    {displayCols.map(col => {
                      const active = sort.col === col
                      return (
                        <th key={col} onClick={() => toggleSort(col)}
                          className="px-3 py-2 font-medium whitespace-nowrap cursor-pointer select-none hover:text-gray-600">
                          {col}
                          <span className="ml-1 text-gray-300">{active ? (sort.dir === 'asc' ? '▲' : '▼') : '⇅'}</span>
                        </th>
                      )
                    })}
                  </tr>
                </thead>
                <tbody>
                  {rows.map((row, i) => {
                    const isOverridden = row._overridden
                    const isRowSelected = selected.has(row.id)
                    const isPanelSelected = selectedRow?.id != null && selectedRow.id === row.id
                    return (
                      <tr key={i} onClick={() => openPanel(row)}
                        className={`border-t border-gray-50 cursor-pointer transition-colors
                          ${isPanelSelected ? 'bg-blue-50' : isRowSelected ? 'bg-blue-50' : isOverridden ? 'bg-amber-50 hover:bg-amber-100' : 'hover:bg-gray-50'}`}>
                        <td className="px-2 py-2">
                          <input
                            type="checkbox"
                            className="cursor-pointer"
                            checked={isRowSelected}
                            onChange={e => {
                              e.stopPropagation()
                              setSelected(s => { const n = new Set(s); n.has(row.id) ? n.delete(row.id) : n.add(row.id); return n })
                            }}
                          />
                        </td>
                        {displayCols.map((col, j) => {
                          const formatted = formatVal(row[col])
                          return (
                            <td key={j} className="px-3 py-2 text-xs text-gray-600 whitespace-nowrap max-w-48 truncate">
                              {formatted === null ? <span className="text-gray-300">—</span> : formatted}
                            </td>
                          )
                        })}
                      </tr>
                    )
                  })}
                </tbody>
              </table>
            </div>

            <div className="flex items-center gap-3 text-sm text-gray-500">
              <button onClick={prev} disabled={offset === 0}
                className="px-3 py-1 border border-gray-200 rounded hover:bg-gray-50 disabled:opacity-40">← Prev</button>
              <span>{offset + 1}–{offset + rows.length}</span>
              <button onClick={next} disabled={rows.length < LIMIT}
                className="px-3 py-1 border border-gray-200 rounded hover:bg-gray-50 disabled:opacity-40">Next →</button>
            </div>
          </>
        )}
      </div>

      {/* Panel */}
      {panelOpen && (
        <div className="w-80 border-l border-gray-200 bg-white flex flex-col overflow-hidden flex-shrink-0">
          <div className="flex items-center justify-between px-3 py-2 border-b border-gray-100">
            <span className="text-xs font-semibold text-gray-600 uppercase tracking-wide">Record</span>
            <button onClick={closePanel} className="text-gray-300 hover:text-gray-500 leading-none text-lg">×</button>
          </div>

          {panelLoading && <p className="text-xs text-gray-400 p-3">Loading…</p>}

          {selectedRecord && !panelLoading && (
            <div className="flex-1 overflow-y-auto flex flex-col min-h-0">
              {panelMsg && (
                <div className={`text-xs px-3 py-2 border-b border-gray-100 ${panelMsg.ok ? 'text-green-600' : 'text-red-500'}`}>
                  {panelMsg.text}
                </div>
              )}

              {/* Raw fields — read only */}
              <div className="border-b border-gray-100">
                <div className="px-3 py-1.5 bg-gray-50 border-b border-gray-100">
                  <span className="text-xs font-medium text-gray-400 uppercase tracking-wide">Raw</span>
                </div>
                {Object.entries(selectedRecord.data || {}).map(([field, val]) => (
                  <div key={field} className="flex items-baseline gap-2 px-3 py-1 border-t border-gray-50 first:border-t-0">
                    <span className="text-xs font-mono text-gray-400 w-28 shrink-0 truncate">{field}</span>
                    <span className="text-xs font-mono text-gray-500 truncate">{formatVal(val) ?? <span className="text-gray-300">—</span>}</span>
                  </div>
                ))}
              </div>

              {/* Transformed fields — read only delta */}
              <div className="border-b border-gray-100">
                <div className="px-3 py-1.5 bg-gray-50 border-b border-gray-100">
                  <span className="text-xs font-medium text-gray-400 uppercase tracking-wide">Transformed</span>
                </div>
                {Object.entries(selectedRecord.transformed || {}).filter(([k]) => !HIDDEN_COLS.has(k)).length === 0
                  ? <div className="px-3 py-2 text-xs text-gray-300">No rule output yet.</div>
                  : Object.entries(selectedRecord.transformed || {}).filter(([k]) => !HIDDEN_COLS.has(k)).map(([field, val]) => (
                    <div key={field} className="flex items-baseline gap-2 px-3 py-1 border-t border-gray-50 first:border-t-0">
                      <span className="text-xs font-mono text-gray-400 w-28 shrink-0 truncate">{field}</span>
                      <span className="text-xs font-mono text-blue-600 truncate">{formatVal(val) ?? <span className="text-gray-300">—</span>}</span>
                    </div>
                  ))
                }
              </div>

              {/* Overrides — editable */}
              <div className="flex-1 border-b border-gray-100">
                <div className="flex items-center justify-between px-3 py-1.5 bg-gray-50 border-b border-gray-100">
                  <span className="text-xs font-medium text-gray-400 uppercase tracking-wide">Overrides</span>
                  <button
                    onClick={() => setExtraCols(ec => [...ec, ''])}
                    className="text-gray-400 hover:text-gray-700 font-medium text-sm leading-none"
                    title="Add field">+</button>
                </div>
                <table className="w-full text-xs">
                  <tbody>
                    {[...new Set([
                      ...Object.keys(selectedRecord.transformed || {}),
                      ...Object.keys(selectedRecord.overrides || {}),
                      ...overrideCols
                    ])].filter(k => !HIDDEN_COLS.has(k)).map(col => {
                      const override = overrideDraft[col] ?? ''
                      const placeholder = formatVal(selectedRecord.transformed?.[col]) ?? ''
                      const suggestions = [...(globalValues[col] || [])].sort()
                      return (
                        <tr key={col} className="border-t border-gray-50">
                          <td className="px-3 py-1.5 w-28 shrink-0">
                            <span className="font-mono text-gray-500 truncate block">{col}</span>
                          </td>
                          <td className="px-1 py-1.5">
                            <AutocompleteInput
                              className={`w-full text-xs font-mono px-2 py-0.5 rounded border focus:outline-none ${
                                override ? 'border-amber-300 bg-amber-50 text-amber-800' : 'border-gray-200 text-gray-600'
                              }`}
                              value={override}
                              placeholder={placeholder}
                              onChange={v => setOverrideDraft(d => ({ ...d, [col]: v }))}
                              onEnter={handleSaveOverrides}
                              suggestions={suggestions}
                            />
                          </td>
                          <td className="pr-2 text-center w-6">
                            {override && (
                              <button
                                onClick={() => setOverrideDraft(d => { const n = { ...d }; delete n[col]; return n })}
                                className="text-gray-300 hover:text-red-400 leading-none text-base">×</button>
                            )}
                          </td>
                        </tr>
                      )
                    })}
                    {extraCols.map((col, i) => {
                      const val = overrideDraft[col] ?? ''
                      const suggestions = [...(globalValues[col] || [])].sort()
                      return (
                        <tr key={`extra-${i}`} className="border-t border-gray-50">
                          <td className="px-3 py-1.5 w-28 shrink-0">
                            <input
                              className="w-full text-xs font-mono border border-gray-200 rounded px-1 py-0.5 focus:outline-none focus:border-blue-400"
                              value={col}
                              placeholder="field name"
                              onChange={e => {
                                const newName = e.target.value
                                setExtraCols(ec => { const c = [...ec]; c[i] = newName; return c })
                                if (val) setOverrideDraft(d => {
                                  const n = { ...d }
                                  delete n[col]
                                  if (newName) n[newName] = val
                                  return n
                                })
                              }}
                            />
                          </td>
                          <td className="px-1 py-1.5">
                            <AutocompleteInput
                              className={`w-full text-xs font-mono px-2 py-0.5 rounded border focus:outline-none ${
                                val ? 'border-amber-300 bg-amber-50 text-amber-800' : 'border-gray-200 text-gray-600'
                              }`}
                              value={val}
                              onChange={v => setOverrideDraft(d => ({ ...d, [col]: v }))}
                              onEnter={handleSaveOverrides}
                              suggestions={suggestions}
                            />
                          </td>
                          <td className="pr-2 text-center w-6">
                            {val && (
                              <button
                                onClick={() => setOverrideDraft(d => { const n = { ...d }; delete n[col]; return n })}
                                className="text-gray-300 hover:text-red-400 leading-none text-base">×</button>
                            )}
                          </td>
                        </tr>
                      )
                    })}
                  </tbody>
                </table>
              </div>

              <div className="flex gap-2 px-3 py-2 border-t border-gray-100 shrink-0">
                <button
                  onClick={handleSaveOverrides}
                  disabled={panelSaving || !isDirty}
                  className="flex-1 text-xs bg-blue-600 text-white rounded px-3 py-1.5 hover:bg-blue-700 disabled:opacity-40">
                  {panelSaving ? 'Saving…' : 'Save'}
                </button>
                {selectedRecord.overrides && Object.keys(selectedRecord.overrides).length > 0 && (
                  <button
                    onClick={handleClearOverrides}
                    disabled={panelSaving}
                    className="text-xs border border-gray-200 rounded px-3 py-1.5 text-gray-500 hover:border-red-300 hover:text-red-500 disabled:opacity-40">
                    Clear
                  </button>
                )}
              </div>
            </div>
          )}
        </div>
      )}
    </div>
  )
}
