import { useEffect, useRef, useState, useCallback } from 'react'
import { useNavigate, useSearchParams } from 'react-router-dom'
import TableCard from '../components/TableCard'
import useAuthStore from '../store/authStore'
import useTableColourStore from '../store/tableColourStore'
import useConnectionStore from '../store/connectionStore'
import useTableViewStore from '../store/tableViewStore'
import client from '../api/client'
import db from '../db/posdb'
import { FlagsIcon, TransferIcon, MergeIcon, PrintIcon, WaiterIcon } from '../components/Icons'

function fmtPrice(v) { return Number(v || 0).toFixed(2) + ' €' }

const _UNIT_LABELS = { kg: 'kg', liter: 'L', gram: 'g', ml: 'mL' }
function fmtItemQty(qty, unitType) {
  const label = _UNIT_LABELS[unitType]
  if (!label) return `×${qty}`
  if (unitType === 'kg' || unitType === 'liter') return `${Number(qty).toFixed(1)}${label}`
  return `${qty}${label}`
}

// ─── Icons ────────────────────────────────────────────────────────────────────

function FilterIcon({ size = 20 }) {
  return (
    <svg width={size} height={size} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
      <polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"/>
    </svg>
  )
}

// ─── Notification drawer ──────────────────────────────────────────────────────

// ─── Table quick-view modal (long press) ──────────────────────────────────────

function CheckIcon({ width = 18, height = 18 }) {
  return (
    <svg width={width} height={height} viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
      <path d="M20 6L9 17l-5-5"/>
    </svg>
  )
}

const QUICK_ACTIONS = [
  { Icon: FlagsIcon,    label: 'Ενδείξεις Τραπεζιού',  key: 'flags',          color: '#fac823', iconBg: 'rgba(251,191,36,0.15)'  },
  { Icon: TransferIcon, label: 'Μεταφορά',              key: 'transfer',       color: '#6099db', iconBg: 'rgba(96,165,250,0.15)'  },
  { Icon: MergeIcon,    label: 'Συγχώνευση',            key: 'merge',          color: '#6099db', iconBg: 'rgba(96,165,250,0.15)'  },
  { Icon: PrintIcon,    label: 'Εκτύπωση Σύνοψης',     key: 'print_synopsis', color: '#cbd5e1', iconBg: 'rgba(148,163,184,0.15)' },
  { Icon: WaiterIcon,   label: 'Ανάθεση Σερβιτόρου',   key: 'assign_waiter',  color: '#39b861', iconBg: 'rgba(34,197,94,0.15)'   },
]

function TableQuickModal({ table, order, flags, onClose, onNavigate, onAction, onCancelOrder, onMarkAllServed, canCancel }) {
  const tableName = table.label || `T${table.number}`
  const activeItems = order?.items?.filter(i => i.status === 'active') || []
  const total = activeItems.reduce((s, i) => s + i.unit_price * i.quantity, 0)
  const paid = order?.payments?.reduce((s, p) => s + p.amount, 0) || 0
  const due = Math.max(0, total - paid)

  const statusLabel = {
    open: 'Ανοιχτό', partially_paid: 'Μερικώς πληρωμένο', paid: 'Πληρωμένο',
  }[order?.status] || 'Ελεύθερο'

  return (
    <div className="modal-overlay" onClick={onClose}>
      <div style={{ width: '100%', maxWidth: 480, margin: '0 auto' }} onClick={e => e.stopPropagation()}>
        <div style={{ background: 'var(--bg2)', borderRadius: '16px 16px 0 0', padding: '16px 20px', borderBottom: '1px solid var(--border)' }}>
          <div className="modal-handle" style={{ marginBottom: 12 }} />
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginBottom: 12 }}>
            <span style={{ fontSize: 22, fontWeight: 700, color: 'var(--text)' }}>{tableName}</span>
            <span style={{ fontSize: 13, color: 'var(--muted)' }}>{statusLabel}</span>
          </div>
          {order ? (
            <div style={{ display: 'flex', flexDirection: 'column', gap: 6, marginBottom: 12 }}>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 14 }}>
                <span style={{ color: 'var(--muted)' }}>Σύνολο</span>
                <span style={{ fontWeight: 600, color: 'var(--text)' }}>{fmtPrice(total)}</span>
              </div>
              <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 14 }}>
                <span style={{ color: 'var(--muted)' }}>Πληρωμένο</span>
                <span style={{ fontWeight: 600, color: '#22c55e' }}>{fmtPrice(paid)}</span>
              </div>
              {due > 0 && (
                <div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 14 }}>
                  <span style={{ color: 'var(--muted)' }}>Υπόλοιπο</span>
                  <span style={{ fontWeight: 700, color: '#f59e0b' }}>{fmtPrice(due)}</span>
                </div>
              )}
            </div>
          ) : (
            <p style={{ fontSize: 13, color: 'var(--muted)', marginBottom: 12 }}>Δεν υπάρχει ενεργή παραγγελία</p>
          )}
          {flags.length > 0 && (
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
              {flags.map(f => (
                <div key={f.id} style={{
                  display: 'flex', alignItems: 'center', gap: 6,
                  background: (f.color || '#6295F3') + '22',
                  border: `1px solid ${f.color || '#6295F3'}`,
                  borderRadius: 20, padding: '4px 10px',
                }}>
                  <span style={{ fontSize: 14 }}>{f.emoji || '🏷️'}</span>
                  <span style={{ fontSize: 12, fontWeight: 600, color: f.color || '#6295F3' }}>{f.name}</span>
                </div>
              ))}
            </div>
          )}
          <button className="btn btn--primary" style={{ width: '100%', marginTop: 14 }} onClick={() => { onClose(); onNavigate() }}>
            Άνοιγμα τραπεζιού
          </button>
        </div>
        <div style={{ background: 'var(--bg2)', borderRadius: '0 0 16px 16px', padding: '8px 20px 24px', borderTop: '2px solid var(--border)' }}>
          <p style={{ fontSize: 11, fontWeight: 700, color: 'var(--muted)', letterSpacing: 1, marginBottom: 8, marginTop: 8 }}>ACTIONS</p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 0 }}>
            {QUICK_ACTIONS.map((a, i) => {
              const disabled = !order && a.key !== 'flags'
              return (
                <button key={a.key} disabled={disabled} onClick={() => { onClose(); onAction(a.key) }} style={{
                  display: 'flex', alignItems: 'center', gap: 14,
                  padding: '12px 0', background: 'none', border: 'none',
                  borderBottom: '1px solid var(--border)',
                  cursor: disabled ? 'not-allowed' : 'pointer',
                  opacity: disabled ? 0.35 : 1, textAlign: 'left',
                }}>
                  <span style={{ width: 36, height: 36, borderRadius: 9, flexShrink: 0, background: a.iconBg, display: 'flex', alignItems: 'center', justifyContent: 'center', color: a.color }}>
                    <a.Icon width="18" height="18" />
                  </span>
                  <span style={{ fontSize: 15, fontWeight: 600, color: a.color }}>{a.label}</span>
                  {!disabled && <span style={{ marginLeft: 'auto', color: 'var(--muted)', fontSize: 18 }}>›</span>}
                </button>
              )
            })}
            {/* Mark all served */}
            {(() => {
              const hasServable = order?.items?.some(i => (i.kds_status || 'pending') === 'done')
              const disabled = !hasServable
              return (
                <button
                  disabled={disabled}
                  onClick={() => { if (!disabled) { onClose(); onMarkAllServed() } }}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 14,
                    padding: '12px 0', background: 'none', border: 'none',
                    borderBottom: '1px solid var(--border)',
                    cursor: disabled ? 'not-allowed' : 'pointer',
                    opacity: disabled ? 0.35 : 1, textAlign: 'left',
                  }}>
                  <span style={{ width: 36, height: 36, borderRadius: 9, flexShrink: 0, background: 'rgba(34,197,94,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: '#4ade80' }}>
                    <CheckIcon width="18" height="18" />
                  </span>
                  <span style={{ fontSize: 15, fontWeight: 600, color: '#4ade80' }}>Σήμανση Όλων ως Παραδοθέντα</span>
                </button>
              )
            })()}
            {/* Cancel order */}
            {(() => {
              const hasActiveItems = activeItems.length > 0
              const disabled = !order || !hasActiveItems
              const colour = canCancel && !disabled ? '#ef4444' : 'var(--muted)'
              return (
                <button
                  disabled={!canCancel || disabled}
                  onClick={() => { if (canCancel && !disabled) onCancelOrder() }}
                  style={{
                    display: 'flex', alignItems: 'center', gap: 14,
                    padding: '12px 0', background: 'none', border: 'none',
                    cursor: canCancel && !disabled ? 'pointer' : 'not-allowed',
                    opacity: canCancel && !disabled ? 1 : 0.35, textAlign: 'left',
                  }}>
                  <span style={{ width: 36, height: 36, borderRadius: 9, flexShrink: 0, background: 'rgba(239,68,68,0.12)', display: 'flex', alignItems: 'center', justifyContent: 'center', color: colour }}>
                    <svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round">
                      <circle cx="12" cy="12" r="10"/><line x1="15" y1="9" x2="9" y2="15"/><line x1="9" y1="9" x2="15" y2="15"/>
                    </svg>
                  </span>
                  <span style={{ fontSize: 15, fontWeight: 600, color: colour }}>Ακύρωση Παραγγελίας</span>
                </button>
              )
            })()}
          </div>
        </div>
      </div>
    </div>
  )
}

