import { useState, useEffect } from 'react'
import Timeline from '../components/Timeline.jsx'

const OPERATORS = ['BETWEEN', '=', '!=', 'IN', 'NOT IN', 'IS NULL', 'IS NOT NULL']

function buildCondition(c) {
  const col = `"${c.col}"`
  if (c.op === 'IS NULL')     return `${col} IS NULL`
  if (c.op === 'IS NOT NULL') return `${col} IS NOT NULL`
  if (c.op === 'BETWEEN') {
    const [a, b] = c.values
    if (!a || !b) return null
    return `${col} BETWEEN '${a}' AND '${b}'`
  }
  if (c.op === 'IN' || c.op === 'NOT IN') {
    const v = (c.values[0] || '').split(',').map(s => s.trim()).filter(Boolean)
    if (!v.length) return null
    return `${col} ${c.op} ('${v.join("','")}')`
  }
  if (!c.values[0]) return null
  return `${col} ${c.op} '${c.values[0]}'`
}

function buildFilterClause(groups) {
  if (!groups?.length) return null
  const parts = groups
    .map(g => g.map(buildCondition).filter(Boolean).join(' AND '))
    .filter(s => s.length > 0)
    .map(s => `(${s})`)
  if (!parts.length) return null
  return parts.join(' OR ')
}

function parseDateRangeFromClause(clause) {
  if (!clause) return null
  const m = clause.match(/BETWEEN '(\d{4}-\d{2}-\d{2})' AND '(\d{4}-\d{2}-\d{2})'/)
  if (m) return { from: m[1], to: m[2] }
  return null
}

function getDateRange(groups) {
  for (const g of groups || []) {
    for (const c of g) {
      if (c.op === 'BETWEEN' && c.values[0] && c.values[1]) return { from: c.values[0], to: c.values[1] }
      if (c.op === '=' && c.values[0]) return { from: c.values[0], to: c.values[0] }
    }
  }
  return null
}

function parseOffset(offsetStr) {
  if (!offsetStr || offsetStr === '0 days') return { yr: 0, mo: 0 }
  const yr = parseInt(offsetStr.match(/(\d+)\s+year/)?.[1] || 0)
  const mo = parseInt(offsetStr.match(/(\d+)\s+month/)?.[1] || 0)
  return { yr, mo }
}

function emptyCondition(cols) {
  return { col: cols[0]?.cname || '', op: 'BETWEEN', values: ['', ''] }
}
function emptyGroup(cols) { return [emptyCondition(cols)] }

function normalizeFilters(stored) {
  // accept legacy flat shape and wrap as one group; fall back to a blank group
  if (!Array.isArray(stored) || stored.length === 0) return null
  if (Array.isArray(stored[0])) return stored
  if (stored[0]?.col != null) return [stored]
  return null
}

