import { useState, useEffect } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import toast from 'react-hot-toast'
import client from '../api/client'
import ConfirmModal from '../components/ConfirmModal'

const EMPTY_PRODUCT = {
  name: '', category_id: '', base_price: '', is_available: true, lifecycle_status: 'active',
  printer_zone_id: '', quick_options: [], options: [], ingredients: [], preference_sets: [],
}

const COLORS = ['#6366f1','#0ea5e9','#10b981','#f59e0b','#ef4444','#ec4899','#8b5cf6','#14b8a6','#f97316','#64748b']

function ColorPicker({ value, onChange }) {
  return (
    <div className="flex flex-wrap gap-2 mt-1">
      {COLORS.map(c => (
        <button key={c} type="button" onClick={() => onChange(c)}
          className="w-7 h-7 rounded-full border-2 transition-all"
          style={{ background: c, borderColor: value === c ? '#000' : 'transparent' }}
        />
      ))}
    </div>
  )
}

function IconBase({ className = '', viewBox, strokeWidth = '1.5', children }) {
  return (
    <svg
      aria-hidden="true"
      viewBox={viewBox}
      fill="none"
      xmlns="http://www.w3.org/2000/svg"
      className={`inline-block shrink-0 ${className}`}
      stroke="currentColor"
      strokeWidth={strokeWidth}
      strokeLinecap="round"
      strokeLinejoin="round"
    >
      {children}
    </svg>
  )
}

function AddIcon({ className = '' }) {
  return (
    <IconBase className={className} viewBox="0 0 24 24">
      <path d="M15 12H9" />
      <path d="M12 9V15" />
      <path d="M22 12C22 16.714 22 19.0711 20.5355 20.5355C19.0711 22 16.714 22 12 22C7.28595 22 4.92893 22 3.46447 20.5355C2 19.0711 2 16.714 2 12C2 7.28595 2 4.92893 3.46447 3.46447C4.92893 2 7.28595 2 12 2C16.714 2 19.0711 2 20.5355 3.46447C21.5093 4.43821 21.8356 5.80655 21.9449 8" />
    </IconBase>
  )
}

function MoveUpIcon({ className = '' }) {
  return (
    <IconBase className={className} viewBox="-0.5 0 25 25">
      <path d="M12 22.4199C17.5228 22.4199 22 17.9428 22 12.4199C22 6.89707 17.5228 2.41992 12 2.41992C6.47715 2.41992 2 6.89707 2 12.4199C2 17.9428 6.47715 22.4199 12 22.4199Z" />
      <path d="M8 13.8599L10.87 10.8C11.0125 10.6416 11.1868 10.5149 11.3815 10.4282C11.5761 10.3415 11.7869 10.2966 12 10.2966C12.2131 10.2966 12.4239 10.3415 12.6185 10.4282C12.8132 10.5149 12.9875 10.6416 13.13 10.8L16 13.8599" />
    </IconBase>
  )
}

function MoveDownIcon({ className = '' }) {
  return (
    <IconBase className={className} viewBox="-0.5 0 25 25">
      <path d="M12 22.4199C17.5228 22.4199 22 17.9428 22 12.4199C22 6.89707 17.5228 2.41992 12 2.41992C6.47715 2.41992 2 6.89707 2 12.4199C2 17.9428 6.47715 22.4199 12 22.4199Z" />
      <path d="M16 10.99L13.13 14.05C12.9858 14.2058 12.811 14.3298 12.6166 14.4148C12.4221 14.4998 12.2122 14.5437 12 14.5437C11.7878 14.5437 11.5779 14.4998 11.3834 14.4148C11.189 14.3298 11.0142 14.2058 10.87 14.05L8 10.99" />
    </IconBase>
  )
}

function EditIcon({ className = '' }) {
  return (
    <IconBase className={className} viewBox="0 0 24 24">
      <path d="M18 10L14 6M18 10L21 7L17 3L14 6M18 10L17 11M14 6L8 12V16H12L14.5 13.5M20 14V20H12M10 4L4 4L4 20H7" />
    </IconBase>
  )
}

function DeleteIcon({ className = '' }) {
  return (
    <IconBase className={className} viewBox="0 0 24 24" strokeWidth="2">
      <path d="M10 11V17" />
      <path d="M14 11V17" />
      <path d="M4 7H20" />
      <path d="M6 7H12H18V18C18 19.6569 16.6569 21 15 21H9C7.34315 21 6 19.6569 6 18V7Z" />
      <path d="M9 5C9 3.89543 9.89543 3 11 3H13C14.1046 3 15 3.89543 15 5V7H9V5Z" />
    </IconBase>
  )
}

function HeartIcon({ filled, className = '' }) {
  return (
    <svg aria-hidden="true" viewBox="0 0 24 24" className={`inline-block shrink-0 ${className}`}
      fill={filled ? 'currentColor' : 'none'} stroke="currentColor" strokeWidth="1.8"
      strokeLinecap="round" strokeLinejoin="round">
      <path d="M20.84 4.61a5.5 5.5 0 0 0-7.78 0L12 5.67l-1.06-1.06a5.5 5.5 0 0 0-7.78 7.78l1.06 1.06L12 21.23l7.78-7.78 1.06-1.06a5.5 5.5 0 0 0 0-7.78z" />
    </svg>
  )
}

function ReorderBtns({ onUp, onDown, disableUp, disableDown }) {
  return (
    <div className="flex flex-col shrink-0">
      <button type="button" onClick={onUp} disabled={disableUp}
        className="text-gray-400 hover:text-gray-600 disabled:opacity-20 leading-none px-1 py-0.5 text-xs">▲</button>
      <button type="button" onClick={onDown} disabled={disableDown}
        className="text-gray-400 hover:text-gray-600 disabled:opacity-20 leading-none px-1 py-0.5 text-xs">▼</button>
    </div>
  )
}

function DefaultBtn({ isDefault, onClick, title }) {
  return (
    <button
      type="button"
      onClick={onClick}
      title={title ?? (isDefault ? 'Κλικ για αποεπιλογή' : 'Ορισμός ως προεπιλογή')}
      className={`w-6 h-6 rounded-full border-2 flex items-center justify-center shrink-0 transition-all ${
        isDefault
          ? 'border-primary-600 bg-primary-600'
          : 'border-gray-300 bg-white hover:border-primary-400'
      }`}
    >
      {isDefault && <span className="w-2.5 h-2.5 rounded-full bg-white block" />}
    </button>
  )
}

function FavoriteBtn({ isFavorite, onClick, title }) {
  return (
    <button
      type="button"
      onClick={onClick}
      title={title ?? (isFavorite ? 'Αφαίρεση από αγαπημένα' : 'Προσθήκη στα αγαπημένα')}
      className={`w-7 h-7 rounded-full flex items-center justify-center shrink-0 transition-all ${
        isFavorite
          ? 'text-rose-500 hover:text-rose-400'
          : 'text-gray-300 hover:text-rose-400'
      }`}
    >
      <HeartIcon filled={isFavorite} className="w-4 h-4" />
    </button>
  )
}

function PriceInput({ value, onChange, placeholder, className = '', allowNegative = false }) {
  const step = 0.10
  const num = parseFloat(value) || 0
  function inc() { onChange(Math.round((num + step) * 100) / 100) }
  function dec() {
    const next = Math.round((num - step) * 100) / 100
    onChange(allowNegative ? next : Math.max(0, next))
  }
  return (
    <div className={`flex items-center border border-gray-300 rounded-lg overflow-hidden h-10 ${className}`}>
      <button type="button" onClick={dec}
        className="px-2 h-full text-gray-500 hover:bg-gray-100 border-r border-gray-300 text-sm font-bold shrink-0">−</button>
      <input
        type="number" step="0.10" value={value}
        onChange={e => onChange(e.target.value)}
        placeholder={placeholder ?? '0.00'}
        className="flex-1 min-w-0 text-center text-sm outline-none bg-transparent px-1"
      />
      <button type="button" onClick={inc}
        className="px-2 h-full text-gray-500 hover:bg-gray-100 border-l border-gray-300 text-sm font-bold shrink-0">+</button>
    </div>
  )
}

function moveItem(arr, i, dir) {
  const j = i + dir
  if (j < 0 || j >= arr.length) return arr
  const next = [...arr]
  ;[next[i], next[j]] = [next[j], next[i]]
  return next
}

function SubChoiceRows({ subChoices, onMove, onToggleDefault, onChange, onRemove, onAdd, parentLabel }) {
  if (!subChoices || subChoices.length === 0) return null
  return (
    <div className="border-t border-gray-100 bg-indigo-50/40 px-3 py-2 space-y-2">
      <p className="text-xs text-indigo-500 font-medium mb-1">
        Υπο-επιλογές του «{parentLabel || '…'}» — εμφανίζονται μόνο αν επιλεγεί
      </p>
      {subChoices.map((sc, sci) => (
        <div key={sci} className="flex items-center gap-2 ml-4">
          <ReorderBtns
            onUp={() => onMove(sci, -1)} onDown={() => onMove(sci, 1)}
            disableUp={sci === 0} disableDown={sci === subChoices.length - 1}
          />
          <DefaultBtn isDefault={sc.is_default} onClick={() => onToggleDefault(sci)} />
          <input className="input flex-1 text-sm" placeholder="π.χ. Καραμέλα"
            value={sc.name} onChange={e => onChange(sci, 'name', e.target.value)} />
          <PriceInput value={sc.extra_cost} onChange={v => onChange(sci, 'extra_cost', v)}
            allowNegative className="w-28 text-sm" />
          <button onClick={() => onRemove(sci)} className="btn btn-danger px-2 min-h-0 h-9 text-sm shrink-0">✕</button>
        </div>
      ))}
      <button onClick={onAdd} className="ml-4 btn btn-secondary text-xs px-2 py-1 min-h-0 h-7">
        + Υπο-επιλογή
      </button>
    </div>
  )
}

// Build the ordered list of sub-category-like rows for a parent:
// interleaves the "General" virtual row at its general_sort_order position
function buildSubList(parent, subcategories) {
  const subs = [...subcategories].sort((a, b) => a.sort_order - b.sort_order)
  const generalRow = { _isGeneral: true, sort_order: parent.general_sort_order }
  const all = [...subs, generalRow].sort((a, b) => a.sort_order - b.sort_order)
  return all
}