// ─── Filters modal ────────────────────────────────────────────────────────────

function FiltersModal({ groups, onClose }) {
  const {
    ownerFilter, statusFilter, zoneFilter,
    setOwnerFilter, setStatusFilter, setZoneFilter,
    clearFilters, setActiveZoneTab,
  } = useTableViewStore()

  function toggleZone(id) {
    const next = zoneFilter.includes(id)
      ? zoneFilter.filter(z => z !== id)
      : [...zoneFilter, id]
    setZoneFilter(next)
    // if we remove a zone that is the active tab, reset to 'all'
    if (!next.length) setActiveZoneTab('all')
  }

  const hasActiveFilters = ownerFilter !== 'all' || statusFilter !== 'all' || zoneFilter.length > 0

  return (
    <div className="modal-overlay" onClick={onClose} style={{ alignItems: 'flex-end' }}>
      <div
        className="modal-sheet"
        onClick={e => e.stopPropagation()}
        style={{ borderRadius: '20px 20px 0 0', paddingBottom: 40, gap: 20 }}
      >
        <div className="modal-handle" />

        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: 17, fontWeight: 700, color: 'var(--text)' }}>Φίλτρα</span>
          {hasActiveFilters && (
            <button
              onClick={() => { clearFilters(); onClose() }}
              style={{ fontSize: 13, fontWeight: 600, color: 'var(--danger)', background: 'none', border: 'none', cursor: 'pointer', padding: '4px 8px' }}
            >
              Καθαρισμός
            </button>
          )}
        </div>

        {/* Owner: ALL | MINE */}
        <div>
          <p style={sectionLabel}>Ανάθεση</p>
          <div style={segmentedWrap}>
            {[['all', 'Όλα'], ['mine', 'Δικά μου']].map(([key, lbl]) => (
              <button key={key} onClick={() => setOwnerFilter(key)} style={segBtn(ownerFilter === key)}>{lbl}</button>
            ))}
          </div>
        </div>

        {/* Status: ALL | FREE | OPEN | PAID */}
        <div>
          <p style={sectionLabel}>Κατάσταση</p>
          <div style={{ ...segmentedWrap, display: 'grid', gridTemplateColumns: '1fr 1fr' }}>
            {[['all', 'Όλα'], ['free', 'Ελεύθερα'], ['open', 'Ανοιχτά'], ['paid', 'Πληρωμένα']].map(([key, lbl]) => (
              <button key={key} onClick={() => setStatusFilter(key)} style={{ ...segBtn(statusFilter === key), borderRadius: 10 }}>{lbl}</button>
            ))}
          </div>
        </div>

        {/* Zones: multi-select, one segmented container per zone */}
        {groups.length > 0 && (
          <div>
            <p style={sectionLabel}>Ζώνες {zoneFilter.length > 0 ? `(${zoneFilter.length} επιλεγμένες)` : ''}</p>
            <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
              {groups.map(g => {
                const active = zoneFilter.includes(g.id)
                return (
                  <div key={g.id} style={segmentedWrap}>
                    <button
                      onClick={() => toggleZone(g.id)}
                      style={{
                        ...segBtn(active),
                        display: 'flex', alignItems: 'center', justifyContent: 'center', gap: 7,
                      }}
                    >
                      {g.color && (
                        <span style={{
                          width: 8, height: 8, borderRadius: '50%',
                          background: active ? 'currentColor' : g.color,
                          flexShrink: 0, opacity: active ? 0.9 : 1,
                        }} />
                      )}
                      {g.name}
                    </button>
                  </div>
                )
              })}
            </div>
          </div>
        )}

        <button className="btn btn--secondary" style={{ width: '100%' }} onClick={onClose}>Εντάξει</button>
      </div>
    </div>
  )
}

const sectionLabel = { fontSize: 11, fontWeight: 700, color: 'var(--muted)', letterSpacing: 0.8, textTransform: 'uppercase', marginBottom: 8 }
const segmentedWrap = { display: 'flex', gap: 6, background: 'var(--bg3)', borderRadius: 12, padding: 4 }
function segBtn(active) {
  return {
    flex: 1, padding: '9px 8px', borderRadius: 9, border: 'none',
    cursor: 'pointer', fontWeight: 600, fontSize: 14,
    background: active ? 'var(--accent)' : 'transparent',
    color: active ? 'var(--accent-fg)' : 'var(--muted)',
    transition: 'background 0.12s',
  }
}

// ─── Main page ────────────────────────────────────────────────────────────────