export default function Baseline({ sources = [], sourceId, versions = [], versionId, setVersionId, refreshVersions }) {
  const [filterCols,     setFilterCols]     = useState([])
  const [log,            setLog]            = useState([])

  // new version form
  const [showNewVersion, setShowNewVersion] = useState(false)
  const [newVerName,     setNewVerName]     = useState('')
  const [newVerDesc,     setNewVerDesc]     = useState('')
  const [creatingVer,    setCreatingVer]    = useState(false)

  // segment form
  const [segType,        setSegType]        = useState('baseline')
  const [description,    setDescription]    = useState('')
  const [filters,        setFilters]        = useState([])  // [[cond,...], [cond,...]]
  const [useRaw,         setUseRaw]         = useState(false)
  const [rawSql,         setRawSql]         = useState('')
  const [offsetYr,       setOffsetYr]       = useState(0)
  const [offsetMo,       setOffsetMo]       = useState(0)
  const [segNote,        setSegNote]        = useState('')
  const [submitting,     setSubmitting]     = useState(false)
  const [editingLogId,   setEditingLogId]   = useState(null)
  const [showAddForm,    setShowAddForm]    = useState(false)
  const [hasForecastOps, setHasForecastOps] = useState(false)

  const [expandedId,     setExpandedId]     = useState(null)
  const [msg,            setMsg]            = useState(null)

  useEffect(() => {
    if (!sourceId) return
    fetch(`/api/sources/${sourceId}/cols`).then(r => r.json()).then(cols => {
      const fc = cols.filter(c => c.role === 'date' || c.role === 'filter')
      setFilterCols(fc)
      setFilters(fc.length > 0 ? [emptyGroup(fc)] : [])
    })
  }, [sourceId])

  useEffect(() => {
    if (!versionId) { setLog([]); return }
    loadLog()
  }, [versionId])

  function loadLog() {
    fetch(`/api/versions/${versionId}/log`).then(r => r.json()).then(data => {
      setLog(data.filter(e => e.operation === 'baseline' || e.operation === 'reference'))
      setHasForecastOps(data.some(e => ['scale', 'recode', 'clone'].includes(e.operation)))
    })
  }

  async function createVersion() {
    if (!newVerName.trim()) return
    setCreatingVer(true)
    try {
      const res = await fetch(`/api/sources/${sourceId}/versions`, {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ name: newVerName.trim(), description: newVerDesc, created_by: 'admin' })
      })
      const data = await res.json()
      if (!res.ok) { flash(data.error, 'error'); return }
      await refreshVersions(sourceId)
      setVersionId(String(data.id))
      setShowNewVersion(false)
      setNewVerName('')
      setNewVerDesc('')
      flash(`Version "${data.name}" created`)
    } catch (err) {
      flash(err.message, 'error')
    } finally {
      setCreatingVer(false)
    }
  }

  async function loadSegment() {
    const clause = useRaw ? rawSql.trim() : buildFilterClause(filters)
    if (!clause) { flash(useRaw ? 'Enter a WHERE clause' : 'Add at least one filter', 'error'); return }
    const isRef = segType === 'reference'
    const offsetStr = [offsetYr > 0 ? `${offsetYr} year` : '', offsetMo > 0 ? `${offsetMo} month` : ''].filter(Boolean).join(' ') || '0 days'
    const endpoint = isRef ? 'reference' : 'baseline'
    const body = {
      where_clause: clause,
      pf_user: 'admin',
      note: description || segNote,
      date_offset: offsetStr,
      ...(useRaw ? { raw_where: clause } : { filters }),
    }
    setSubmitting(true)
    try {
      const url    = editingLogId
        ? `/api/versions/${versionId}/baseline/${editingLogId}`
        : `/api/versions/${versionId}/${endpoint}`
      const method = editingLogId ? 'PUT' : 'POST'
      const res = await fetch(url, {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(body)
      })
      const data = await res.json()
      if (!res.ok) { flash(data.error, 'error'); return }
      flash(editingLogId
        ? `Updated — ${data.rows_deleted} rows replaced with ${data.rows_affected}`
        : `Loaded ${data.rows_affected ?? data.row_count ?? ''} rows`)
      loadLog()
      cancelEdit()
    } catch (err) {
      flash(err.message, 'error')
    } finally {
      setSubmitting(false)
    }
  }

  function startEdit(entry) {
    if (hasForecastOps) {
      flash('Undo forecast operations first to edit segments', 'error')
      return
    }
    const params = entry.params || {}
    setSegType(entry.operation)
    setSegNote(entry.note || '')
    setDescription('')
    const off = parseOffset(params.date_offset)
    setOffsetYr(off.yr)
    setOffsetMo(off.mo)
    const groups = normalizeFilters(params.filters)
    if (groups) {
      setUseRaw(false)
      setRawSql('')
      setFilters(groups)
    } else if (params.where_clause) {
      // legacy: only the compiled WHERE was stored. Open in raw mode.
      setUseRaw(true)
      setRawSql(params.where_clause)
      setFilters(filterCols.length > 0 ? [emptyGroup(filterCols)] : [])
    } else {
      setUseRaw(false)
      setRawSql('')
      setFilters(filterCols.length > 0 ? [emptyGroup(filterCols)] : [])
    }
    setEditingLogId(entry.id)
    setExpandedId(null)
    setTimeout(() => {
      document.getElementById('add-segment')?.scrollIntoView({ behavior: 'smooth', block: 'start' })
    }, 0)
  }

  function cancelEdit() {
    setEditingLogId(null)
    setShowAddForm(false)
    setDescription('')
    setSegNote('')
    setOffsetYr(0)
    setOffsetMo(0)
    setUseRaw(false)
    setRawSql('')
    setFilters(filterCols.length > 0 ? [emptyGroup(filterCols)] : [])
  }

  async function undoSegment(logid) {
    await fetch(`/api/log/${logid}`, { method: 'DELETE' })
    loadLog()
    flash('Segment undone')
  }

  async function clearBaseline() {
    if (!confirm('Delete all baseline rows for this version?')) return
    const res = await fetch(`/api/versions/${versionId}/baseline`, { method: 'DELETE' })
    const data = await res.json()
    if (!res.ok) { flash(data.error, 'error'); return }
    loadLog()
    flash(`Cleared ${data.rows_deleted} rows`)
  }

  async function closeVersion() {
    const res = await fetch(`/api/versions/${versionId}/close`, {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ pf_user: 'admin' })
    })
    const data = await res.json()
    if (!res.ok) { flash(data.error, 'error'); return }
    await refreshVersions(sourceId)
    flash('Version closed')
  }

  async function reopenVersion() {
    const res = await fetch(`/api/versions/${versionId}/reopen`, { method: 'POST' })
    const data = await res.json()
    if (!res.ok) { flash(data.error, 'error'); return }
    await refreshVersions(sourceId)
    flash('Version reopened')
  }

  async function deleteVersion() {
    if (!confirm(`Delete version "${selectedVersion?.name}"? This drops the forecast table and cannot be undone.`)) return
    const res = await fetch(`/api/versions/${versionId}`, { method: 'DELETE' })
    const data = await res.json()
    if (!res.ok) { flash(data.error, 'error'); return }
    const updated = await refreshVersions(sourceId)
    setVersionId(updated.length > 0 ? String(updated[0].id) : '')
    flash('Version deleted')
  }

  function flash(text, type = 'ok') {
    setMsg({ text, type })
    setTimeout(() => setMsg(null), 3000)
  }

  const selectedVersion = versions.find(v => String(v.id) === versionId)

  return (
    <div className="h-full overflow-y-auto bg-gray-50">
      <div className="p-4 flex flex-col gap-4 max-w-4xl">

        {msg && (
          <div className={`px-3 py-2 text-xs rounded font-medium ${msg.type === 'error' ? 'bg-red-50 text-red-700' : 'bg-green-50 text-green-700'}`}>
            {msg.text}
          </div>
        )}

        {/* Version actions */}
        <div className="flex items-center gap-3 flex-wrap">
          <button onClick={() => setShowNewVersion(v => !v)} className="text-xs text-blue-600 hover:text-blue-700 border border-blue-200 px-2 py-1 rounded">
            + New version
          </button>
          {versionId && (
            <div className="flex items-center gap-2">
              {selectedVersion?.status === 'open'
                ? <button onClick={closeVersion} className="text-xs text-gray-500 hover:text-gray-700 border border-gray-200 px-2 py-1 rounded">Close</button>
                : <button onClick={reopenVersion} className="text-xs text-gray-500 hover:text-gray-700 border border-gray-200 px-2 py-1 rounded">Reopen</button>
              }
              <button onClick={deleteVersion} className="text-xs text-red-400 hover:text-red-600 border border-red-200 px-2 py-1 rounded">Delete</button>
            </div>
          )}
        </div>

        {showNewVersion && (
          <div className="bg-white border border-gray-200 rounded p-3 flex flex-col gap-3">
            <div className="flex items-end gap-3">
              <div className="flex flex-col gap-1">
                <label className="text-xs text-gray-500">Name</label>
                <input value={newVerName} onChange={e => setNewVerName(e.target.value)} placeholder="e.g. FY2026 Plan" className="border border-gray-200 rounded px-2 py-1 text-sm w-48" />
              </div>
              <div className="flex flex-col gap-1 flex-1">
                <label className="text-xs text-gray-500">Description</label>
                <input value={newVerDesc} onChange={e => setNewVerDesc(e.target.value)} placeholder="optional" className="border border-gray-200 rounded px-2 py-1 text-sm" />
              </div>
              <button onClick={createVersion} disabled={creatingVer || !newVerName.trim()} className="bg-blue-600 text-white text-xs px-3 py-1.5 rounded hover:bg-blue-700 disabled:opacity-50 shrink-0">
                {creatingVer ? 'Creating table…' : 'Create'}
              </button>
              <button onClick={() => setShowNewVersion(false)} className="text-gray-400 hover:text-gray-600 text-xs shrink-0">Cancel</button>
            </div>
            <div className="text-xs text-gray-400 border-t border-gray-100 pt-2">
              Creates a forecast table <span className="font-mono text-gray-500">pf.fc_{sources.find(s=>String(s.id)===sourceId)?.tname}_&lt;id&gt;</span> in the database from the current col meta. If col meta changes after creation the table and SQL will be out of sync — delete and recreate the version to realign.
            </div>
          </div>
        )}

        {versionId && <>

          {/* Segments loaded */}
          <div className="bg-white border border-gray-200 rounded">
            <div className="px-3 py-2 border-b border-gray-100 text-xs font-medium text-gray-500 uppercase tracking-wide flex items-center justify-between">
              <span>Segments loaded</span>
              <button onClick={clearBaseline} className="text-red-400 hover:text-red-600 text-xs normal-case font-normal">Clear all baseline</button>
            </div>
            <table className="w-full text-xs">
              <thead className="bg-gray-50">
                <tr className="text-left text-gray-400 border-b border-gray-100">
                  <th className="px-3 py-1.5 font-medium w-6"></th>
                  <th className="px-3 py-1.5 font-medium">#</th>
                  <th className="px-3 py-1.5 font-medium">note</th>
                  <th className="px-3 py-1.5 font-medium text-right">rows</th>
                  <th className="px-3 py-1.5 font-medium text-right">{log[0]?.value_col || 'value'}</th>
                  <th className="px-3 py-1.5 font-medium">by</th>
                  <th className="px-3 py-1.5 font-medium">when</th>
                  <th className="px-3 py-1.5 font-medium"></th>
                </tr>
              </thead>
              <tbody>
                {log.length === 0 && (
                  <tr><td colSpan={8} className="px-3 py-3 text-gray-300 italic">No segments loaded yet</td></tr>
                )}
                {!showAddForm && !editingLogId && (
                  <tr className="border-t border-gray-100">
                    <td colSpan={8} className="p-0">
                      <button
                        onClick={() => setShowAddForm(true)}
                        className="w-full px-3 py-2 text-xs text-blue-600 hover:bg-blue-50 text-left font-medium"
                      >
                        + Add segment
                      </button>
                    </td>
                  </tr>
                )}
                {log.map((entry, i) => {
                  const isOpen = expandedId === entry.id
                  const view = segmentValuesFor(entry, filterCols)
                  return (
                    <>
                      <tr
                        key={entry.id}
                        onClick={() => setExpandedId(isOpen ? null : entry.id)}
                        className={`border-t border-gray-50 cursor-pointer hover:bg-gray-50 ${editingLogId === entry.id ? 'bg-amber-50 ring-1 ring-amber-300 ring-inset' : isOpen ? 'bg-blue-50' : ''}`}
                      >
                        <td className="px-3 py-2 text-gray-400 w-6"><span className="text-gray-300 text-xs">{isOpen ? '▾' : '▸'}</span></td>
                        <td className="px-3 py-2 text-gray-400">{log.length - i}</td>
                        <td className="px-3 py-2">
                          <span className={`inline-block mr-2 px-1.5 py-0.5 rounded text-xs font-medium ${entry.operation === 'reference' ? 'bg-purple-50 text-purple-600' : 'bg-blue-50 text-blue-600'}`}>
                            {entry.operation}
                          </span>
                          {entry.note || <span className="text-gray-300">—</span>}
                        </td>
                        <td className="px-3 py-2 text-right text-gray-700 font-mono">
                          {entry.row_count != null ? entry.row_count.toLocaleString() : '—'}
                        </td>
                        <td className="px-3 py-2 text-right text-gray-700 font-mono">
                          {entry.value_total != null ? entry.value_total.toLocaleString(undefined, { maximumFractionDigits: 0 }) : '—'}
                        </td>
                        <td className="px-3 py-2 text-gray-500">{entry.pf_user}</td>
                        <td className="px-3 py-2 text-gray-400">{new Date(entry.stamp).toLocaleDateString()}</td>
                        <td className="px-3 py-2 text-right">
                          {!hasForecastOps && (
                            <button onClick={e => { e.stopPropagation(); startEdit(entry) }} className="text-gray-400 hover:text-blue-600 text-xs mr-3">Edit</button>
                          )}
                          <button onClick={e => { e.stopPropagation(); undoSegment(entry.id) }} className="text-gray-400 hover:text-red-500 text-xs">Undo</button>
                        </td>
                      </tr>
                      {isOpen && (
                        <tr key={`${entry.id}-detail`} className="bg-blue-50 border-t border-blue-100">
                          <td colSpan={6} className="px-2 py-2">
                            <div className="bg-white border border-gray-200 rounded">
                              <SegmentForm mode="view" {...view} filterCols={filterCols} />
                            </div>
                          </td>
                        </tr>
                      )}
                    </>
                  )
                })}
              </tbody>
            </table>
          </div>

          {/* Add / Edit Segment */}
          {(showAddForm || editingLogId) && (
            <div id="add-segment" className={`bg-white border rounded ${editingLogId ? 'border-amber-300' : 'border-gray-200'}`}>
              <div className={`px-3 py-2 border-b text-xs font-medium uppercase tracking-wide flex items-center justify-between ${editingLogId ? 'bg-amber-50 border-amber-200 text-amber-800' : 'bg-white border-gray-100 text-gray-500'}`}>
                <span>{(() => {
                  if (!editingLogId) return 'Add Segment'
                  const idx = log.findIndex(e => e.id === editingLogId)
                  if (idx < 0) return 'Edit Segment'
                  const entry  = log[idx]
                  const segNum = log.length - idx
                  const label  = entry.operation === 'reference' ? 'reference' : 'baseline'
                  return entry.note
                    ? `Edit segment #${segNum} — ${label} — ${entry.note}`
                    : `Edit segment #${segNum} — ${label}`
                })()}</span>
                <button onClick={cancelEdit} className="text-gray-400 hover:text-gray-600 normal-case font-normal">
                  {editingLogId ? 'Cancel edit' : 'Close'}
                </button>
              </div>
              <SegmentForm
                mode="edit"
                segType={segType} setSegType={setSegType}
                filters={filters} setFilters={setFilters}
                useRaw={useRaw} setUseRaw={setUseRaw}
                rawSql={rawSql} setRawSql={setRawSql}
                description={description} setDescription={setDescription}
                segNote={segNote} setSegNote={setSegNote}
                offsetYr={offsetYr} setOffsetYr={setOffsetYr}
                offsetMo={offsetMo} setOffsetMo={setOffsetMo}
                filterCols={filterCols}
                onSubmit={loadSegment}
                submitting={submitting}
                editing={!!editingLogId}
              />
            </div>
          )}

        </>}

      </div>
    </div>
  )
}