export default function ProductsPage() {
  const qc = useQueryClient()
  const [selectedCat, setSelectedCat] = useState(null)
  const [editProduct, setEditProduct] = useState(null)
  const [editCat, setEditCat] = useState(null)
  const [confirmDelete, setConfirmDelete] = useState(null)
  const [showInactive, setShowInactive] = useState(false)
  const [showArchived, setShowArchived] = useState(false)
  const [multiSelect, setMultiSelect] = useState(false)
  const [selected, setSelected] = useState(new Set())
  const [sortMode, setSortMode] = useState('custom')

  const { data: categories = [] } = useQuery({
    queryKey: ['categories'],
    queryFn: () => client.get('/api/products/categories').then(r => r.data),
  })
  const { data: allProducts = [] } = useQuery({
    queryKey: ['products-all'],
    queryFn: () => client.get('/api/products/?all=true').then(r => r.data),
  })
  const { data: statusData } = useQuery({
    queryKey: ['system-status'],
    queryFn: () => client.get('/api/system/status').then(r => r.data),
    staleTime: 60_000,
  })
  const printers = statusData?.printers ?? []

  // selectedCat can be:
  //   null                  → all products
  //   number                → specific category (if top-level: includes all sub-cats too)
  //   '__general_<id>'      → only direct products of that top-level category (no sub-cat)
  const isGeneralSel = typeof selectedCat === 'string' && selectedCat.startsWith('__general_')
  const generalParentId = isGeneralSel ? Number(selectedCat.replace('__general_', '')) : null
  const selectedCatObj = isGeneralSel ? null : categories.find(c => c.id === selectedCat)
  const visibleCatIds = isGeneralSel
    ? [generalParentId]  // only direct products on the parent
    : selectedCat
      ? selectedCatObj?.parent_id == null
        ? [selectedCat, ...categories.filter(c => c.parent_id === selectedCat).map(c => c.id)]
        : [selectedCat]
      : null
  const filteredByCat = visibleCatIds ? allProducts.filter(p => visibleCatIds.includes(p.category_id)) : allProducts
  const baseList = filteredByCat.filter(p => {
    if (p.lifecycle_status === 'archived') return showArchived
    if (!p.is_available) return showInactive
    return true
  })
  const products = [...baseList].sort((a, b) => {
    if (sortMode === 'name') return a.name.localeCompare(b.name, 'el')
    if (sortMode === 'price') return a.base_price - b.base_price
    return (a.sort_order ?? 0) - (b.sort_order ?? 0) || a.id - b.id
  })

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['products-all'] })
    qc.invalidateQueries({ queryKey: ['categories'] })
  }

  const saveCat = useMutation({
    mutationFn: b => editCat?.id ? client.put(`/api/products/categories/${editCat.id}`, b) : client.post('/api/products/categories', b),
    onSuccess: () => { toast.success('Κατηγορία αποθηκεύτηκε'); setEditCat(null); invalidate() },
    onError: () => toast.error('Σφάλμα'),
  })
  const deleteCat = useMutation({
    mutationFn: id => client.delete(`/api/products/categories/${id}`),
    onSuccess: () => { toast.success('Διαγράφηκε'); setConfirmDelete(null); invalidate() },
    onError: () => toast.error('Σφάλμα'),
  })
  const reorderCats = useMutation({
    mutationFn: items => client.put('/api/products/categories/reorder', items),
    onSuccess: () => invalidate(),
  })
  const reorderSubcats = useMutation({
    mutationFn: items => client.put('/api/products/categories/reorder-subcategories', items),
    onSuccess: () => invalidate(),
  })
  const reorderGeneral = useMutation({
    mutationFn: items => client.put('/api/products/categories/reorder-general', items),
    onSuccess: () => invalidate(),
  })
  const toggleAutoExpanded = useMutation({
    mutationFn: ({ id, auto_expanded }) => client.put(`/api/products/categories/${id}`, { auto_expanded }),
    onSuccess: () => invalidate(),
  })
  const saveProduct = useMutation({
    mutationFn: b => editProduct?.id ? client.put(`/api/products/${editProduct.id}`, b) : client.post('/api/products/', b),
    onSuccess: () => { toast.success('Προϊόν αποθηκεύτηκε'); setEditProduct(null); invalidate() },
    onError: () => toast.error('Σφάλμα'),
  })
  const toggleAvail = useMutation({
    mutationFn: ({ id, is_available }) => client.put(`/api/products/${id}`, { is_available }),
    onSuccess: () => invalidate(),
    onError: () => toast.error('Σφάλμα'),
  })
  const archiveProduct = useMutation({
    mutationFn: id => client.delete(`/api/products/${id}`),
    onSuccess: () => { toast.success('Αρχειοθετήθηκε'); setConfirmDelete(null); invalidate() },
    onError: () => toast.error('Σφάλμα'),
  })
  const hardDeleteProduct = useMutation({
    mutationFn: id => client.delete(`/api/products/${id}?hard=true`),
    onSuccess: () => { toast.success('Διαγράφηκε οριστικά'); setConfirmDelete(null); invalidate() },
    onError: err => toast.error(err.response?.data?.detail || 'Σφάλμα'),
  })
  const reorderProducts = useMutation({
    mutationFn: items => client.put('/api/products/reorder', items),
    onSuccess: () => invalidate(),
  })

  function moveProd(prod, dir) {
    const sorted = [...baseList].sort((a, b) => (a.sort_order ?? 0) - (b.sort_order ?? 0) || a.id - b.id)
    const idx = sorted.findIndex(p => p.id === prod.id)
    const swapIdx = idx + dir
    if (swapIdx < 0 || swapIdx >= sorted.length) return
    const normalised = sorted.map((p, i) => ({ id: p.id, sort_order: i }))
    ;[normalised[idx].sort_order, normalised[swapIdx].sort_order] = [normalised[swapIdx].sort_order, normalised[idx].sort_order]
    reorderProducts.mutate(normalised)
  }

  function moveCat(cat, dir) {
    const sorted = categories.filter(c => !c.parent_id).sort((a, b) => a.sort_order - b.sort_order)
    const idx = sorted.findIndex(c => c.id === cat.id)
    const swapIdx = idx + dir
    if (swapIdx < 0 || swapIdx >= sorted.length) return
    const updates = sorted.map((c, i) => {
      if (i === idx) return { id: c.id, sort_order: sorted[swapIdx].sort_order }
      if (i === swapIdx) return { id: c.id, sort_order: sorted[idx].sort_order }
      return { id: c.id, sort_order: c.sort_order }
    })
    reorderCats.mutate(updates)
  }

  // Shared helper: move any row (sub-cat or General) in the mixed sub-list.
  // Normalises the whole list to 0-based sequential indices, swaps the two positions,
  // then writes all updated values. This avoids colliding sort_order values.
  function _moveInSubList(parent, itemIdx, dir) {
    const subs = categories.filter(c => c.parent_id === parent.id).sort((a, b) => a.sort_order - b.sort_order)
    const subList = buildSubList(parent, subs)
    const swapIdx = itemIdx + dir
    if (itemIdx < 0 || swapIdx < 0 || swapIdx >= subList.length) return
    // Normalise to clean sequential indices
    const normalised = subList.map((row, i) => ({ ...row, _normOrder: i }))
    ;[normalised[itemIdx]._normOrder, normalised[swapIdx]._normOrder] =
      [normalised[swapIdx]._normOrder, normalised[itemIdx]._normOrder]
    // Write subcats and general separately
    const subcatUpdates = normalised
      .filter(r => !r._isGeneral)
      .map(r => ({ id: r.id, sort_order: r._normOrder }))
    const generalRow = normalised.find(r => r._isGeneral)
    if (subcatUpdates.length) reorderSubcats.mutate(subcatUpdates)
    if (generalRow) reorderGeneral.mutate([{ id: parent.id, general_sort_order: generalRow._normOrder }])
  }

  function moveSubcat(parent, subcat, dir) {
    const subs = categories.filter(c => c.parent_id === parent.id).sort((a, b) => a.sort_order - b.sort_order)
    const subList = buildSubList(parent, subs)
    const idx = subList.findIndex(r => !r._isGeneral && r.id === subcat.id)
    _moveInSubList(parent, idx, dir)
  }

  function moveGeneral(parent, dir) {
    const subs = categories.filter(c => c.parent_id === parent.id).sort((a, b) => a.sort_order - b.sort_order)
    const subList = buildSubList(parent, subs)
    const idx = subList.findIndex(r => r._isGeneral)
    _moveInSubList(parent, idx, dir)
  }

  function toggleSelect(id) {
    setSelected(prev => { const n = new Set(prev); n.has(id) ? n.delete(id) : n.add(id); return n })
  }
  function selectAll() { setSelected(new Set(products.map(p => p.id))) }
  function clearSelect() { setSelected(new Set()) }
  function exitMultiSelect() { setMultiSelect(false); setSelected(new Set()) }

  async function bulkAction(action) {
    const ids = [...selected]
    if (!ids.length) return
    try {
      if (action === 'available') { await Promise.all(ids.map(id => client.put(`/api/products/${id}`, { is_available: true }))); toast.success(`${ids.length} διαθέσιμα`) }
      else if (action === 'unavailable') { await Promise.all(ids.map(id => client.put(`/api/products/${id}`, { is_available: false }))); toast.success(`${ids.length} μη διαθέσιμα`) }
      else if (action === 'archive') { setConfirmDelete({ type: 'bulk-archive', ids }); return }
      invalidate(); exitMultiSelect()
    } catch { toast.error('Σφάλμα') }
  }

  async function confirmBulkArchive(ids) {
    const results = await Promise.allSettled(ids.map(id => client.delete(`/api/products/${id}`)))
    const ok = results.filter(r => r.status === 'fulfilled').length
    const fail = results.filter(r => r.status === 'rejected').length
    if (ok) toast.success(`${ok} αρχειοθετήθηκαν ή διαγράφηκαν`)
    if (fail) toast.error(`${fail} απέτυχαν`)
    setConfirmDelete(null); invalidate(); exitMultiSelect()
  }

  function handleConfirmDelete() {
    if (!confirmDelete) return
    if (confirmDelete.type === 'category') deleteCat.mutate(confirmDelete.id)
    if (confirmDelete.type === 'product-archive') archiveProduct.mutate(confirmDelete.id)
    if (confirmDelete.type === 'product-hard') hardDeleteProduct.mutate(confirmDelete.id)
    if (confirmDelete.type === 'bulk-archive') confirmBulkArchive(confirmDelete.ids)
  }

  const printerName = id => printers.find(p => p.id === id)?.name ?? `#${id}`
  const categoryIconClass = 'w-4 h-4'
  const categoryActionBtnClass = 'p-1 rounded-md hover:bg-black/5 disabled:opacity-30 disabled:cursor-not-allowed'
  const categoryMoveBtnClass = `${categoryActionBtnClass} text-primary-700 hover:text-primary-800`
  const categoryEditBtnClass = `${categoryActionBtnClass} text-orange-500 hover:text-orange-600`
  const categoryDeleteBtnClass = `${categoryActionBtnClass} text-red-600 hover:text-red-700`

  const topLevelCats = categories.filter(c => !c.parent_id).sort((a, b) => a.sort_order - b.sort_order)

  return (
    <div className="flex gap-6 h-full">
      {/* Left: Categories */}
      <aside className="w-96 shrink-0 space-y-1 overflow-y-auto">
        <div className="flex items-center justify-between mb-3">
          <h2 className="font-semibold text-gray-700">Κατηγορίες</h2>
          <button
            onClick={() => setEditCat({ _isNew: true })}
            className="btn btn-primary px-2 py-1 min-h-0 h-8 text-white"
            title="Προσθήκη κατηγορίας"
            aria-label="Προσθήκη κατηγορίας"
          >
            <AddIcon className={categoryIconClass} />
          </button>
        </div>
        <button onClick={() => setSelectedCat(null)}
          className={`w-full text-left px-3 py-2.5 rounded-xl text-sm font-medium transition-colors ${!selectedCat ? 'bg-primary-700 text-white' : 'hover:bg-gray-100 text-gray-700'}`}>
          Όλα
        </button>

        {topLevelCats.map((cat, idx) => {
          const subs = categories.filter(c => c.parent_id === cat.id).sort((a, b) => a.sort_order - b.sort_order)
          const subList = buildSubList(cat, subs)
          const isParentActive = selectedCat === cat.id
          return (
            <div key={cat.id}>
              {/* Top-level category row */}
              <div className={`flex items-center gap-1 rounded-xl ${isParentActive ? 'bg-primary-700 text-white' : 'hover:bg-gray-100'}`}>
                {cat.color && <span className="w-2.5 h-2.5 rounded-full ml-2 shrink-0" style={{ background: cat.color }} />}
                <button onClick={() => setSelectedCat(cat.id)} className="flex-1 text-left px-2 py-2.5 text-sm font-medium truncate">{cat.name}</button>
                {/* Add sub-category button */}
                <button
                  onClick={() => setEditCat({ _isNew: true, parent_id: cat.id })}
                  className={`${categoryActionBtnClass} text-green-600 hover:text-green-700`}
                  title="Προσθήκη υποκατηγορίας"
                >
                  <AddIcon className={categoryIconClass} />
                </button>
                <button onClick={() => moveCat(cat, -1)} disabled={idx === 0} className={categoryMoveBtnClass} title="Μετακίνηση πάνω">
                  <MoveUpIcon className={categoryIconClass} />
                </button>
                <button onClick={() => moveCat(cat, 1)} disabled={idx === topLevelCats.length - 1} className={categoryMoveBtnClass} title="Μετακίνηση κάτω">
                  <MoveDownIcon className={categoryIconClass} />
                </button>
                <button onClick={() => setEditCat(cat)} className={categoryEditBtnClass} title="Επεξεργασία">
                  <EditIcon className={categoryIconClass} />
                </button>
                <button onClick={() => setConfirmDelete({ type: 'category', id: cat.id })} className={`${categoryDeleteBtnClass} mr-1`} title="Διαγραφή">
                  <DeleteIcon className={categoryIconClass} />
                </button>
              </div>

              {/* Sub-category rows (indented), interleaved with General group */}
              {subList.map((row, subIdx) => {
                if (row._isGeneral) {
                  // Virtual "General" row — products directly on the parent
                  const isGeneralActive = selectedCat === `__general_${cat.id}`
                  return (
                    <div key="__general__" className={`flex items-center gap-1 ml-4 rounded-xl ${isGeneralActive ? 'bg-primary-600 text-white' : 'hover:bg-gray-100'}`}>
                      <span className="w-1.5 h-1.5 rounded-full ml-2 shrink-0 bg-gray-300" />
                      <button
                        onClick={() => setSelectedCat(`__general_${cat.id}`)}
                        className={`flex-1 text-left px-2 py-2 text-xs italic truncate ${selectedCat === `__general_${cat.id}` ? 'font-semibold' : 'text-gray-400'}`}
                      >Γενικά</button>
                      <button onClick={() => moveGeneral(cat, -1)} disabled={subIdx === 0} className={`${categoryMoveBtnClass} opacity-60`} title="Μετακίνηση Γενικά πάνω">
                        <MoveUpIcon className={categoryIconClass} />
                      </button>
                      <button onClick={() => moveGeneral(cat, 1)} disabled={subIdx === subList.length - 1} className={`${categoryMoveBtnClass} opacity-60 mr-1`} title="Μετακίνηση Γενικά κάτω">
                        <MoveDownIcon className={categoryIconClass} />
                      </button>
                    </div>
                  )
                }
                const isSubActive = selectedCat === row.id
                return (
                  <div key={row.id} className={`flex items-center gap-1 ml-4 rounded-xl ${isSubActive ? 'bg-primary-600 text-white' : 'hover:bg-gray-100'}`}>
                    {row.color
                      ? <span className="w-1.5 h-1.5 rounded-full ml-2 shrink-0" style={{ background: row.color }} />
                      : <span className="w-1.5 h-1.5 rounded-full ml-2 shrink-0 bg-gray-400" />
                    }
                    <button onClick={() => setSelectedCat(row.id)} className="flex-1 text-left px-2 py-2 text-xs font-medium truncate">{row.name}</button>
                    {/* Auto-expanded toggle */}
                    <button
                      type="button"
                      onClick={() => toggleAutoExpanded.mutate({ id: row.id, auto_expanded: !row.auto_expanded })}
                      title={row.auto_expanded ? 'Auto-expanded: ON — κλικ για απενεργοποίηση' : 'Auto-expanded: OFF — κλικ για ενεργοποίηση'}
                      className={`px-1.5 py-0.5 rounded text-xs font-bold shrink-0 transition-colors ${
                        row.auto_expanded
                          ? 'bg-emerald-100 text-emerald-700 hover:bg-emerald-200'
                          : 'bg-gray-100 text-gray-400 hover:bg-gray-200'
                      }`}
                    >
                      ↕
                    </button>
                    <button onClick={() => moveSubcat(cat, row, -1)} disabled={subIdx === 0} className={categoryMoveBtnClass} title="Μετακίνηση πάνω">
                      <MoveUpIcon className={categoryIconClass} />
                    </button>
                    <button onClick={() => moveSubcat(cat, row, 1)} disabled={subIdx === subList.length - 1} className={categoryMoveBtnClass} title="Μετακίνηση κάτω">
                      <MoveDownIcon className={categoryIconClass} />
                    </button>
                    <button onClick={() => setEditCat(row)} className={categoryEditBtnClass} title="Επεξεργασία">
                      <EditIcon className={categoryIconClass} />
                    </button>
                    <button onClick={() => setConfirmDelete({ type: 'category', id: row.id })} className={`${categoryDeleteBtnClass} mr-1`} title="Διαγραφή">
                      <DeleteIcon className={categoryIconClass} />
                    </button>
                  </div>
                )
              })}
            </div>
          )
        })}
      </aside>

      {/* Right: Products */}
      <div className="flex-1 space-y-4 min-w-0">
        <div className="flex items-center gap-3 flex-wrap">
          <h2 className="font-semibold text-gray-700 flex-1">
            {isGeneralSel
              ? (() => {
                  const parent = categories.find(c => c.id === generalParentId)
                  return `Προϊόντα — ${parent?.name ?? '?'} / Γενικά`
                })()
              : selectedCat
                ? (() => {
                    const cat = categories.find(c => c.id === selectedCat)
                    if (!cat) return 'Προϊόντα'
                    if (cat.parent_id) {
                      const parent = categories.find(c => c.id === cat.parent_id)
                      return `Προϊόντα — ${parent?.name ?? '?'} / ${cat.name}`
                    }
                    return `Προϊόντα — ${cat.name}`
                  })()
                : 'Προϊόντα'
            }
          </h2>
          <label className="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
            <input type="checkbox" checked={showInactive} onChange={e => setShowInactive(e.target.checked)} className="accent-primary-700" />
            Ανενεργά
          </label>
          <label className="flex items-center gap-2 text-sm text-gray-600 cursor-pointer">
            <input type="checkbox" checked={showArchived} onChange={e => setShowArchived(e.target.checked)} className="accent-primary-700" />
            Αρχειοθετημένα
          </label>
          <select value={sortMode} onChange={e => setSortMode(e.target.value)} className="input text-sm py-1 h-9 min-h-0 w-auto pr-8">
            <option value="custom">Σειρά: Προσαρμοσμένη</option>
            <option value="name">Σειρά: Αλφαβητικά</option>
            <option value="price">Σειρά: Τιμή</option>
          </select>
          {!multiSelect && <button onClick={() => setMultiSelect(true)} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9">Πολλαπλή επιλογή</button>}
          {multiSelect && (
            <div className="flex gap-2 flex-wrap">
              <span className="text-sm text-gray-500 self-center">{selected.size} επιλεγμένα</span>
              <button onClick={selectAll} className="btn btn-secondary text-xs px-2 py-1 min-h-0 h-8">Όλα</button>
              <button onClick={clearSelect} className="btn btn-secondary text-xs px-2 py-1 min-h-0 h-8">Καθαρισμός</button>
              <button onClick={() => bulkAction('available')} disabled={!selected.size} className="btn btn-secondary text-xs px-2 py-1 min-h-0 h-8 text-green-600">Διαθέσιμο</button>
              <button onClick={() => bulkAction('unavailable')} disabled={!selected.size} className="btn btn-secondary text-xs px-2 py-1 min-h-0 h-8 text-amber-600">Μη διαθέσιμο</button>
              <button onClick={() => bulkAction('archive')} disabled={!selected.size} className="btn btn-danger text-xs px-2 py-1 min-h-0 h-8">Αρχειοθέτηση</button>
              <button onClick={exitMultiSelect} className="btn btn-secondary text-xs px-2 py-1 min-h-0 h-8">Ακύρωση</button>
            </div>
          )}
          {!multiSelect && <button onClick={() => setEditProduct({ ...EMPTY_PRODUCT })} className="btn btn-primary">+ Νέο προϊόν</button>}
        </div>

        {products.length === 0 && <p className="text-center text-gray-400 py-16">Δεν υπάρχουν προϊόντα.</p>}

        <div className="space-y-3">
          {products.map((p, idx) => {
            const isArchived = p.lifecycle_status === 'archived'
            return (
              <div key={p.id}
                onClick={multiSelect ? () => toggleSelect(p.id) : undefined}
                className={`card p-4 flex items-center gap-3 transition-opacity ${(!p.is_available || isArchived) ? 'opacity-60' : ''} ${multiSelect ? 'cursor-pointer select-none' : ''} ${multiSelect && selected.has(p.id) ? 'ring-2 ring-primary-500 bg-primary-50' : ''}`}
              >
                {multiSelect && (
                  <input type="checkbox" checked={selected.has(p.id)} onChange={() => toggleSelect(p.id)}
                    onClick={e => e.stopPropagation()} className="w-4 h-4 accent-primary-700 shrink-0" />
                )}
                {p.image_url && (
                  <img src={`${import.meta.env.VITE_API_URL || ''}${p.image_url}`} alt={p.name}
                    className="w-12 h-12 rounded-lg object-cover shrink-0" />
                )}
                <div className="flex-1 min-w-0">
                  <p className="font-semibold text-gray-800 flex items-center gap-2">
                    {p.name}
                    {isArchived && (
                      <span className="text-xs bg-gray-200 text-gray-600 px-1.5 py-0.5 rounded font-normal">Αρχείο</span>
                    )}
                    {!isArchived && !p.is_available && (
                      <span className="text-xs bg-amber-100 text-amber-700 px-1.5 py-0.5 rounded font-normal">Ανενεργό</span>
                    )}
                  </p>
                  <p className="text-sm text-gray-500">
                    {(() => {
                      const cat = categories.find(c => c.id === p.category_id)
                      if (!cat) return '—'
                      if (cat.parent_id) {
                        const parent = categories.find(c => c.id === cat.parent_id)
                        return `${parent?.name ?? '?'} / ${cat.name}`
                      }
                      return cat.name
                    })()} · €{p.base_price.toFixed(2)}
                    {p.printer_zone_id && ` · ${printerName(p.printer_zone_id)}`}
                  </p>
                </div>
                {!multiSelect && (
                  <>
                    {/* Availability toggle — only for non-archived products */}
                    {!isArchived && (
                      <button
                        onClick={e => { e.stopPropagation(); toggleAvail.mutate({ id: p.id, is_available: !p.is_available }) }}
                        className={`flex items-center gap-2 px-3 py-1.5 rounded-lg border text-sm font-medium transition-colors shrink-0 ${
                          p.is_available
                            ? 'bg-green-50 border-green-300 text-green-700 hover:bg-green-100'
                            : 'bg-gray-100 border-gray-300 text-gray-500 hover:bg-gray-200'
                        }`}
                      >
                        <span className={`w-2 h-2 rounded-full ${p.is_available ? 'bg-green-500' : 'bg-gray-400'}`} />
                        {p.is_available ? 'Διαθέσιμο' : 'Ανενεργό'}
                      </button>
                    )}
                    <button onClick={() => setEditProduct(p)} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9 shrink-0">Επεξεργασία</button>
                    {/* Archive/delete button — context-sensitive */}
                    {isArchived ? (
                      <button
                        onClick={() => setConfirmDelete({ type: 'product-hard', id: p.id })}
                        className="btn btn-danger text-sm px-3 py-1.5 min-h-0 h-9 shrink-0"
                        title="Οριστική διαγραφή"
                      >
                        Διαγραφή
                      </button>
                    ) : (
                      <button
                        onClick={() => setConfirmDelete({ type: 'product-archive', id: p.id })}
                        className="btn btn-danger text-sm px-3 py-1.5 min-h-0 h-9 shrink-0"
                        title="Αρχειοθέτηση (διατηρείται για ιστορικό)"
                      >
                        Αρχειοθέτηση
                      </button>
                    )}
                    {sortMode === 'custom' && !isArchived && (
                      <div className="flex flex-col gap-0.5 shrink-0">
                        <button onClick={() => moveProd(p, -1)} disabled={idx === 0} className="text-gray-400 hover:text-gray-600 disabled:opacity-20 text-xs leading-none">▲</button>
                        <button onClick={() => moveProd(p, 1)} disabled={idx === products.length - 1} className="text-gray-400 hover:text-gray-600 disabled:opacity-20 text-xs leading-none">▼</button>
                      </div>
                    )}
                  </>
                )}
              </div>
            )
          })}
        </div>
      </div>

      {editCat !== null && (
        <CategoryFormModal
          cat={editCat}
          parentName={editCat.parent_id ? categories.find(c => c.id === editCat.parent_id)?.name : null}
          onSave={(name, color) => saveCat.mutate({ name, color, parent_id: editCat.parent_id ?? null })}
          onClose={() => setEditCat(null)}
        />
      )}
      {editProduct !== null && (
        <ProductFormModal
          product={editProduct} categories={categories} printers={printers}
          onSave={b => saveProduct.mutate(b)}
          onCopy={formData => setEditProduct({ ...EMPTY_PRODUCT, ...formData, id: undefined, image_url: undefined, name: formData.name + ' (αντίγραφο)' })}
          onClose={() => setEditProduct(null)}
        />
      )}
      {confirmDelete && (
        <ConfirmModal
          title="Επιβεβαίωση"
          message={
            confirmDelete.type === 'category'
              ? 'Η κατηγορία θα διαγραφεί.'
              : confirmDelete.type === 'bulk-archive'
              ? `${confirmDelete.ids.length} προϊόντα θα αρχειοθετηθούν (αν υπάρχουν σε παραγγελίες) ή θα διαγραφούν.`
              : confirmDelete.type === 'product-archive'
              ? 'Το προϊόν θα αρχειοθετηθεί. Αν δεν υπάρχει σε παλαιές παραγγελίες θα διαγραφεί οριστικά, αλλιώς θα κρατηθεί για ιστορικό.'
              : 'Οριστική διαγραφή. Το προϊόν θα χαθεί μόνιμα.'
          }
          confirmLabel={confirmDelete.type === 'category' ? 'Επιβεβαίωση' : confirmDelete.type === 'product-hard' ? 'Διαγραφή' : 'Αρχειοθέτηση'}
          confirmClass="btn-danger"
          onConfirm={handleConfirmDelete}
          onCancel={() => setConfirmDelete(null)}
        />
      )}
    </div>
  )
}