export default function TableListPage() {
  const { user } = useAuthStore()
  const { status: connStatus } = useConnectionStore()
  const isOffline = connStatus !== 'online'

  const [tables, setTables] = useState([])
  const [groups, setGroups] = useState([])
  const [orders, setOrders] = useState([])
  const [flagDefs, setFlagDefs] = useState([])
  const [flagAssignments, setFlagAssignments] = useState([])
  const [waiters, setWaiters] = useState([])   // waiter objects for avatar lookup
  const [offline, setOffline] = useState(false)
  const [showFilters, setShowFilters] = useState(false)
  const [quickModal, setQuickModal] = useState(null)
  const [canCancel, setCanCancel] = useState(false)
  const [cancelConfirm, setCancelConfirm] = useState(null)
  // Orders tab filters
  const [ordersFilter, setOrdersFilter] = useState('all')   // status: 'all'|'pending'|'preparing'|'ready'
  const [ordersMyOnly, setOrdersMyOnly] = useState(false)   // view: mine|all
  const [ordersSortBy, setOrdersSortBy] = useState('time')  // 'time'|'latest_change'|'kds_priority'
  const [showOrdersFilters, setShowOrdersFilters] = useState(false)

  // pull-to-refresh state
  const [pulling, setPulling] = useState(false)
  const [pullY, setPullY] = useState(0)
  const [refreshing, setRefreshing] = useState(false)
  const pullStart = useRef(null)
  const scrollRef = useRef(null)
  const PULL_THRESHOLD = 72

  const navigate = useNavigate()
  const [searchParams] = useSearchParams()
  const pageTab = searchParams.get('tab') === 'orders' ? 'orders' : 'tables'
  const filterBtnRef = useRef(null)

  const loadFromBackend = useTableColourStore(s => s.loadFromBackend)

  const {
    density, ownerFilter, statusFilter, zoneFilter, activeZoneTab, setActiveZoneTab,
  } = useTableViewStore()

  // ── Load from IndexedDB when offline ──────────────────────────────────────
  const loadFromDB = useCallback(async () => {
    try {
      const [dbTables, dbOrders, dbGroups, dbFlagDefs, dbFlagAssign] = await Promise.all([
        db.pos_tables.toArray(),
        db.pos_orders.toArray(),
        db.table_groups?.toArray() ?? Promise.resolve([]),
        db.flag_defs?.toArray() ?? Promise.resolve([]),
        db.flag_assignments?.toArray() ?? Promise.resolve([]),
      ])
      console.log('[IDB] tables:', dbTables.length, 'orders:', dbOrders.length, 'groups:', dbGroups.length, 'flagDefs:', dbFlagDefs.length)
      setTables(dbTables.filter(t => t.is_active !== false))
      setOrders(dbOrders)
      setGroups(dbGroups)
      setFlagDefs(dbFlagDefs)
      setFlagAssignments(dbFlagAssign)
    } catch (e) {
      console.error('[IDB] loadFromDB failed:', e)
    }
    setOffline(true)
  }, [])

  // ── Stale-while-revalidate: show IDB instantly, then update from server ───────
  useEffect(() => {
    // Always seed from IDB first so the screen is never blank on mount
    loadFromDB().then(() => {
      // If we're online, immediately fetch fresh data (it will overwrite IDB render)
      if (!isOffline) load()
    })
  }, []) // eslint-disable-line react-hooks/exhaustive-deps

  useEffect(() => { if (isOffline) loadFromDB() }, [isOffline])

  useEffect(() => {
    const handler = () => setOffline(true)
    window.addEventListener('backend-offline', handler)
    return () => window.removeEventListener('backend-offline', handler)
  }, [])

  useEffect(() => {
    const handler = () => load()
    window.addEventListener('sse-reconnected', handler)
    return () => window.removeEventListener('sse-reconnected', handler)
  }, [])

  useEffect(() => { if (connStatus === 'online') setOffline(false) }, [connStatus])

  async function load() {
    try {
      const [tablesRes, ordersRes, groupsRes, flagDefsRes, flagAssignRes, settingsRes, waitersRes] = await Promise.all([
        client.get('/api/tables/'),
        client.get('/api/orders/active'),
        client.get('/api/tables/groups'),
        client.get('/api/flags/defs'),
        client.get('/api/flags/assignments'),
        client.get('/api/settings/'),
        client.get('/api/waiters/on-shift'),
      ])

      const tables = tablesRes.data
      const groups = groupsRes.data
      const flagDefs = flagDefsRes.data
      const flagAssignments = flagAssignRes.data

      setTables(tables)
      setGroups(groups)
      setFlagDefs(flagDefs)
      setFlagAssignments(flagAssignments)
      setWaiters(waitersRes.data)

      const fullOrders = await Promise.all(
        ordersRes.data.map(o =>
          client.get(`/api/orders/${o.id}`)
            .then(r => ({ ...r.data, waiter_ids: r.data.waiters?.map(w => w.waiter_id) ?? o.waiter_ids ?? [] }))
            .catch(() => o)
        )
      )
      setOrders(fullOrders)

      const raw = settingsRes.data?.['ui.table_colours']?.value
      if (raw) loadFromBackend(raw)
      setOffline(false)

      // Write everything to IDB so offline fallback has fresh data
      const activeIds = new Set(fullOrders.map(o => o.id))
      Promise.all([
        db.pos_tables.bulkPut(tables),
        db.table_groups.bulkPut(groups),
        db.flag_defs.bulkPut(flagDefs),
        db.flag_assignments.clear().then(() =>
          flagAssignments.length > 0 ? db.flag_assignments.bulkAdd(flagAssignments) : Promise.resolve()
        ),
        db.pos_orders.bulkPut(fullOrders).then(async () => {
          const allIdbIds = await db.pos_orders.toCollection().primaryKeys()
          const staleIds = allIdbIds.filter(id => !activeIds.has(id) && typeof id === 'number')
          if (staleIds.length > 0) await db.pos_orders.bulkDelete(staleIds)
        }),
      ]).then(() => {
        console.log('[IDB] saved — tables:', tables.length, 'groups:', groups.length, 'flagDefs:', flagDefs.length)
      }).catch(e => console.error('[IDB] save failed:', e))
    } catch {
      // Network failed — fall back to IDB if we haven't already
      if (!isOffline) loadFromDB()
    }
  }

  useEffect(() => {
    client.get('/api/orders/cancel-permissions').then(r => setCanCancel(r.data?.can_cancel === true)).catch(() => {})
  }, [])

  async function executeCancelOrder(orderId) {
    try {
      await client.delete(`/api/orders/${orderId}?print_cancellation=true`)
      setCancelConfirm(null)
      setQuickModal(null)
      load()
    } catch {}
  }

  async function executeMarkAllServed(orderId) {
    try {
      await client.post(`/api/kds/orders/${orderId}/items/mark-all-served`)
      load()
    } catch {}
  }

  // ── SSE live updates ───────────────────────────────────────────────────────
  useEffect(() => {
    if (isOffline) return
    function onSSE(e) {
      const { type, data } = e.detail
      if (type === 'order_updated' || type === 'order_paid') {
        client.get(`/api/orders/${data.order_id}`)
          .then(r => {
            const full = { ...r.data, waiter_ids: r.data.waiters?.map(w => w.waiter_id) ?? [] }
            setOrders(prev => {
              const exists = prev.find(o => o.id === data.order_id)
              return exists ? prev.map(o => o.id === data.order_id ? full : o) : [...prev, full]
            })
          })
          .catch(() => {
            setOrders(prev => {
              const existing = prev.find(o => o.id === data.order_id)
              if (existing) return prev.map(o => o.id === data.order_id ? { ...o, status: data.status, table_id: data.table_id } : o)
              return [...prev, { id: data.order_id, table_id: data.table_id, status: data.status, waiter_ids: [] }]
            })
          })
      } else if (type === 'order_closed') {
        setOrders(prev => prev.filter(o => o.id !== data.order_id))
      } else if (type === 'table_flags_changed') {
        client.get('/api/flags/assignments').then(r => setFlagAssignments(r.data)).catch(() => {})
      } else if (type === 'table_list_changed') {
        client.get('/api/tables/').then(r => setTables(r.data)).catch(() => {})
      } else if (type === 'kds_item_updated' || type === 'kds_order_updated') {
        // Re-fetch full order so kds_status is always fresh from server
        const { order_id } = data
        client.get(`/api/orders/${order_id}`)
          .then(r => {
            const full = { ...r.data, waiter_ids: r.data.waiters?.map(w => w.waiter_id) ?? [] }
            setOrders(prev => prev.map(o => o.id === order_id ? full : o))
          }).catch(() => {})
      }
    }
    window.addEventListener('sse-event', onSSE)
    return () => window.removeEventListener('sse-event', onSSE)
  }, [isOffline])

  // ── Derived maps ───────────────────────────────────────────────────────────
  const flagDefMap = Object.fromEntries(flagDefs.map(f => [f.id, f]))
  const tableFlagsMap = {}
  flagAssignments.forEach(a => {
    if (!tableFlagsMap[a.table_id]) tableFlagsMap[a.table_id] = []
    const def = flagDefMap[a.flag_id]
    if (def) tableFlagsMap[a.table_id].push(def)
  })
  const waiterMap = Object.fromEntries(waiters.map(w => [w.id, w]))

  function getOrder(tableId) { return orders.find(o => o.table_id === tableId) }
  function isMyOrder(order) { return !!(order && user && order.waiter_ids?.includes(user.id)) }
  function getOrderWaiters(order) {
    if (!order) return []
    return (order.waiter_ids || []).map(id => waiterMap[id]).filter(Boolean)
  }

  // ── Filtering logic ────────────────────────────────────────────────────────
  // Zones visible in top bar = those allowed by zoneFilter (or all if empty)
  const allowedZoneIds = zoneFilter.length > 0 ? new Set(zoneFilter) : null

  // visibleGroups = groups shown in the top bar
  const visibleGroups = groups.filter(g => !allowedZoneIds || allowedZoneIds.has(g.id))

  // Validate activeZoneTab against current allowedZoneIds
  // If the active tab is no longer visible, reset to 'all'
  const effectiveZoneTab = (
    activeZoneTab === 'all' ||
    activeZoneTab === 'standalone' ||
    visibleGroups.some(g => g.id === activeZoneTab)
  ) ? activeZoneTab : 'all'

  const filtered = tables.filter(t => {
    const order = getOrder(t.id)

    // Status filter
    if (statusFilter === 'free' && order) return false
    if (statusFilter === 'open' && (!order || order.status === 'paid' || order.status === 'partially_paid')) return false
    if (statusFilter === 'paid' && order?.status !== 'paid' && order?.status !== 'partially_paid') return false

    // Owner filter
    if (ownerFilter === 'mine' && !isMyOrder(order)) return false

    // Zone filter from modal (multi-select restricts which zones are allowed)
    if (allowedZoneIds && !allowedZoneIds.has(t.group_id ?? 'none')) return false

    // Active zone tab (secondary, single-select within allowed)
    if (effectiveZoneTab !== 'all' && t.group_id !== effectiveZoneTab) return false

    return true
  })

  // ── Pull-to-refresh handlers ───────────────────────────────────────────────
  function onPullTouchStart(e) {
    if (scrollRef.current?.scrollTop > 0) return
    pullStart.current = e.touches[0].clientY
  }
  function onPullTouchMove(e) {
    if (pullStart.current === null) return
    const dy = e.touches[0].clientY - pullStart.current
    if (dy > 0 && scrollRef.current?.scrollTop <= 0) {
      e.preventDefault()
      setPulling(true)
      setPullY(Math.min(dy, PULL_THRESHOLD * 1.5))
    }
  }
  async function onPullTouchEnd() {
    if (!pulling) return
    if (pullY >= PULL_THRESHOLD) {
      setRefreshing(true)
      await load()
      setRefreshing(false)
    }
    setPulling(false)
    setPullY(0)
    pullStart.current = null
  }

  // ── Grid columns per density ───────────────────────────────────────────────
  const gridCols = {
    '1x1': 'repeat(4, 1fr)',
    '2x1': 'repeat(2, 1fr)',
    '2x2': 'repeat(2, 1fr)',
    '4x1': '1fr',
    '4x2': '1fr',
    '4x3': '1fr',
  }[density] || 'repeat(2, 1fr)'

  const hasActiveFilters = ownerFilter !== 'all' || statusFilter !== 'all' || zoneFilter.length > 0

  function handleQuickAction(tableId, actionKey) {
    navigate(`/tables/${tableId}?action=${actionKey}`)
  }

  // ── Orders tab derived data ────────────────────────────────────────────────
  const ordersWithKds = orders.filter(o => {
    if (o.status === 'closed' || o.status === 'cancelled') return false
    const items = o.items || []
    const relevant = items.filter(i => i.status !== 'cancelled' && (i.kds_status || 'pending') !== 'served')
    return relevant.length > 0
  })

  const myOrdersWithKds = ordersWithKds.filter(o => o.waiter_ids?.includes(user?.id))

  const filteredOrders = (() => {
    const base = (ordersMyOnly ? myOrdersWithKds : ordersWithKds).filter(o => {
      if (ordersFilter === 'all') return true
      const items = (o.items || []).filter(i => i.status !== 'cancelled' && (i.kds_status || 'pending') !== 'served')
      if (items.length === 0) return false
      const kds = s => s || 'pending'
      const pending   = items.filter(i => kds(i.kds_status) === 'pending').length
      const preparing = items.filter(i => kds(i.kds_status) === 'preparing').length
      const done      = items.filter(i => kds(i.kds_status) === 'done').length
      const total     = items.length
      if (ordersFilter === 'pending')   return pending === total
      if (ordersFilter === 'preparing') return preparing > 0
      if (ordersFilter === 'ready')     return done === total
      return true
    })
    if (ordersSortBy === 'kds_priority') {
      // fully ready first; then by % ready descending; then preparing; then pending
      const score = o => {
        const items = (o.items || []).filter(i => i.status !== 'cancelled' && (i.kds_status || 'pending') !== 'served')
        if (items.length === 0) return { tier: 3, pct: 0 }
        const done = items.filter(i => (i.kds_status || 'pending') === 'done').length
        const prep = items.filter(i => (i.kds_status || 'pending') === 'preparing').length
        if (done === items.length) return { tier: 0, pct: 1 }
        if (done > 0) return { tier: 1, pct: done / items.length }
        if (prep > 0) return { tier: 2, pct: 0 }
        return { tier: 3, pct: 0 }
      }
      return [...base].sort((a, b) => {
        const sA = score(a), sB = score(b)
        if (sA.tier !== sB.tier) return sA.tier - sB.tier
        return sB.pct - sA.pct
      })
    }
    if (ordersSortBy === 'latest_change') {
      // most recently changed KDS status first
      return [...base].sort((a, b) => {
        const tA = new Date(a.kds_status_changed_at || a.opened_at || 0).getTime()
        const tB = new Date(b.kds_status_changed_at || b.opened_at || 0).getTime()
        return tB - tA
      })
    }
    // default: by time of order (oldest first — first order made, first shown)
    return [...base].sort((a, b) => new Date(a.opened_at || 0) - new Date(b.opened_at || 0))
  })()

  return (
    <>
      {pageTab === 'tables' ? (
        <>
          {/* ── Zone tab bar ─────────────────────────────────────────────────── */}
          <div style={{
            display: 'flex', alignItems: 'center', gap: 6,
            padding: '10px 12px',
            background: 'var(--bg)',
            borderBottom: '1px solid var(--border)',
            overflowX: 'auto', scrollbarWidth: 'none',
          }}>
            <ZoneTab label="Όλα" active={effectiveZoneTab === 'all'} onClick={() => setActiveZoneTab('all')} />
            {visibleGroups.map(g => (
              <ZoneTab key={g.id} label={g.name} color={g.color}
                active={effectiveZoneTab === g.id}
                onClick={() => setActiveZoneTab(effectiveZoneTab === g.id ? 'all' : g.id)}
              />
            ))}
          </div>

          {/* ── Standalone view OR Table grid ────────────────────────────────── */}
          {effectiveZoneTab === 'standalone' ? (
            <StandaloneView orders={orders} gridCols={gridCols} navigate={navigate} />
          ) : (
            <div
              ref={scrollRef}
              style={{ flex: 1, overflowY: 'auto', minHeight: 0, overscrollBehavior: 'contain' }}
              onTouchStart={onPullTouchStart}
              onTouchMove={onPullTouchMove}
              onTouchEnd={onPullTouchEnd}
            >
              {(pulling || refreshing) && (
                <div style={{
                  display: 'flex', alignItems: 'center', justifyContent: 'center',
                  height: Math.min(pullY, PULL_THRESHOLD),
                  color: 'var(--muted)', fontSize: 13, fontWeight: 600,
                  overflow: 'hidden', transition: pulling ? 'none' : 'height 0.2s',
                }}>
                  {refreshing ? '⟳ Ανανέωση…' : pullY >= PULL_THRESHOLD ? '↑ Αφήστε για ανανέωση' : '↓ Τραβήξτε για ανανέωση'}
                </div>
              )}
              {isOffline && tables.length === 0 && (
                <div style={{ textAlign: 'center', padding: '48px 24px', color: 'var(--muted)' }}>
                  <div style={{ fontSize: 36, marginBottom: 12 }}>📡</div>
                  <p style={{ fontWeight: 700, fontSize: 16, color: 'var(--text)', marginBottom: 6 }}>Offline — δεν υπάρχουν αποθηκευμένα δεδομένα</p>
                  <p style={{ fontSize: 13, lineHeight: 1.5 }}>Συνδέσου στο δίκτυο μια φορά για να αποθηκευτούν τα δεδομένα τοπικά.</p>
                </div>
              )}
              <div style={{
                display: 'grid',
                gridTemplateColumns: gridCols,
                gap: density === '1x1' ? 8 : 10,
                padding: '12px 12px 88px',
                alignContent: 'start',
              }}>
                {filtered.map(t => {
                  const order = getOrder(t.id)
                  const tableFlags = tableFlagsMap[t.id] || []
                  const grp = groups.find(g => g.id === t.group_id)
                  const orderWaiters = getOrderWaiters(order)
                  function handleClick() {
                    navigate(order ? `/tables/${t.id}` : `/tables/${t.id}/add?new=1`)
                  }
                  return (
                    <TableCard
                      key={t.id}
                      table={t}
                      order={order}
                      isMine={isMyOrder(order)}
                      flags={tableFlags}
                      groupName={grp?.name || ''}
                      waiterObjects={orderWaiters}
                      density={density}
                      onClick={handleClick}
                      onLongPress={isOffline ? undefined : () => setQuickModal({ table: t, order, flags: tableFlags })}
                    />
                  )
                })}
              </div>
            </div>
          )}

          {/* ── Filter FAB ───────────────────────────────────────────────────── */}
          <button
            ref={filterBtnRef}
            onClick={() => setShowFilters(true)}
            style={{
              position: 'fixed', bottom: 84, right: 24,
              width: 52, height: 52, borderRadius: '50%', border: 'none',
              background: hasActiveFilters ? 'var(--accent-dim,#92400e)' : 'var(--accent,#f59e0b)',
              color: hasActiveFilters ? '#fde68a' : 'var(--accent-fg,#1c1000)',
              cursor: 'pointer',
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              boxShadow: '0 4px 20px rgba(245,158,11,0.55), 0 2px 8px rgba(0,0,0,0.35)',
              zIndex: 40, transition: 'background 0.12s',
            }}
          >
            <FilterIcon size={20} />
            {hasActiveFilters && (
              <span style={{
                position: 'absolute', top: 0, right: 0,
                background: '#ef4444', color: '#fff',
                fontSize: 9, fontWeight: 800,
                borderRadius: '50%', width: 16, height: 16,
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}>
                {(ownerFilter !== 'all' ? 1 : 0) + (statusFilter !== 'all' ? 1 : 0) + (zoneFilter.length > 0 ? 1 : 0)}
              </span>
            )}
          </button>
        </>
      ) : (
        /* ── Orders tab ──────────────────────────────────────────────────────── */
        <OrdersView
          orders={filteredOrders}
          allOrders={ordersWithKds}
          tables={tables}
          filter={ordersFilter}
          setFilter={setOrdersFilter}
          myOnly={ordersMyOnly}
          setMyOnly={setOrdersMyOnly}
          sortBy={ordersSortBy}
          setSortBy={setOrdersSortBy}
          showFilters={showOrdersFilters}
          setShowFilters={setShowOrdersFilters}
          onNavigate={orderId => {
            const o = orders.find(x => x.id === orderId)
            if (o?.table_id) navigate(`/tables/${o.table_id}`)
            else navigate(`/orders/${orderId}`)
          }}
          onMarkAllServed={executeMarkAllServed}
          onRefresh={load}
        />
      )}

      {/* ── Modals ────────────────────────────────────────────────────────────── */}
      {showFilters && (
        <FiltersModal groups={groups} onClose={() => setShowFilters(false)} anchorRef={filterBtnRef} />
      )}

      {quickModal && (
        <TableQuickModal
          table={quickModal.table}
          order={quickModal.order}
          flags={quickModal.flags}
          canCancel={canCancel}
          onClose={() => setQuickModal(null)}
          onNavigate={() => navigate(`/tables/${quickModal.table.id}`)}
          onAction={(key) => handleQuickAction(quickModal.table.id, key)}
          onCancelOrder={() => setCancelConfirm({ orderId: quickModal.order?.id })}
          onMarkAllServed={() => { setQuickModal(null); executeMarkAllServed(quickModal.order?.id) }}
        />
      )}

      {cancelConfirm && (
        <div className="modal-overlay" onClick={() => setCancelConfirm(null)}>
          <div style={{ width: '100%', maxWidth: 400, margin: '0 auto', background: 'var(--bg2)', borderRadius: '16px 16px 0 0', padding: '24px 20px 32px' }} onClick={e => e.stopPropagation()}>
            <div className="modal-handle" style={{ marginBottom: 16 }} />
            <p style={{ fontSize: 18, fontWeight: 700, color: 'var(--text)', marginBottom: 8 }}>Ακύρωση Παραγγελίας;</p>
            <p style={{ fontSize: 14, color: 'var(--muted)', marginBottom: 20 }}>Όλα τα ενεργά αντικείμενα θα ακυρωθούν και θα εκτυπωθεί απόδειξη ακύρωσης.</p>
            <div style={{ display: 'flex', gap: 10 }}>
              <button className="btn btn--secondary" style={{ flex: 1 }} onClick={() => setCancelConfirm(null)}>Ακύρωση</button>
              <button className="btn" style={{ flex: 1, background: '#ef4444', color: '#fff' }} onClick={() => executeCancelOrder(cancelConfirm.orderId)}>Επιβεβαίωση</button>
            </div>
          </div>
        </div>
      )}

    </>
  )
}

// ─── KDS filter chip data ─────────────────────────────────────────────────────

const KDS_FILTER_CHIPS = [
  {
    key: 'all',
    full: 'Όλες', short: 'All',
    icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <rect x="3" y="3" width="7" height="7" rx="1.5" fill="currentColor"/>
        <rect x="14" y="3" width="7" height="7" rx="1.5" fill="currentColor"/>
        <rect x="3" y="14" width="7" height="7" rx="1.5" fill="currentColor"/>
        <rect x="14" y="14" width="7" height="7" rx="1.5" fill="currentColor"/>
      </svg>
    ),
    color: '#94a3b8', activeBg: '#334155', activeColor: '#e2e8f0',
  },
  {
    key: 'pending',
    full: 'Εκκρεμούν', short: 'PND',
    icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm.5-13H11v6l5.25 3.15.75-1.23-4.5-2.67V7z" fill="currentColor"/>
      </svg>
    ),
    color: '#f59e0b', activeBg: 'rgba(245,158,11,0.25)', activeColor: '#fbbf24',
  },
  {
    key: 'preparing',
    full: 'Σε Προετοιμασία', short: 'PRP',
    icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <path d="M13.5 0.67s.74 2.65.74 4.8c0 2.06-1.35 3.73-3.41 3.73-2.07 0-3.63-1.67-3.63-3.73l.03-.36C5.21 7.51 4 10.62 4 14c0 4.42 3.58 8 8 8s8-3.58 8-8C20 8.61 17.41 3.8 13.5.67zM11.71 19c-1.78 0-3.22-1.4-3.22-3.14 0-1.62 1.05-2.76 2.81-3.12 1.77-.36 3.6-1.21 4.62-2.58.39 1.29.59 2.65.59 4.04 0 2.65-2.15 4.8-4.8 4.8z" fill="currentColor"/>
      </svg>
    ),
    color: '#60a5fa', activeBg: 'rgba(96,165,250,0.25)', activeColor: '#93c5fd',
  },
  {
    key: 'ready',
    full: 'Έτοιμες', short: 'RDY',
    icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <circle cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="2"/>
        <path d="M7 12l3.5 3.5L17 8" stroke="currentColor" strokeWidth="2.2" strokeLinecap="round" strokeLinejoin="round"/>
      </svg>
    ),
    color: '#4ade80', activeBg: 'rgba(34,197,94,0.25)', activeColor: '#86efac',
  },
  {
    key: 'ready_items',
    full: 'Μερικώς Έτοιμες', short: 'PRT',
    icon: (
      <svg width="14" height="14" viewBox="0 0 24 24" fill="none">
        <path d="M12 2a10 10 0 0 1 0 20V2z" fill="currentColor" opacity="0.5"/>
        <path d="M12 2a10 10 0 0 0 0 20V2z" fill="currentColor"/>
      </svg>
    ),
    color: '#34d399', activeBg: 'rgba(52,211,153,0.22)', activeColor: '#6ee7b7',
  },
]