// derive view-mode props for a saved segment
function segmentValuesFor(entry, filterCols) {
  const params = entry.params || {}
  const off = parseOffset(params.date_offset)
  const groups = normalizeFilters(params.filters)
  return {
    segType: entry.operation === 'reference' ? 'reference' : 'baseline',
    filters: groups || (filterCols.length > 0 ? [emptyGroup(filterCols)] : []),
    useRaw: !groups && !!params.where_clause,
    rawSql: params.where_clause || '',
    description: '',
    segNote: entry.note || '',
    offsetYr: off.yr,
    offsetMo: off.mo,
  }
}

function SegmentForm({
  mode,                // 'view' | 'edit'
  segType, setSegType,
  filters, setFilters,
  useRaw, setUseRaw,
  rawSql, setRawSql,
  description, setDescription,
  segNote, setSegNote,
  offsetYr, setOffsetYr,
  offsetMo, setOffsetMo,
  filterCols,
  onSubmit,
  submitting,
  editing,
}) {
  const disabled  = mode === 'view'
  const compiled  = useRaw ? rawSql : (buildFilterClause(filters) || '')
  const dateRange = useRaw ? parseDateRangeFromClause(rawSql) : getDateRange(filters)

  function setGroup(gi, fn) {
    setFilters(prev => prev.map((g, i) => i === gi ? fn(g) : g))
  }
  function addCondition(gi)   { setGroup(gi, g => [...g, emptyCondition(filterCols)]) }
  function removeCondition(gi, ci) {
    setFilters(prev => {
      const next = prev.map((g, i) => i === gi ? g.filter((_, j) => j !== ci) : g)
      return next.filter(g => g.length > 0)
    })
  }
  function updateCondition(gi, ci, field, value) {
    setGroup(gi, g => g.map((c, j) => {
      if (j !== ci) return c
      if (field === 'op') {
        const needsTwo  = value === 'BETWEEN'
        const needsNone = ['IS NULL', 'IS NOT NULL'].includes(value)
        return { ...c, op: value, values: needsNone ? [] : needsTwo ? ['', ''] : [''] }
      }
      return { ...c, [field]: value }
    }))
  }
  function updateConditionValue(gi, ci, vi, value) {
    setGroup(gi, g => g.map((c, j) => {
      if (j !== ci) return c
      const vals = [...c.values]; vals[vi] = value
      return { ...c, values: vals }
    }))
  }
  function addGroup() { setFilters(prev => [...prev, emptyGroup(filterCols)]) }
  function removeGroup(gi) { setFilters(prev => prev.filter((_, i) => i !== gi)) }
  function toggleRaw() {
    if (useRaw) {
      setUseRaw(false)
      setRawSql('')
    } else {
      setRawSql(compiled)
      setUseRaw(true)
    }
  }

  const baseInp = 'border border-gray-200 rounded px-2 py-1 text-xs bg-white disabled:bg-gray-50 disabled:text-gray-500'

  return (
    <div className="p-4 flex flex-col gap-4">

      {/* Type */}
      <div className="flex items-center gap-3">
        <label className="text-xs text-gray-500 w-28 shrink-0">Type</label>
        <div className="flex rounded border border-gray-200 overflow-hidden text-xs">
          {['baseline', 'reference'].map(t => (
            <button
              key={t}
              disabled={disabled}
              onClick={() => { if (disabled) return; setSegType(t); if (t === 'reference') { setOffsetYr(0); setOffsetMo(0) } }}
              className={`px-3 py-1 capitalize ${segType === t ? 'bg-blue-600 text-white' : 'bg-white text-gray-500 hover:bg-gray-50'} disabled:opacity-60 disabled:cursor-default`}
            >{t}</button>
          ))}
        </div>
      </div>

      {/* Description (edit only) */}
      {mode === 'edit' && (
        <div className="flex items-center gap-3">
          <label className="text-xs text-gray-500 w-28 shrink-0">Description</label>
          <input value={description} onChange={e => setDescription(e.target.value)} placeholder="e.g. FY25 actuals +1yr" className="border border-gray-200 rounded px-2 py-1.5 text-sm flex-1 max-w-sm" />
        </div>
      )}

      {/* Filters */}
      <div>
        <div className="flex items-center justify-between mb-2">
          <label className="text-xs text-gray-500 w-28 shrink-0">Filters</label>
          {!disabled && (
            <button onClick={toggleRaw} className="text-blue-600 hover:text-blue-700 text-xs font-medium">
              {useRaw ? '← Back to filters' : 'Switch to manual SQL →'}
            </button>
          )}
        </div>

        {!useRaw && (
          <div className="flex flex-col gap-3 ml-28">
            {filters.map((group, gi) => (
              <div key={gi} className="border border-gray-200 rounded">
                <div className="flex items-center justify-between px-2 py-1 bg-gray-50 border-b border-gray-100">
                  <span className="text-xs text-gray-500">
                    {gi === 0 ? 'Group 1' : `Group ${gi + 1} — OR`}
                  </span>
                  {!disabled && (
                    <div className="flex items-center gap-3">
                      <button onClick={() => addCondition(gi)} className="text-blue-600 hover:text-blue-700 text-xs">+ AND condition</button>
                      {filters.length > 1 && (
                        <button onClick={() => removeGroup(gi)} className="text-gray-300 hover:text-red-400 text-xs">remove group</button>
                      )}
                    </div>
                  )}
                </div>
                <div className="flex flex-col gap-1.5 p-2">
                  {group.map((c, ci) => {
                    const isDateCol = filterCols.find(fc => fc.cname === c.col)?.role === 'date'
                    return (
                      <div key={ci} className="flex items-center gap-2 flex-wrap">
                        <select disabled={disabled} value={c.col} onChange={e => updateCondition(gi, ci, 'col', e.target.value)} className={baseInp}>
                          {filterCols.map(fc => <option key={fc.cname} value={fc.cname}>{fc.cname}</option>)}
                        </select>
                        <select disabled={disabled} value={c.op} onChange={e => updateCondition(gi, ci, 'op', e.target.value)} className={baseInp}>
                          {OPERATORS.map(op => <option key={op} value={op}>{op}</option>)}
                        </select>
                        {c.op === 'BETWEEN' && <>
                          <input disabled={disabled} type={isDateCol ? 'date' : 'text'} value={c.values[0] || ''} onChange={e => updateConditionValue(gi, ci, 0, e.target.value)} placeholder="from" className={`${baseInp} w-36 font-mono`} />
                          <span className="text-gray-400 text-xs">and</span>
                          <input disabled={disabled} type={isDateCol ? 'date' : 'text'} value={c.values[1] || ''} onChange={e => updateConditionValue(gi, ci, 1, e.target.value)} placeholder="to" className={`${baseInp} w-36 font-mono`} />
                        </>}
                        {(c.op === '=' || c.op === '!=') && (
                          <input disabled={disabled} type={isDateCol ? 'date' : 'text'} value={c.values[0] || ''} onChange={e => updateConditionValue(gi, ci, 0, e.target.value)} placeholder="value" className={`${baseInp} w-36 font-mono`} />
                        )}
                        {(c.op === 'IN' || c.op === 'NOT IN') && (
                          <input disabled={disabled} value={c.values[0] || ''} onChange={e => updateConditionValue(gi, ci, 0, e.target.value)} placeholder="val1, val2, …" className={`${baseInp} w-48 font-mono`} />
                        )}
                        {!disabled && group.length > 1 && (
                          <button onClick={() => removeCondition(gi, ci)} className="text-gray-300 hover:text-red-400 text-xs">✕</button>
                        )}
                      </div>
                    )
                  })}
                </div>
              </div>
            ))}
            {!disabled && (
              <button onClick={addGroup} className="self-start text-blue-600 hover:text-blue-700 text-xs font-medium">+ Add OR group</button>
            )}
            {filters.length === 0 && (
              <span className="text-xs text-gray-300 italic">No filters — at least one is required</span>
            )}
          </div>
        )}

        {useRaw && (
          <div className="ml-28">
            <textarea
              disabled={disabled}
              value={rawSql}
              onChange={e => setRawSql(e.target.value)}
              placeholder="WHERE clause body (no WHERE keyword) — e.g. (status = 'OPEN' AND order_date BETWEEN '2024-01-01' AND '2024-12-31') OR id IS NULL"
              rows={3}
              className={`w-full border border-gray-200 rounded px-2 py-1.5 text-xs font-mono bg-white disabled:bg-gray-50 disabled:text-gray-500`}
            />
            {!disabled && (
              <p className="text-xs text-amber-700 mt-1">Raw SQL is not validated. You are responsible for correctness and security.</p>
            )}
          </div>
        )}

        {/* Compiled SQL preview (only meaningful when not in raw mode) */}
        {!useRaw && (
          <div className="ml-28 mt-2 flex items-start gap-2">
            <span className="text-xs text-gray-400 w-12 shrink-0 pt-0.5">SQL</span>
            <code className="text-xs font-mono text-gray-700 bg-gray-50 border border-gray-200 rounded px-2 py-1 flex-1 break-all">
              {compiled || <span className="text-gray-300 not-italic">— add a condition —</span>}
            </code>
          </div>
        )}
      </div>

      {/* Date offset */}
      <div className="flex items-center gap-3">
        <label className="text-xs text-gray-500 w-28 shrink-0">Date offset</label>
        <div className="flex items-center gap-2">
          <input disabled={disabled} type="number" value={offsetYr} min={0} onChange={e => setOffsetYr(parseInt(e.target.value) || 0)} className={`${baseInp} text-sm w-16 text-center`} />
          <span className="text-xs text-gray-500">yr</span>
          <input disabled={disabled} type="number" value={offsetMo} min={0} max={11} onChange={e => setOffsetMo(parseInt(e.target.value) || 0)} className={`${baseInp} text-sm w-16 text-center`} />
          <span className="text-xs text-gray-500">mo</span>
        </div>
      </div>

      {/* Timeline */}
      {dateRange && (
        <div className="ml-28">
          <div className="bg-gray-50 border border-gray-200 rounded p-3">
            <Timeline
              dateFrom={dateRange.from}
              dateTo={dateRange.to}
              offsetYr={offsetYr}
              offsetMo={offsetMo}
              type={segType}
            />
          </div>
        </div>
      )}

      {/* Note + submit */}
      <div className="flex items-end gap-3">
        <div className="flex flex-col gap-1 flex-1 max-w-xs">
          <label className="text-xs text-gray-500">Note</label>
          <input disabled={disabled} value={segNote} onChange={e => setSegNote(e.target.value)} placeholder="optional" className={`${baseInp} text-sm py-1.5`} />
        </div>
        {mode === 'edit' && (
          <button onClick={onSubmit} disabled={submitting || (!useRaw && filters.length === 0)} className="bg-blue-600 text-white text-xs px-5 py-2 rounded hover:bg-blue-700 disabled:opacity-50 shrink-0">
            {submitting
              ? (editing ? 'Saving…' : 'Loading…')
              : (editing
                  ? `Save ${segType === 'reference' ? 'Reference' : 'Segment'}`
                  : `Load ${segType === 'reference' ? 'Reference' : 'Segment'}`)}
          </button>
        )}
      </div>
    </div>
  )
}