function CategoryFormModal({ cat, parentName, onSave, onClose }) {
  const [name, setName] = useState(cat.name || '')
  const [color, setColor] = useState(cat.color || '')
  const isNew = !cat.id
  const isSub = !!cat.parent_id
  const title = isNew
    ? isSub ? `Νέα υποκατηγορία${parentName ? ` σε «${parentName}»` : ''}` : 'Νέα κατηγορία'
    : isSub ? 'Επεξεργασία υποκατηγορίας' : 'Επεξεργασία κατηγορίας'
  return (
    <div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4">
      <div className="bg-white rounded-2xl shadow-xl w-full max-w-xs p-6 space-y-4">
        <h2 className="font-bold text-gray-800">{title}</h2>
        {isSub && parentName && (
          <p className="text-xs text-gray-400 -mt-2">Κατηγορία: <span className="font-medium text-gray-600">{parentName}</span></p>
        )}
        <div>
          <label className="label">Όνομα</label>
          <input className="input" value={name} onChange={e => setName(e.target.value)} autoFocus />
        </div>
        <div>
          <label className="label">Χρώμα</label>
          <ColorPicker value={color} onChange={setColor} />
        </div>
        <div className="flex gap-3 pt-2">
          <button onClick={onClose} className="flex-1 btn btn-secondary">Ακύρωση</button>
          <button onClick={() => onSave(name, color || null)} disabled={!name.trim()} className="flex-1 btn btn-primary">Αποθήκευση</button>
        </div>
      </div>
    </div>
  )
}