const KDS_ITEM_COLORS = {
  pending:   { textColor: '#f59e0b', label: 'ΕΚΚΡΕΜΕΙ' },
  preparing: { textColor: '#60a5fa', label: 'ΕΤΟΙΜΑΖΕΤΑΙ' },
  done:      { textColor: '#4ade80', label: 'READY' },
  served:    { textColor: null,      label: null },
}

// ─── Orders view ──────────────────────────────────────────────────────────────

// ─── Orders filter drawer ─────────────────────────────────────────────────────

function OrdersFilterDrawer({ myOnly, setMyOnly, sortBy, setSortBy, filter, setFilter, onClose }) {
  const hasActive = myOnly || sortBy !== 'time' || filter !== 'all'

  const STATUS_OPTIONS = [
    { key: 'all',       label: 'Όλες' },
    { key: 'pending',   label: 'PEND' },
    { key: 'preparing', label: 'PREP' },
    { key: 'ready',     label: 'READY' },
  ]

  function toggleStatus(key) {
    if (key === 'all') { setFilter('all'); return }
    setFilter(prev => prev === key ? 'all' : key)
  }

  return (
    <div className="modal-overlay" onClick={onClose} style={{ alignItems: 'flex-end' }}>
      <div
        className="modal-sheet"
        onClick={e => e.stopPropagation()}
        style={{ borderRadius: '20px 20px 0 0', paddingBottom: 40, gap: 20 }}
      >
        <div className="modal-handle" />

        <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
          <span style={{ fontSize: 17, fontWeight: 700, color: 'var(--text)' }}>Φίλτρα Παραγγελιών</span>
          {hasActive && (
            <button
              onClick={() => { setMyOnly(false); setSortBy('time'); setFilter('all'); onClose() }}
              style={{ fontSize: 13, fontWeight: 600, color: 'var(--danger)', background: 'none', border: 'none', cursor: 'pointer', padding: '4px 8px' }}
            >
              Καθαρισμός
            </button>
          )}
        </div>

        {/* View filter */}
        <div>
          <p style={sectionLabel}>Προβολή</p>
          <div style={segmentedWrap}>
            {[['false', 'Όλες'], ['true', 'Δικές μου']].map(([val, lbl]) => (
              <button key={val} onClick={() => setMyOnly(val === 'true')} style={segBtn(String(myOnly) === val)}>{lbl}</button>
            ))}
          </div>
        </div>

        {/* Sort method */}
        <div>
          <p style={sectionLabel}>Ταξινόμηση</p>
          <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
            {[
              ['time',          'Κατά ώρα παραγγελίας'],
              ['latest_change', 'Κατά τελευταία αλλαγή'],
              ['kds_priority',  'Ready → Prep → Pend'],
            ].map(([key, lbl]) => (
              <div key={key} style={segmentedWrap}>
                <button onClick={() => setSortBy(key)} style={segBtn(sortBy === key)}>{lbl}</button>
              </div>
            ))}
          </div>
        </div>

        {/* Status filter (multi-select: ALL selects all 3) */}
        <div>
          <p style={sectionLabel}>Κατάσταση</p>
          <div style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: 6 }}>
            {STATUS_OPTIONS.map(({ key, label }) => (
              <div key={key} style={segmentedWrap}>
                <button
                  onClick={() => toggleStatus(key)}
                  style={{ ...segBtn(filter === key || (key === 'all' && filter === 'all')), borderRadius: 10 }}
                >
                  {label}
                </button>
              </div>
            ))}
          </div>
        </div>

        <button className="btn btn--secondary" style={{ width: '100%' }} onClick={onClose}>Εντάξει</button>
      </div>
    </div>
  )
}