// ─── Product Form Modal ───────────────────────────────────────────────────────

function buildFormFromProduct(product) {
  return {
    name: product.name || '',
    category_id: product.category_id ?? '',
    base_price: product.base_price ?? '',
    is_available: product.is_available ?? true,
    lifecycle_status: product.lifecycle_status ?? 'active',
    printer_zone_id: product.printer_zone_id ?? '',
    quick_options: product.quick_options?.map(q => ({
      name: q.name,
      price: q.price ?? 0,
      allow_multiple: q.allow_multiple ?? false,
      sort_order: q.sort_order ?? 0,
      is_favorite: q.is_favorite ?? false,
      favorite_sort_order: q.favorite_sort_order ?? 0,
    })) ?? [],
    options: product.options?.map(o => ({
      name: o.name,
      extra_cost: o.extra_cost ?? 0,
      allow_multiple: o.allow_multiple ?? false,
      sub_choices: o.sub_choices?.map(s => ({ name: s.name, extra_cost: s.extra_cost ?? 0, is_default: s.is_default ?? false })) ?? [],
      is_favorite: o.is_favorite ?? false,
      favorite_sort_order: o.favorite_sort_order ?? 0,
    })) ?? [],
    ingredients: product.ingredients?.map(i => ({
      name: i.name,
      extra_cost: i.extra_cost ?? 0,
      is_favorite: i.is_favorite ?? false,
      favorite_sort_order: i.favorite_sort_order ?? 0,
    })) ?? [],
    preference_sets: product.preference_sets?.map(ps => ({
      name: ps.name,
      default_choice_index: ps.choices ? ps.choices.findIndex(c => c.id === ps.default_choice_id) : -1,
      choices: ps.choices?.map(c => ({
        name: c.name,
        extra_cost: c.extra_cost ?? 0,
        disables_subset: c.disables_subset ?? false,
        sub_choices: c.sub_choices?.map(s => ({ name: s.name, extra_cost: s.extra_cost ?? 0, is_default: s.is_default ?? false })) ?? [],
      })) ?? [],
      shared_subset: ps.shared_subset ? {
        name: ps.shared_subset.name,
        choices: ps.shared_subset.choices?.map(s => ({ name: s.name, extra_cost: s.extra_cost ?? 0, is_default: s.is_default ?? false })) ?? [],
      } : null,
      is_favorite: ps.is_favorite ?? false,
      favorite_sort_order: ps.favorite_sort_order ?? 0,
    })) ?? [],
  }
}

// Build a flat sorted list of all favorited items across all types
function buildFavoritesList(form) {
  const items = []
  form.quick_options.forEach((q, i) => {
    if (q.is_favorite) items.push({ type: 'quick', idx: i, favorite_sort_order: q.favorite_sort_order ?? 0 })
  })
  form.ingredients.forEach((ing, i) => {
    if (ing.is_favorite) items.push({ type: 'ingredient', idx: i, favorite_sort_order: ing.favorite_sort_order ?? 0 })
  })
  form.options.forEach((o, i) => {
    if (o.is_favorite) items.push({ type: 'option', idx: i, favorite_sort_order: o.favorite_sort_order ?? 0 })
  })
  form.preference_sets.forEach((ps, i) => {
    if (ps.is_favorite) items.push({ type: 'pref', idx: i, favorite_sort_order: ps.favorite_sort_order ?? 0 })
  })
  return items.sort((a, b) => a.favorite_sort_order - b.favorite_sort_order)
}

function getFavSortField(form, type, idx) {
  if (type === 'quick') return form.quick_options[idx]?.favorite_sort_order ?? 0
  if (type === 'ingredient') return form.ingredients[idx]?.favorite_sort_order ?? 0
  if (type === 'option') return form.options[idx]?.favorite_sort_order ?? 0
  if (type === 'pref') return form.preference_sets[idx]?.favorite_sort_order ?? 0
  return 0
}

function setFavSortField(form, type, idx, value) {
  if (type === 'quick') return { ...form, quick_options: form.quick_options.map((q, i) => i === idx ? { ...q, favorite_sort_order: value } : q) }
  if (type === 'ingredient') return { ...form, ingredients: form.ingredients.map((ing, i) => i === idx ? { ...ing, favorite_sort_order: value } : ing) }
  if (type === 'option') return { ...form, options: form.options.map((o, i) => i === idx ? { ...o, favorite_sort_order: value } : o) }
  if (type === 'pref') return { ...form, preference_sets: form.preference_sets.map((ps, i) => i === idx ? { ...ps, favorite_sort_order: value } : ps) }
  return form
}

function getItemLabel(form, type, idx) {
  if (type === 'quick') return form.quick_options[idx]?.name || '(χωρίς όνομα)'
  if (type === 'ingredient') return form.ingredients[idx]?.name || '(χωρίς όνομα)'
  if (type === 'option') return form.options[idx]?.name || '(χωρίς όνομα)'
  if (type === 'pref') return form.preference_sets[idx]?.name || '(χωρίς όνομα)'
  return ''
}

function getItemTypeLabel(type) {
  if (type === 'quick') return 'Γρήγορη'
  if (type === 'ingredient') return 'Υλικό'
  if (type === 'option') return 'Έξτρα'
  if (type === 'pref') return 'Προτίμηση'
  return ''
}