function OrdersView({ orders, allOrders, tables, filter, setFilter, myOnly, setMyOnly, sortBy, setSortBy, showFilters, setShowFilters, onNavigate, onMarkAllServed, onRefresh }) {
  const { chipStyle } = useTableViewStore()
  const [expandedOrders, setExpandedOrders] = useState({})
  const [refreshing, setRefreshing] = useState(false)
  const [pulling, setPulling] = useState(false)
  const [pullY, setPullY] = useState(0)
  const pullStart = useRef(null)
  const scrollRef = useRef(null)
  const PULL_THRESHOLD = 72

  const hasActiveOrderFilters = myOnly || sortBy !== 'time' || filter !== 'all'

  function toggleExpand(orderId) {
    setExpandedOrders(prev => ({ ...prev, [orderId]: !prev[orderId] }))
  }

  function onPullTouchStart(e) {
    if (scrollRef.current?.scrollTop > 0) return
    pullStart.current = e.touches[0].clientY
  }
  function onPullTouchMove(e) {
    if (pullStart.current === null) return
    const dy = e.touches[0].clientY - pullStart.current
    if (dy > 0 && scrollRef.current?.scrollTop <= 0) {
      e.preventDefault()
      setPulling(true)
      setPullY(Math.min(dy, PULL_THRESHOLD * 1.5))
    }
  }
  async function onPullTouchEnd() {
    if (!pulling) return
    if (pullY >= PULL_THRESHOLD) {
      setRefreshing(true)
      await onRefresh?.()
      setRefreshing(false)
    }
    setPulling(false)
    setPullY(0)
    pullStart.current = null
  }

  const tableMap = Object.fromEntries(tables.map(t => [t.id, t]))

  const kds = s => s || 'pending'

  function getOrderKdsLabel(o) {
    const items = (o.items || []).filter(i => i.status !== 'cancelled' && kds(i.kds_status) !== 'served')
    if (!items.length) return null
    const pending   = items.filter(i => kds(i.kds_status) === 'pending').length
    const preparing = items.filter(i => kds(i.kds_status) === 'preparing').length
    const done      = items.filter(i => kds(i.kds_status) === 'done').length
    const total     = items.length
    if (done === total)   return { label: 'READY',       color: '#4ade80', bg: 'rgba(34,197,94,0.15)' }
    if (preparing > 0)    return { label: 'ΕΤΟΙΜΑΖΕΤΑΙ', color: '#60a5fa', bg: 'rgba(96,165,250,0.15)' }
    if (pending === total) return { label: 'ΕΚΚΡΕΜΕΙ',   color: '#f59e0b', bg: 'rgba(245,158,11,0.15)' }
    return { label: `${done}/${total} READY`, color: '#4ade80', bg: 'rgba(34,197,94,0.12)' }
  }

  // Count per filter for badge
  function countFor(key) {
    return allOrders.filter(o => {
      const items = (o.items || []).filter(i => i.status !== 'cancelled' && kds(i.kds_status) !== 'served')
      if (!items.length) return false
      const pending   = items.filter(i => kds(i.kds_status) === 'pending').length
      const preparing = items.filter(i => kds(i.kds_status) === 'preparing').length
      const done      = items.filter(i => kds(i.kds_status) === 'done').length
      const total     = items.length
      if (key === 'all')          return true
      if (key === 'pending')      return pending === total
      if (key === 'preparing')    return preparing > 0
      if (key === 'ready')        return done === total
      if (key === 'ready_items')  return done > 0 && done < total
      return false
    }).length
  }

  return (
    <div style={{ display: 'flex', flexDirection: 'column', flex: 1, minHeight: 0 }}>
      {/* Filter chips */}
      <div style={{
        display: 'flex', alignItems: 'center', gap: 6,
        padding: '10px 12px',
        borderBottom: '1px solid var(--border)',
        overflowX: 'auto', scrollbarWidth: 'none', flexShrink: 0,
      }}>
        {KDS_FILTER_CHIPS.map(chip => {
          const active = filter === chip.key
          const count = countFor(chip.key)
          const cs = chipStyle || 'icon_short'
          const showIcon = cs === 'icon' || cs === 'icon_short' || cs === 'icon_full'
          const showText = cs !== 'icon'
          const textLabel = (cs === 'full' || cs === 'icon_full') ? chip.full : chip.short
          return (
            <button
              key={chip.key}
              onClick={() => setFilter(chip.key)}
              style={{
                display: 'flex', alignItems: 'center', gap: 6,
                padding: '8px 16px', borderRadius: 20,
                border: '2px solid transparent',
                background: active ? chip.activeBg : 'var(--bg3)',
                color: active ? chip.activeColor : 'var(--muted)',
                fontSize: 14, fontWeight: 600, cursor: 'pointer',
                whiteSpace: 'nowrap', flexShrink: 0,
                lineHeight: 1,
                transition: 'background 0.12s, color 0.12s',
              }}
            >
              {showIcon && <span style={{ display: 'inline-flex', alignItems: 'center', flexShrink: 0 }}>{chip.icon}</span>}
              {showText && <span style={{ lineHeight: 1 }}>{textLabel}</span>}
              <span style={{
                background: active ? `${chip.color}30` : 'rgba(255,255,255,0.08)',
                color: active ? chip.activeColor : 'var(--muted)',
                borderRadius: 10, fontSize: 11, fontWeight: 800,
                padding: '1px 6px', lineHeight: 1,
              }}>{count}</span>
            </button>
          )
        })}
      </div>

      {/* Order list */}
      <div
        ref={scrollRef}
        style={{ flex: 1, overflowY: 'auto', minHeight: 0, padding: '8px 12px 100px', overscrollBehavior: 'contain' }}
        onTouchStart={onPullTouchStart}
        onTouchMove={onPullTouchMove}
        onTouchEnd={onPullTouchEnd}
      >
        {(pulling || refreshing) && (
          <div style={{
            display: 'flex', alignItems: 'center', justifyContent: 'center',
            height: Math.min(pullY, PULL_THRESHOLD),
            color: 'var(--muted)', fontSize: 13, fontWeight: 600,
            overflow: 'hidden', transition: pulling ? 'none' : 'height 0.2s',
          }}>
            {refreshing ? '⟳ Ανανέωση…' : pullY >= PULL_THRESHOLD ? '↑ Αφήστε για ανανέωση' : '↓ Τραβήξτε για ανανέωση'}
          </div>
        )}
        {orders.length === 0 && (
          <div style={{ textAlign: 'center', padding: '40px 0', color: 'var(--muted)', fontSize: 14 }}>
            Δεν υπάρχουν παραγγελίες
          </div>
        )}
        {orders.map(o => {
          const t = tableMap[o.table_id]
          const isStandaloneOrder = !o.table_id && (o.order_type === 'takeaway' || o.order_type === 'delivery')
          const tableName = isStandaloneOrder
            ? (o.order_type === 'delivery' ? `Delivery #${o.id}` : `Takeaway #${o.id}`)
            : (t ? (t.label || `T${t.number}`) : `#${o.id}`)
          const kdsLabel = getOrderKdsLabel(o)
          const expanded = expandedOrders[o.id]
          const visibleItems = (o.items || []).filter(i => i.status !== 'cancelled' && kds(i.kds_status) !== 'served')

          return (
            <div key={o.id} style={{
              background: 'var(--bg2)',
              border: '1px solid var(--border)',
              borderRadius: 14,
              marginBottom: 10,
              overflow: 'hidden',
            }}>
              {/* Order header */}
              <div
                onClick={() => toggleExpand(o.id)}
                style={{
                  display: 'flex', alignItems: 'center', gap: 10,
                  padding: '12px 14px', cursor: 'pointer',
                }}
              >
                {/* Table name */}
                <span style={{ fontSize: 18, fontWeight: 800, color: 'var(--text)', letterSpacing: -0.5, flexShrink: 0 }}>
                  {tableName}
                </span>

                {/* KDS status badge */}
                {kdsLabel && (
                  <span style={{
                    display: 'inline-flex', alignItems: 'center',
                    height: 20, padding: '0 8px', borderRadius: 4,
                    background: kdsLabel.bg, color: kdsLabel.color,
                    fontSize: 10, fontWeight: 800, letterSpacing: 0.3,
                    border: `1px solid ${kdsLabel.color}40`,
                  }}>{kdsLabel.label}</span>
                )}

                {/* Item count */}
                <span style={{ fontSize: 12, color: 'var(--muted)', marginLeft: 2 }}>
                  {visibleItems.length} είδη
                </span>

                <span style={{ marginLeft: 'auto', color: 'var(--muted)', fontSize: 16, transition: 'transform 0.2s', display: 'inline-block', transform: expanded ? 'rotate(180deg)' : 'rotate(0deg)' }}>▾</span>
              </div>

              {/* Expanded items */}
              {expanded && (
                <div style={{ borderTop: '1px solid var(--border)' }}>
                  {visibleItems.map((item, idx) => {
                    const kdsC = KDS_ITEM_COLORS[kds(item.kds_status)] || KDS_ITEM_COLORS.pending
                    const nameCol = kdsC.textColor || 'var(--text)'
                    return (
                      <div key={item.id} style={{
                        display: 'flex', alignItems: 'center', gap: 8,
                        padding: '8px 14px',
                        borderBottom: idx < visibleItems.length - 1 ? '1px solid var(--border)' : 'none',
                      }}>
                        <span style={{
                          fontSize: 11, fontWeight: 700, color: 'var(--text)',
                          background: 'var(--bg3)', borderRadius: 3,
                          padding: '1px 5px', flexShrink: 0,
                        }}>{fmtItemQty(item.quantity, item.unit_type)}</span>
                        <span style={{ fontSize: 13, color: nameCol, flex: 1, fontWeight: 500 }}>
                          {item.product?.name || `#${item.product_id}`}
                        </span>
                        {kdsC.label && (
                          <span style={{
                            fontSize: 9, fontWeight: 800, color: kdsC.textColor,
                            borderRadius: 3, padding: '1px 5px',
                            border: `1px solid ${kdsC.textColor}60`,
                          }}>{kdsC.label}</span>
                        )}
                      </div>
                    )
                  })}
                  {/* Quick actions */}
                  <div style={{ display: 'flex', gap: 8, padding: '10px 14px', borderTop: '1px solid var(--border)' }}>
                    <button
                      onClick={() => onNavigate(o.id)}
                      style={{
                        flex: 1, height: 34, borderRadius: 8, border: 'none',
                        background: 'var(--bg3)', color: 'var(--text)',
                        fontSize: 13, fontWeight: 600, cursor: 'pointer',
                      }}
                    >Άνοιγμα</button>
                    {o.items?.some(i => kds(i.kds_status) === 'done') && (
                      <button
                        onClick={() => onMarkAllServed(o.id)}
                        style={{
                          flex: 1, height: 34, borderRadius: 8, border: 'none',
                          background: 'rgba(34,197,94,0.15)', color: '#4ade80',
                          fontSize: 13, fontWeight: 700, cursor: 'pointer',
                        }}
                      >Σήμανση Παραδοθέντων</button>
                    )}
                  </div>
                </div>
              )}
            </div>
          )
        })}
      </div>

      {/* Orders filter FAB */}
      <button
        onClick={() => setShowFilters(true)}
        style={{
          position: 'fixed', bottom: 84, right: 24,
          width: 52, height: 52, borderRadius: '50%', border: 'none',
          background: hasActiveOrderFilters ? 'var(--accent-dim,#92400e)' : 'var(--accent,#f59e0b)',
          color: hasActiveOrderFilters ? '#fde68a' : 'var(--accent-fg,#1c1000)',
          cursor: 'pointer',
          display: 'flex', alignItems: 'center', justifyContent: 'center',
          boxShadow: '0 4px 20px rgba(245,158,11,0.55), 0 2px 8px rgba(0,0,0,0.35)',
          zIndex: 40, transition: 'background 0.12s',
        }}
      >
        <FilterIcon size={20} />
        {hasActiveOrderFilters && (
          <span style={{
            position: 'absolute', top: 0, right: 0,
            background: '#ef4444', color: '#fff',
            fontSize: 9, fontWeight: 800,
            borderRadius: '50%', width: 16, height: 16,
            display: 'flex', alignItems: 'center', justifyContent: 'center',
          }}>
            {(myOnly ? 1 : 0) + (sortBy !== 'time' ? 1 : 0) + (filter !== 'all' ? 1 : 0)}
          </span>
        )}
      </button>

      {showFilters && (
        <OrdersFilterDrawer
          myOnly={myOnly}
          setMyOnly={setMyOnly}
          sortBy={sortBy}
          setSortBy={setSortBy}
          filter={filter}
          setFilter={setFilter}
          onClose={() => setShowFilters(false)}
        />
      )}
    </div>
  )
}