function ProductFormModal({ product, categories, printers, onSave, onCopy, onClose }) {
  const [form, setForm] = useState(() => buildFormFromProduct(product))
  const [activeTab, setActiveTab] = useState('favorites')
  const [imageFile, setImageFile] = useState(null)
  const [uploading, setUploading] = useState(false)
  const qc = useQueryClient()

  useEffect(() => {
    function onKey(e) { if (e.key === 'Escape') onClose() }
    window.addEventListener('keydown', onKey)
    return () => window.removeEventListener('keydown', onKey)
  }, [onClose])

  useEffect(() => {
    setForm(buildFormFromProduct(product))
    setActiveTab('favorites')
    setImageFile(null)
  }, [product.id, product.name])

  function setField(k, v) { setForm(f => ({ ...f, [k]: v })) }

  // ── Favorites reorder ──
  function moveFavorite(favList, favIdx, dir) {
    const newList = [...favList]
    const swapIdx = favIdx + dir
    if (swapIdx < 0 || swapIdx >= newList.length) return
    // Swap favorite_sort_order values
    const aOrder = newList[favIdx].favorite_sort_order
    const bOrder = newList[swapIdx].favorite_sort_order
    setForm(f => {
      let next = setFavSortField(f, newList[favIdx].type, newList[favIdx].idx, bOrder)
      next = setFavSortField(next, newList[swapIdx].type, newList[swapIdx].idx, aOrder)
      return next
    })
  }

  function toggleFavorite(type, idx) {
    setForm(f => {
      const currentFavs = buildFavoritesList(f)
      const isFav = (() => {
        if (type === 'quick') return f.quick_options[idx]?.is_favorite
        if (type === 'ingredient') return f.ingredients[idx]?.is_favorite
        if (type === 'option') return f.options[idx]?.is_favorite
        if (type === 'pref') return f.preference_sets[idx]?.is_favorite
      })()
      // Assign next available sort order when adding
      const newSortOrder = isFav ? 0 : (currentFavs.length > 0 ? Math.max(...currentFavs.map(x => x.favorite_sort_order)) + 1 : 0)
      if (type === 'quick') return { ...f, quick_options: f.quick_options.map((q, i) => i === idx ? { ...q, is_favorite: !isFav, favorite_sort_order: isFav ? 0 : newSortOrder } : q) }
      if (type === 'ingredient') return { ...f, ingredients: f.ingredients.map((ing, i) => i === idx ? { ...ing, is_favorite: !isFav, favorite_sort_order: isFav ? 0 : newSortOrder } : ing) }
      if (type === 'option') return { ...f, options: f.options.map((o, i) => i === idx ? { ...o, is_favorite: !isFav, favorite_sort_order: isFav ? 0 : newSortOrder } : o) }
      if (type === 'pref') return { ...f, preference_sets: f.preference_sets.map((ps, i) => i === idx ? { ...ps, is_favorite: !isFav, favorite_sort_order: isFav ? 0 : newSortOrder } : ps) }
      return f
    })
  }

  // ── Quick Options ──
  function addQuickOption() { setForm(f => ({ ...f, quick_options: [...f.quick_options, { name: '', price: 0, allow_multiple: false, sort_order: f.quick_options.length, is_favorite: false, favorite_sort_order: 0 }] })) }
  function removeQuickOption(i) { setForm(f => ({ ...f, quick_options: f.quick_options.filter((_, idx) => idx !== i) })) }
  function setQuickOption(i, k, v) { setForm(f => ({ ...f, quick_options: f.quick_options.map((q, idx) => idx === i ? { ...q, [k]: v } : q) })) }
  function moveQuickOption(i, dir) { setForm(f => ({ ...f, quick_options: moveItem(f.quick_options, i, dir) })) }

  // ── Options ──
  function addOption() { setForm(f => ({ ...f, options: [...f.options, { name: '', extra_cost: 0, allow_multiple: false, sub_choices: [], is_favorite: false, favorite_sort_order: 0 }] })) }
  function removeOption(i) { setForm(f => ({ ...f, options: f.options.filter((_, idx) => idx !== i) })) }
  function setOption(i, k, v) { setForm(f => ({ ...f, options: f.options.map((o, idx) => idx === i ? { ...o, [k]: v } : o) })) }
  function moveOption(i, dir) { setForm(f => ({ ...f, options: moveItem(f.options, i, dir) })) }

  function addOptionSubChoice(oi) {
    setForm(f => ({ ...f, options: f.options.map((o, idx) =>
      idx !== oi ? o : { ...o, sub_choices: [...(o.sub_choices || []), { name: '', extra_cost: 0, is_default: false }] }
    )}))
  }
  function removeOptionSubChoice(oi, sci) {
    setForm(f => ({ ...f, options: f.options.map((o, idx) =>
      idx !== oi ? o : { ...o, sub_choices: o.sub_choices.filter((_, i) => i !== sci) }
    )}))
  }
  function setOptionSubChoice(oi, sci, k, v) {
    setForm(f => ({ ...f, options: f.options.map((o, idx) =>
      idx !== oi ? o : {
        ...o, sub_choices: o.sub_choices.map((sc, scidx) => {
          if (scidx !== sci) return k === 'is_default' && v === true ? { ...sc, is_default: false } : sc
          return { ...sc, [k]: v }
        })
      }
    )}))
  }
  function moveOptionSubChoice(oi, sci, dir) {
    setForm(f => ({ ...f, options: f.options.map((o, idx) =>
      idx !== oi ? o : { ...o, sub_choices: moveItem(o.sub_choices, sci, dir) }
    )}))
  }
  function toggleOptionSubDefault(oi, sci) {
    const sc = form.options[oi]?.sub_choices?.[sci]
    setOptionSubChoice(oi, sci, 'is_default', !sc?.is_default)
  }

  // ── Ingredients ──
  function addIngredient() { setForm(f => ({ ...f, ingredients: [...f.ingredients, { name: '', extra_cost: 0, is_favorite: false, favorite_sort_order: 0 }] })) }
  function removeIngredient(i) { setForm(f => ({ ...f, ingredients: f.ingredients.filter((_, idx) => idx !== i) })) }
  function setIngredient(i, k, v) { setForm(f => ({ ...f, ingredients: f.ingredients.map((ing, idx) => idx === i ? { ...ing, [k]: v } : ing) })) }
  function moveIngredient(i, dir) { setForm(f => ({ ...f, ingredients: moveItem(f.ingredients, i, dir) })) }

  // ── Preference sets ──
  function addPrefSet() {
    const newIdx = form.preference_sets.length
    setForm(f => ({ ...f, preference_sets: [...f.preference_sets, { name: '', default_choice_index: -1, choices: [], shared_subset: null, is_favorite: false, favorite_sort_order: 0 }] }))
    setActiveTab(newIdx)
  }
  function removePrefSet(si) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.filter((_, idx) => idx !== si) }))
    setActiveTab('favorites')
  }
  function setPrefSetField(si, k, v) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => idx === si ? { ...ps, [k]: v } : ps) }))
  }
  function addChoice(si) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) =>
      idx === si ? { ...ps, choices: [...ps.choices, { name: '', extra_cost: 0, disables_subset: false, sub_choices: [] }] } : ps
    )}))
  }
  function removeChoice(si, ci) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      const newChoices = ps.choices.filter((_, cidx) => cidx !== ci)
      const d = ps.default_choice_index
      const newDefault = d === ci ? -1 : d > ci ? d - 1 : d
      return { ...ps, choices: newChoices, default_choice_index: newDefault }
    })}))
  }
  function setChoice(si, ci, k, v) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) =>
      idx === si ? { ...ps, choices: ps.choices.map((ch, cidx) => cidx === ci ? { ...ch, [k]: v } : ch) } : ps
    )}))
  }
  function moveChoice(si, ci, dir) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      const newChoices = moveItem(ps.choices, ci, dir)
      const j = ci + dir
      let nd = ps.default_choice_index
      if (nd === ci) nd = j; else if (nd === j) nd = ci
      return { ...ps, choices: newChoices, default_choice_index: nd }
    })}))
  }
  function toggleDefaultChoice(si, ci) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) =>
      idx !== si ? ps : { ...ps, default_choice_index: ps.default_choice_index === ci ? -1 : ci }
    )}))
  }
  function addSubChoice(si, ci) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, pidx) =>
      pidx !== si ? ps : { ...ps, choices: ps.choices.map((ch, cidx) =>
        cidx !== ci ? ch : { ...ch, sub_choices: [...(ch.sub_choices || []), { name: '', extra_cost: 0, is_default: false }] }
      )}
    )}))
  }
  function removeSubChoice(si, ci, sci) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, pidx) =>
      pidx !== si ? ps : { ...ps, choices: ps.choices.map((ch, cidx) =>
        cidx !== ci ? ch : { ...ch, sub_choices: ch.sub_choices.filter((_, i) => i !== sci) }
      )}
    )}))
  }
  function setSubChoice(si, ci, sci, k, v) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, pidx) =>
      pidx !== si ? ps : { ...ps, choices: ps.choices.map((ch, cidx) =>
        cidx !== ci ? ch : { ...ch, sub_choices: ch.sub_choices.map((sc, scidx) => {
          if (scidx !== sci) return k === 'is_default' && v === true ? { ...sc, is_default: false } : sc
          return { ...sc, [k]: v }
        })}
      )}
    )}))
  }
  function moveSubChoice(si, ci, sci, dir) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, pidx) =>
      pidx !== si ? ps : { ...ps, choices: ps.choices.map((ch, cidx) =>
        cidx !== ci ? ch : { ...ch, sub_choices: moveItem(ch.sub_choices, sci, dir) }
      )}
    )}))
  }

  function setSharedSubsetName(si, name) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      return { ...ps, shared_subset: ps.shared_subset ? { ...ps.shared_subset, name } : { name, choices: [] } }
    })}))
  }
  function addSharedSubsetChoice(si) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      const ss = ps.shared_subset || { name: '', choices: [] }
      return { ...ps, shared_subset: { ...ss, choices: [...ss.choices, { name: '', extra_cost: 0, is_default: false }] } }
    })}))
  }
  function removeSharedSubsetChoice(si, sci) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      const newChoices = ps.shared_subset.choices.filter((_, i) => i !== sci)
      return { ...ps, shared_subset: newChoices.length ? { ...ps.shared_subset, choices: newChoices } : null }
    })}))
  }
  function setSharedSubsetChoice(si, sci, k, v) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) => {
      if (idx !== si) return ps
      const newChoices = ps.shared_subset.choices.map((sc, scidx) => {
        if (scidx !== sci) return k === 'is_default' && v === true ? { ...sc, is_default: false } : sc
        return { ...sc, [k]: v }
      })
      return { ...ps, shared_subset: { ...ps.shared_subset, choices: newChoices } }
    })}))
  }
  function moveSharedSubsetChoice(si, sci, dir) {
    setForm(f => ({ ...f, preference_sets: f.preference_sets.map((ps, idx) =>
      idx !== si ? ps : { ...ps, shared_subset: { ...ps.shared_subset, choices: moveItem(ps.shared_subset.choices, sci, dir) } }
    )}))
  }

  function buildBody() {
    return {
      name: form.name,
      category_id: form.category_id ? Number(form.category_id) : null,
      base_price: parseFloat(form.base_price),
      is_available: form.is_available,
      lifecycle_status: form.lifecycle_status,
      printer_zone_id: form.printer_zone_id ? Number(form.printer_zone_id) : null,
      quick_options: form.quick_options.map((q, i) => ({
        name: q.name,
        price: parseFloat(q.price) || 0,
        allow_multiple: q.allow_multiple ?? false,
        sort_order: i,
        is_favorite: q.is_favorite ?? false,
        favorite_sort_order: q.favorite_sort_order ?? 0,
      })),
      options: form.options.map(o => ({
        name: o.name,
        extra_cost: parseFloat(o.extra_cost) || 0,
        allow_multiple: o.allow_multiple ?? false,
        sub_choices: (o.sub_choices || []).map(s => ({ name: s.name, extra_cost: parseFloat(s.extra_cost) || 0, is_default: s.is_default ?? false })),
        is_favorite: o.is_favorite ?? false,
        favorite_sort_order: o.favorite_sort_order ?? 0,
      })),
      ingredients: form.ingredients.map(i => ({
        name: i.name,
        extra_cost: parseFloat(i.extra_cost) || 0,
        is_favorite: i.is_favorite ?? false,
        favorite_sort_order: i.favorite_sort_order ?? 0,
      })),
      preference_sets: form.preference_sets.map(ps => ({
        name: ps.name,
        default_choice_index: ps.default_choice_index >= 0 ? ps.default_choice_index : null,
        shared_subset: ps.shared_subset?.choices?.length ? {
          name: ps.shared_subset.name || '',
          choices: ps.shared_subset.choices.map(s => ({ name: s.name, extra_cost: parseFloat(s.extra_cost) || 0, is_default: s.is_default ?? false })),
        } : null,
        choices: ps.choices.map(c => ({
          name: c.name,
          extra_cost: parseFloat(c.extra_cost) || 0,
          disables_subset: c.disables_subset ?? false,
          sub_choices: (c.sub_choices || []).map(s => ({ name: s.name, extra_cost: parseFloat(s.extra_cost) || 0, is_default: s.is_default ?? false })),
        })),
        is_favorite: ps.is_favorite ?? false,
        favorite_sort_order: ps.favorite_sort_order ?? 0,
      })),
    }
  }

  async function submit() {
    if (!imageFile) {
      onSave(buildBody())
      return
    }
    if (!isNew) {
      onSave(buildBody())
      setUploading(true)
      try {
        const fd = new FormData(); fd.append('file', imageFile)
        await client.post(`/api/products/${product.id}/image`, fd)
        qc.invalidateQueries({ queryKey: ['products-all'] })
      } catch { toast.error('Σφάλμα ανεβάσματος εικόνας') }
      finally { setUploading(false) }
    } else {
      setUploading(true)
      try {
        const res = await client.post('/api/products/', buildBody())
        const newId = res.data.id
        const fd = new FormData(); fd.append('file', imageFile)
        await client.post(`/api/products/${newId}/image`, fd)
        qc.invalidateQueries({ queryKey: ['products-all'] })
        onClose()
      } catch { toast.error('Σφάλμα αποθήκευσης') }
      finally { setUploading(false) }
    }
  }

  const isNew = !product.id
  const canSave = form.name.trim() && form.base_price

  const favCount = buildFavoritesList(form).length

  const tabs = [
    { key: 'favorites', label: 'Αγαπημένα', count: favCount, isFavTab: true },
    { key: 'quick', label: 'Γρήγορες', count: form.quick_options.length },
    { key: 'ingredients', label: 'Υλικά', count: form.ingredients.length },
    { key: 'options', label: 'Έξτρα', count: form.options.length },
    ...form.preference_sets.map((ps, i) => ({ key: i, label: ps.name || `Προτ. ${i + 1}`, count: ps.choices.length })),
    { key: '__add_pref__', label: '＋ Προτίμηση', isAdd: true },
  ]

  const favList = buildFavoritesList(form)

  return (
    <div className="fixed inset-0 bg-black/50 flex items-center justify-center z-50 p-4">
      <div className="bg-white rounded-2xl shadow-2xl flex flex-col overflow-hidden" style={{ width: '90vw', height: '92vh' }}>

        {/* ── Header ── */}
        <div className="flex items-center justify-between px-6 py-4 border-b border-gray-100 shrink-0">
          <h2 className="font-bold text-gray-800 text-lg">
            {isNew ? 'Νέο προϊόν' : `Επεξεργασία — ${product.name}`}
          </h2>
          <button onClick={onClose} className="w-8 h-8 rounded-full hover:bg-gray-100 flex items-center justify-center text-gray-500 text-lg">✕</button>
        </div>

        {/* ── Body: left/right split ── */}
        <div className="flex-1 flex overflow-hidden">

          {/* LEFT: product info */}
          <div className="w-80 shrink-0 border-r border-gray-100 bg-gray-50/50 px-5 py-5 flex flex-col gap-3">
            <p className="text-xs font-semibold text-gray-400 uppercase tracking-widest">Στοιχεία προϊόντος</p>

            <div>
              <label className="label">Όνομα *</label>
              <input className="input" value={form.name} onChange={e => setField('name', e.target.value)} autoFocus placeholder="π.χ. Espresso" />
            </div>

            <div>
              <label className="label">Τιμή βάσης (€) *</label>
              <PriceInput value={form.base_price} onChange={v => setField('base_price', v)} className="w-full" />
            </div>

            <div>
              <label className="label">Κατηγορία</label>
              <select className="input" value={form.category_id} onChange={e => setField('category_id', e.target.value)}>
                <option value="">— Χωρίς κατηγορία —</option>
                {categories.filter(c => !c.parent_id).sort((a, b) => a.sort_order - b.sort_order).flatMap(parent => {
                  const subs = categories.filter(c => c.parent_id === parent.id).sort((a, b) => a.sort_order - b.sort_order)
                  return [
                    <option key={parent.id} value={parent.id}>{parent.name}</option>,
                    ...subs.map(s => <option key={s.id} value={s.id}>&nbsp;&nbsp;↳ {s.name}</option>),
                  ]
                })}
              </select>
            </div>

            <div>
              <label className="label">Ζώνη εκτυπωτή</label>
              <select className="input" value={form.printer_zone_id} onChange={e => setField('printer_zone_id', e.target.value)}>
                <option value="">— Χωρίς εκτυπωτή —</option>
                {printers.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
              </select>
            </div>

            {/* Availability toggle */}
            <button
              type="button"
              onClick={() => setField('is_available', !form.is_available)}
              className={`flex items-center gap-2 px-3 py-2 rounded-lg border text-sm font-medium transition-colors ${
                form.is_available
                  ? 'bg-green-50 border-green-300 text-green-700 hover:bg-green-100'
                  : 'bg-gray-100 border-gray-300 text-gray-500 hover:bg-gray-200'
              }`}
            >
              <span className={`w-2.5 h-2.5 rounded-full ${form.is_available ? 'bg-green-500' : 'bg-gray-400'}`} />
              {form.is_available ? 'Διαθέσιμο' : 'Μη διαθέσιμο'}
            </button>

            {/* Image upload */}
            <div>
              <label className="label">Εικόνα προϊόντος</label>
              {product.image_url && (
                <img src={`${import.meta.env.VITE_API_URL || ''}${product.image_url}`}
                  className="w-16 h-16 rounded-xl object-cover border border-gray-200 mb-2" alt="" />
              )}
              {imageFile && (
                <div className="text-xs text-primary-700 font-medium mb-1 break-all">{imageFile.name}</div>
              )}
              <label className="cursor-pointer inline-flex items-center gap-2 px-3 py-2 rounded-lg border border-gray-300 bg-white hover:bg-gray-50 text-sm text-gray-600 transition-colors">
                <svg width="14" height="14" viewBox="0 0 24 24" fill="none"><path d="M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/></svg>
                {imageFile ? 'Αλλαγή εικόνας' : 'Επιλογή εικόνας'}
                <input type="file" accept="image/*" className="sr-only"
                  onChange={e => setImageFile(e.target.files[0] ?? null)} />
              </label>
              {isNew && imageFile && (
                <p className="text-xs text-gray-400 mt-1">Η εικόνα θα ανέβει μαζί με την αποθήκευση.</p>
              )}
            </div>
          </div>

          {/* RIGHT: tabs */}
          <div className="flex-1 flex flex-col overflow-hidden">
            {/* Tab bar */}
            <div className="flex border-b border-gray-200 overflow-x-auto shrink-0 bg-white">
              {tabs.map(tab => {
                if (tab.isAdd) return (
                  <button key="__add_pref__" onClick={addPrefSet}
                    className="px-4 py-3 text-sm font-medium text-primary-600 hover:bg-primary-50 whitespace-nowrap border-b-2 border-transparent transition-colors">
                    {tab.label}
                  </button>
                )
                const isActive = activeTab === tab.key
                return (
                  <button key={String(tab.key)} onClick={() => setActiveTab(tab.key)}
                    className={`px-4 py-3 text-sm font-medium whitespace-nowrap border-b-2 transition-colors flex items-center gap-1.5 ${
                      isActive ? 'border-primary-600 text-primary-700 bg-primary-50/50' : 'border-transparent text-gray-500 hover:text-gray-700 hover:bg-gray-50'
                    }`}>
                    {tab.isFavTab && <HeartIcon filled={favCount > 0} className={`w-3.5 h-3.5 ${favCount > 0 ? 'text-rose-500' : 'text-gray-400'}`} />}
                    {tab.label}
                    {tab.count > 0 && (
                      <span className={`text-xs px-1.5 py-0.5 rounded-full font-mono ${isActive ? 'bg-primary-100 text-primary-700' : 'bg-gray-100 text-gray-500'}`}>
                        {tab.count}
                      </span>
                    )}
                  </button>
                )
              })}
            </div>

            {/* Tab content */}
            <div className="flex-1 overflow-y-auto px-6 py-5">

              {/* ── Favorites tab ── */}
              {activeTab === 'favorites' && (
                <div>
                  <p className="text-sm text-gray-500 mb-4">
                    Αγαπημένα — εμφανίζονται πρώτα στον σερβιτόρο. Σημειώστε ως αγαπημένο οποιοδήποτε στοιχείο από τις άλλες καρτέλες. Εδώ μπορείτε να τα αναδιατάξετε.
                  </p>
                  {favList.length === 0 && (
                    <p className="text-sm text-gray-400 text-center py-12">
                      Δεν υπάρχουν αγαπημένα. Χρησιμοποιήστε το <HeartIcon className="w-4 h-4 inline text-gray-400" /> σε γρήγορες επιλογές, υλικά, έξτρα ή προτιμήσεις.
                    </p>
                  )}
                  <div className="space-y-2">
                    {favList.map((fav, fi) => {
                      const label = getItemLabel(form, fav.type, fav.idx)
                      const typeLabel = getItemTypeLabel(fav.type)
                      return (
                        <div key={`${fav.type}-${fav.idx}`} className="flex items-center gap-3 border border-rose-100 bg-rose-50/30 rounded-xl p-3">
                          <ReorderBtns
                            onUp={() => moveFavorite(favList, fi, -1)}
                            onDown={() => moveFavorite(favList, fi, 1)}
                            disableUp={fi === 0}
                            disableDown={fi === favList.length - 1}
                          />
                          <HeartIcon filled className="w-4 h-4 text-rose-400 shrink-0" />
                          <div className="flex-1 min-w-0">
                            <p className="text-sm font-medium text-gray-800 truncate">{label}</p>
                            <p className="text-xs text-gray-400">{typeLabel}</p>
                          </div>
                          <button
                            type="button"
                            onClick={() => toggleFavorite(fav.type, fav.idx)}
                            className="text-xs text-gray-400 hover:text-red-500 transition-colors px-2 py-1 rounded hover:bg-red-50"
                          >
                            Αφαίρεση
                          </button>
                        </div>
                      )
                    })}
                  </div>
                </div>
              )}

              {/* ── Quick Options tab ── */}
              {activeTab === 'quick' && (
                <div>
                  <div className="flex items-center justify-between mb-3">
                    <p className="text-sm text-gray-500">Γρήγορες επιλογές — χωρίς υπο-επιλογές.</p>
                    <button onClick={addQuickOption} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9">+ Επιλογή</button>
                  </div>
                  {!form.quick_options.length && <p className="text-sm text-gray-400 text-center py-8">Δεν υπάρχουν γρήγορες επιλογές.</p>}
                  <div className="space-y-2">
                    {form.quick_options.map((q, i) => (
                      <div key={i} className={`flex gap-2 items-center border rounded-xl p-3 bg-white ${q.is_favorite ? 'border-rose-200' : 'border-gray-200'}`}>
                        <ReorderBtns onUp={() => moveQuickOption(i, -1)} onDown={() => moveQuickOption(i, 1)}
                          disableUp={i === 0} disableDown={i === form.quick_options.length - 1} />
                        <FavoriteBtn isFavorite={q.is_favorite} onClick={() => toggleFavorite('quick', i)} />
                        <input className="input flex-1" placeholder="Όνομα (π.χ. Extra Bacon)"
                          value={q.name} onChange={e => setQuickOption(i, 'name', e.target.value)} />
                        <PriceInput value={q.price} onChange={v => setQuickOption(i, 'price', v)}
                          className="w-32" placeholder="0.00" />
                        <label className="flex items-center gap-1.5 text-sm text-gray-600 cursor-pointer shrink-0 select-none">
                          <input type="checkbox" checked={q.allow_multiple}
                            onChange={e => setQuickOption(i, 'allow_multiple', e.target.checked)}
                            className="accent-primary-700 w-4 h-4" />
                          Πολλαπλά
                        </label>
                        <button onClick={() => removeQuickOption(i)} className="btn btn-danger px-3 min-h-0 h-10">✕</button>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* ── Ingredients tab ── */}
              {activeTab === 'ingredients' && (
                <div>
                  <div className="flex items-center justify-between mb-3">
                    <p className="text-sm text-gray-500">Υλικά που ο πελάτης μπορεί να αφαιρέσει.</p>
                    <button onClick={addIngredient} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9">+ Υλικό</button>
                  </div>
                  {!form.ingredients.length && <p className="text-sm text-gray-400 text-center py-8">Δεν υπάρχουν υλικά.</p>}
                  <div className="space-y-2">
                    {form.ingredients.map((ing, i) => (
                      <div key={i} className={`flex gap-2 items-center border rounded-xl p-3 bg-white ${ing.is_favorite ? 'border-rose-200' : 'border-gray-200'}`}>
                        <ReorderBtns onUp={() => moveIngredient(i, -1)} onDown={() => moveIngredient(i, 1)}
                          disableUp={i === 0} disableDown={i === form.ingredients.length - 1} />
                        <FavoriteBtn isFavorite={ing.is_favorite} onClick={() => toggleFavorite('ingredient', i)} />
                        <input className="input flex-1" placeholder="Όνομα υλικού" value={ing.name}
                          onChange={e => setIngredient(i, 'name', e.target.value)} />
                        <PriceInput value={ing.extra_cost} onChange={v => setIngredient(i, 'extra_cost', v)}
                          allowNegative className="w-32" />
                        <button onClick={() => removeIngredient(i)} className="btn btn-danger px-3 min-h-0 h-10">✕</button>
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* ── Extras tab ── */}
              {activeTab === 'options' && (
                <div>
                  <div className="flex items-center justify-between mb-3">
                    <p className="text-sm text-gray-500">Έξτρα (checkbox). Κάθε extra μπορεί να έχει υπο-επιλογές.</p>
                    <button onClick={addOption} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9">+ Έξτρα</button>
                  </div>
                  {!form.options.length && <p className="text-sm text-gray-400 text-center py-8">Δεν υπάρχουν extras.</p>}
                  <div className="space-y-3">
                    {form.options.map((opt, i) => (
                      <div key={i} className={`border rounded-xl overflow-hidden ${opt.is_favorite ? 'border-rose-200' : 'border-gray-200'}`}>
                        <div className="flex gap-2 items-center p-3 bg-white flex-wrap">
                          <ReorderBtns onUp={() => moveOption(i, -1)} onDown={() => moveOption(i, 1)}
                            disableUp={i === 0} disableDown={i === form.options.length - 1} />
                          <FavoriteBtn isFavorite={opt.is_favorite} onClick={() => toggleFavorite('option', i)} />
                          <input className="input flex-1 min-w-40" placeholder="Όνομα extra (π.χ. Κανέλα)"
                            value={opt.name} onChange={e => setOption(i, 'name', e.target.value)} />
                          <PriceInput value={opt.extra_cost} onChange={v => setOption(i, 'extra_cost', v)}
                            allowNegative className="w-32" />
                          <label className="flex items-center gap-1.5 text-sm text-gray-600 cursor-pointer shrink-0 select-none">
                            <input type="checkbox" checked={opt.allow_multiple}
                              onChange={e => setOption(i, 'allow_multiple', e.target.checked)}
                              className="accent-primary-700 w-4 h-4" />
                            Πολλαπλά
                          </label>
                          <button onClick={() => addOptionSubChoice(i)}
                            className="btn btn-secondary text-xs px-2 min-h-0 h-9 shrink-0 whitespace-nowrap">
                            + Υπο-επιλογές
                          </button>
                          <button onClick={() => removeOption(i)} className="btn btn-danger px-3 min-h-0 h-10">✕</button>
                        </div>
                        <SubChoiceRows
                          subChoices={opt.sub_choices}
                          parentLabel={opt.name}
                          onMove={(sci, dir) => moveOptionSubChoice(i, sci, dir)}
                          onToggleDefault={sci => toggleOptionSubDefault(i, sci)}
                          onChange={(sci, k, v) => setOptionSubChoice(i, sci, k, v)}
                          onRemove={sci => removeOptionSubChoice(i, sci)}
                          onAdd={() => addOptionSubChoice(i)}
                        />
                      </div>
                    ))}
                  </div>
                </div>
              )}

              {/* ── Preference set tabs ── */}
              {typeof activeTab === 'number' && form.preference_sets[activeTab] && (() => {
                const si = activeTab
                const ps = form.preference_sets[si]
                const hasSharedSubset = !!(ps.shared_subset)
                return (
                  <div>
                    <div className="flex items-center gap-3 mb-4">
                      <input className="input flex-1 font-semibold text-base"
                        placeholder="Όνομα προτίμησης (π.χ. Ζάχαρη)" value={ps.name}
                        onChange={e => setPrefSetField(si, 'name', e.target.value)} autoFocus />
                      <FavoriteBtn isFavorite={ps.is_favorite} onClick={() => toggleFavorite('pref', si)} />
                      <button onClick={() => removePrefSet(si)} className="btn btn-danger px-3 min-h-0 h-10 shrink-0">Διαγραφή</button>
                    </div>

                    <p className="text-xs text-gray-400 mb-3">
                      ● = προεπιλογή (κλικ ξανά για αποεπιλογή) · ⊘ = απενεργοποιεί το κοινό υπο-σύνολο
                    </p>

                    <div className="space-y-3 mb-5">
                      {ps.choices.map((ch, ci) => (
                        <div key={ci} className="border border-gray-200 rounded-xl overflow-hidden">
                          <div className="flex items-center gap-2 p-3 bg-white">
                            <ReorderBtns onUp={() => moveChoice(si, ci, -1)} onDown={() => moveChoice(si, ci, 1)}
                              disableUp={ci === 0} disableDown={ci === ps.choices.length - 1} />
                            <DefaultBtn isDefault={ps.default_choice_index === ci} onClick={() => toggleDefaultChoice(si, ci)} />
                            <input className="input flex-1" placeholder="Όνομα επιλογής (π.χ. Σκέτος)"
                              value={ch.name} onChange={e => setChoice(si, ci, 'name', e.target.value)} />
                            <PriceInput value={ch.extra_cost} onChange={v => setChoice(si, ci, 'extra_cost', v)}
                              allowNegative className="w-32" />
                            {hasSharedSubset && (
                              <button type="button"
                                onClick={() => setChoice(si, ci, 'disables_subset', !ch.disables_subset)}
                                title={ch.disables_subset ? 'Εμφάνιση κοινού υπο-συνόλου' : 'Απόκρυψη κοινού υπο-συνόλου'}
                                className={`w-7 h-7 rounded-full flex items-center justify-center shrink-0 text-sm transition-colors ${
                                  ch.disables_subset ? 'bg-red-100 text-red-500' : 'text-gray-300 hover:text-red-400'
                                }`}>⊘</button>
                            )}
                            <button onClick={() => addSubChoice(si, ci)}
                              className="btn btn-secondary text-xs px-2 min-h-0 h-9 shrink-0 whitespace-nowrap">
                              + Υπο-επιλογές
                            </button>
                            <button onClick={() => removeChoice(si, ci)} className="btn btn-danger px-2 min-h-0 h-9 shrink-0">✕</button>
                          </div>
                          <SubChoiceRows
                            subChoices={ch.sub_choices}
                            parentLabel={ch.name}
                            onMove={(sci, dir) => moveSubChoice(si, ci, sci, dir)}
                            onToggleDefault={sci => setSubChoice(si, ci, sci, 'is_default', !ch.sub_choices[sci]?.is_default)}
                            onChange={(sci, k, v) => setSubChoice(si, ci, sci, k, v)}
                            onRemove={sci => removeSubChoice(si, ci, sci)}
                            onAdd={() => addSubChoice(si, ci)}
                          />
                        </div>
                      ))}
                    </div>

                    <button onClick={() => addChoice(si)} className="btn btn-secondary text-sm px-4 py-1.5 min-h-0 h-9">
                      + Επιλογή
                    </button>

                    <div className="mt-6 border-t border-gray-100 pt-5">
                      <div className="flex items-center justify-between mb-3">
                        <div>
                          <p className="text-sm font-semibold text-gray-700">Κοινό υπο-σύνολο</p>
                          <p className="text-xs text-gray-400">Εμφανίζεται για όλες τις επιλογές εκτός αυτών με ⊘</p>
                        </div>
                        {!ps.shared_subset ? (
                          <button onClick={() => setSharedSubsetName(si, '')} className="btn btn-secondary text-sm px-3 py-1.5 min-h-0 h-9">
                            + Κοινό υπο-σύνολο
                          </button>
                        ) : (
                          <button onClick={() => setPrefSetField(si, 'shared_subset', null)} className="btn btn-danger text-sm px-3 py-1.5 min-h-0 h-9">
                            Αφαίρεση
                          </button>
                        )}
                      </div>
                      {ps.shared_subset && (
                        <div className="border border-indigo-200 rounded-xl p-4 bg-indigo-50/30 space-y-3">
                          <div>
                            <label className="label text-xs">Όνομα (π.χ. Είδος ζάχαρης)</label>
                            <input className="input text-sm" placeholder="π.χ. Είδος ζάχαρης"
                              value={ps.shared_subset.name || ''}
                              onChange={e => setSharedSubsetName(si, e.target.value)} />
                          </div>
                          <div className="space-y-2">
                            {(ps.shared_subset.choices || []).map((sc, sci) => (
                              <div key={sci} className="flex items-center gap-2">
                                <ReorderBtns onUp={() => moveSharedSubsetChoice(si, sci, -1)} onDown={() => moveSharedSubsetChoice(si, sci, 1)}
                                  disableUp={sci === 0} disableDown={sci === ps.shared_subset.choices.length - 1} />
                                <DefaultBtn isDefault={sc.is_default} onClick={() => setSharedSubsetChoice(si, sci, 'is_default', !sc.is_default)} />
                                <input className="input flex-1 text-sm" placeholder="π.χ. Λευκή"
                                  value={sc.name} onChange={e => setSharedSubsetChoice(si, sci, 'name', e.target.value)} />
                                <PriceInput value={sc.extra_cost} onChange={v => setSharedSubsetChoice(si, sci, 'extra_cost', v)}
                                  allowNegative className="w-32 text-sm" />
                                <button onClick={() => removeSharedSubsetChoice(si, sci)} className="btn btn-danger px-2 min-h-0 h-9 text-sm shrink-0">✕</button>
                              </div>
                            ))}
                          </div>
                          <button onClick={() => addSharedSubsetChoice(si)} className="btn btn-secondary text-xs px-3 py-1 min-h-0 h-7">
                            + Επιλογή υπο-συνόλου
                          </button>
                        </div>
                      )}
                    </div>
                  </div>
                )
              })()}
            </div>
          </div>
        </div>

        {/* ── Footer ── */}
        <div className="flex items-center justify-between px-6 py-4 border-t border-gray-100 bg-gray-50/50 shrink-0 gap-3">
          <button onClick={onClose} className="btn btn-secondary px-6">Ακύρωση</button>
          <div className="flex gap-3">
            {!isNew && (
              <button onClick={() => onCopy({ ...form })} className="btn btn-secondary px-6 text-indigo-600 border-indigo-200 hover:bg-indigo-50">
                📋 Αντιγραφή
              </button>
            )}
            <button onClick={submit} disabled={!canSave || uploading} className="btn btn-primary px-8">
              {uploading ? 'Ανέβασμα…' : isNew ? 'Δημιουργία' : 'Αποθήκευση'}
            </button>
          </div>
        </div>
      </div>
    </div>
  )
}