// ─── Standalone order card (takeaway / delivery) ──────────────────────────────

function StandaloneOrderCard({ order, onClick }) {
  const isDelivery = order.order_type === 'delivery'
  const activeItems = (order.items || []).filter(i => i.status === 'active')
  const paidItems  = (order.items || []).filter(i => i.status === 'paid')
  const total = [...activeItems, ...paidItems].reduce((s, i) => s + (i.unit_price + (i.price_adjustment || 0)) * i.quantity, 0)

  const statusColor = {
    open: '#f59e0b',
    partially_paid: '#60a5fa',
    paid: '#4ade80',
  }[order.status] || '#94a3b8'

  const kds = order.kds_status || 'pending'
  const kdsColor = { pending: '#f59e0b', preparing: '#60a5fa', done: '#4ade80', served: '#94a3b8' }[kds] || '#94a3b8'

  return (
    <div
      onClick={onClick}
      style={{
        background: 'var(--bg2)',
        border: `2px solid ${isDelivery ? 'rgba(96,165,250,0.35)' : 'rgba(245,158,11,0.35)'}`,
        borderRadius: 14,
        padding: '12px 14px',
        cursor: 'pointer',
        display: 'flex',
        flexDirection: 'column',
        gap: 6,
        minHeight: 90,
        position: 'relative',
        overflow: 'hidden',
      }}
    >
      {/* Type badge top-right */}
      <span style={{
        position: 'absolute', top: 8, right: 8,
        fontSize: 9, fontWeight: 800, letterSpacing: 0.5,
        padding: '2px 7px', borderRadius: 6,
        background: isDelivery ? 'rgba(96,165,250,0.18)' : 'rgba(245,158,11,0.18)',
        color: isDelivery ? '#93c5fd' : '#fbbf24',
        border: `1px solid ${isDelivery ? '#60a5fa44' : '#f59e0b44'}`,
      }}>
        {isDelivery ? 'DELIVERY' : 'TAKEAWAY'}
      </span>

      {/* Order id */}
      <span style={{ fontSize: 16, fontWeight: 800, color: 'var(--text)', letterSpacing: -0.3, paddingRight: 72 }}>
        #{order.id}
      </span>

      {/* Status + KDS row */}
      <div style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
        <span style={{
          fontSize: 9, fontWeight: 800, letterSpacing: 0.3,
          padding: '2px 6px', borderRadius: 4,
          background: `${statusColor}22`, color: statusColor,
          border: `1px solid ${statusColor}44`,
        }}>
          {{ open: 'ΑΝΟΙΧΤΟ', partially_paid: 'ΜΕΡ. ΠΛΗΡΩΜ.', paid: 'ΠΛΗΡΩΜΕΝΟ' }[order.status] || order.status.toUpperCase()}
        </span>
        {kds !== 'served' && (
          <span style={{
            fontSize: 9, fontWeight: 800, letterSpacing: 0.3,
            padding: '2px 6px', borderRadius: 4,
            background: `${kdsColor}22`, color: kdsColor,
            border: `1px solid ${kdsColor}44`,
          }}>
            {{ pending: 'ΕΚΚΡΕΜΕΙ', preparing: 'ΕΤΟΙΜΑΖΕΤΑΙ', done: 'READY' }[kds] || kds.toUpperCase()}
          </span>
        )}
      </div>

      {/* Total + item count */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'baseline', marginTop: 'auto' }}>
        <span style={{ fontSize: 11, color: 'var(--muted)' }}>{activeItems.length + paidItems.length} είδη</span>
        <span style={{ fontSize: 14, fontWeight: 700, color: 'var(--text)' }}>{total.toFixed(2)} €</span>
      </div>
    </div>
  )
}

// ─── New standalone action card (+ New Takeaway / + New Delivery) ─────────────

function NewStandaloneCard({ label, color, icon, onClick }) {
  return (
    <div
      onClick={onClick}
      style={{
        background: `${color}0f`,
        border: `2px dashed ${color}55`,
        borderRadius: 14,
        padding: '12px 14px',
        cursor: 'pointer',
        display: 'flex',
        flexDirection: 'column',
        alignItems: 'center',
        justifyContent: 'center',
        gap: 8,
        minHeight: 90,
      }}
    >
      <span style={{ fontSize: 24, color }}>{icon}</span>
      <span style={{ fontSize: 13, fontWeight: 700, color, textAlign: 'center', lineHeight: 1.3 }}>{label}</span>
    </div>
  )
}

// ─── Standalone page view ─────────────────────────────────────────────────────

function StandaloneView({ orders, gridCols, navigate }) {
  const standaloneOrders = orders
    .filter(o => o.order_type === 'takeaway' || o.order_type === 'delivery')
    .sort((a, b) => new Date(a.opened_at || 0) - new Date(b.opened_at || 0))

  return (
    <div style={{ flex: 1, overflowY: 'auto', minHeight: 0 }}>
      <div style={{
        display: 'grid',
        gridTemplateColumns: gridCols,
        gap: 10,
        padding: '12px 12px 88px',
        alignContent: 'start',
      }}>
        {/* Fixed action cards always at top */}
        <NewStandaloneCard
          label="+ Νέο Takeaway"
          color="#f59e0b"
          icon="🥡"
          onClick={() => navigate('/standalone/takeaway/add?new=1')}
        />
        <NewStandaloneCard
          label="+ Νέα Delivery"
          color="#60a5fa"
          icon="🛵"
          onClick={() => navigate('/standalone/delivery/add?new=1')}
        />

        {/* Open standalone orders */}
        {standaloneOrders.map(o => (
          <StandaloneOrderCard
            key={o.id}
            order={o}
            onClick={() => navigate(`/orders/${o.id}`)}
          />
        ))}
      </div>
    </div>
  )
}

// ─── Zone tab pill ────────────────────────────────────────────────────────────

function ZoneTab({ label, color, active, onClick }) {
  return (
    <button
      onClick={onClick}
      style={{
        display: 'flex', alignItems: 'center', gap: 6,
        padding: '8px 16px', borderRadius: 20,
        border: '2px solid transparent',
        cursor: 'pointer', whiteSpace: 'nowrap', flexShrink: 0,
        fontWeight: 600, fontSize: 14, lineHeight: 1,
        background: active ? 'var(--accent)' : 'var(--bg3)',
        color: active ? 'var(--accent-fg)' : 'var(--muted)',
        transition: 'background 0.12s, color 0.12s',
      }}
    >
      {color && (
        <span style={{
          width: 8, height: 8, borderRadius: '50%',
          background: color, flexShrink: 0,
          opacity: active ? 1 : 0.7,
        }} />
      )}
      {label}
    </button>
  )
}
