import { useState } from 'react'
import { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'
import { useNavigate } from 'react-router-dom'
import toast from 'react-hot-toast'
import client from '../api/client'

// ─── Business Day + Shift Management Panel ───────────────────────────────────

function fmtTime(iso) {
  if (!iso) return '—'
  return new Date(iso).toLocaleTimeString('el-GR', { hour: '2-digit', minute: '2-digit' })
}

function fmtShiftDuration(iso) {
  if (!iso) return ''
  const mins = Math.floor((Date.now() - new Date(iso).getTime()) / 60000)
  if (mins < 60) return `${mins}λ`
  const h = Math.floor(mins / 60); const m = mins % 60
  return m === 0 ? `${h}ω` : `${h}ω ${m}λ`
}

function StartShiftModal({ waiters, onClose, onStart }) {
  const [waiterId, setWaiterId] = useState('')
  const [cash, setCash] = useState('')
  const [busy, setBusy] = useState(false)

  async function submit() {
    if (!waiterId) { toast.error('Επιλέξτε σερβιτόρο'); return }
    setBusy(true)
    try {
      await onStart(Number(waiterId), cash ? parseFloat(cash) : null)
      onClose()
    } catch (e) {
      toast.error(e.response?.data?.detail || 'Σφάλμα εκκίνησης βάρδιας')
    } finally {
      setBusy(false)
    }
  }

  return (
    <div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4"
      onClick={e => { if (e.target === e.currentTarget) onClose() }}>
      <div className="bg-white rounded-2xl shadow-xl w-full max-w-sm p-6 space-y-4">
        <div className="flex items-center justify-between">
          <h2 className="text-lg font-bold text-gray-800">Έναρξη Βάρδιας</h2>
          <button onClick={onClose} className="text-gray-400 hover:text-gray-600 text-xl">✕</button>
        </div>
        <div>
          <label className="text-xs font-semibold text-gray-500 uppercase tracking-wide block mb-1">Σερβιτόρος</label>
          <select className="h-10 w-full rounded-lg border border-gray-300 bg-white px-3 text-sm text-gray-800 focus:outline-none"
            value={waiterId} onChange={e => setWaiterId(e.target.value)}>
            <option value="">— Επιλέξτε —</option>
            {waiters.map(w => <option key={w.id} value={w.id}>{w.full_name || w.username}</option>)}
          </select>
        </div>
        <div>
          <label className="text-xs font-semibold text-gray-500 uppercase tracking-wide block mb-1">Αρχικά Μετρητά (€)</label>
          <input type="number" step="0.01" min="0" placeholder="0.00" value={cash} onChange={e => setCash(e.target.value)}
            className="h-10 w-full rounded-lg border border-gray-300 bg-white px-3 text-sm text-gray-800 focus:outline-none" />
        </div>
        <div className="flex gap-3 pt-1">
          <button onClick={onClose} className="flex-1 h-10 px-4 rounded-lg border border-gray-300 text-sm font-medium text-gray-700 hover:bg-gray-50">Ακύρωση</button>
          <button onClick={submit} disabled={busy}
            className="flex-1 h-10 px-4 rounded-lg bg-primary-600 text-white text-sm font-semibold hover:bg-primary-700 disabled:opacity-60">
            {busy ? 'Εκκίνηση…' : 'Έναρξη'}
          </button>
        </div>
      </div>
    </div>
  )
}

function CloseConfirmModal({ details, onClose, onConfirm, busy }) {
  const hasPendingPayments = details.partially_paid > 0

  if (!hasPendingPayments) {
    // All tables open but nothing owed — safe to close, just needs confirmation
    return (
      <div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4"
        onClick={e => { if (e.target === e.currentTarget) onClose() }}>
        <div className="bg-white rounded-2xl shadow-xl w-full max-w-md p-6 space-y-4">
          <h2 className="text-lg font-bold text-gray-800">Κλείσιμο Ημέρας</h2>
          <div className="bg-blue-50 border border-blue-200 rounded-xl p-4 text-sm text-blue-800 space-y-2">
            <p className="font-semibold">
              {details.open_orders} {details.open_orders === 1 ? 'τραπέζι είναι ακόμα ανοιχτό' : 'τραπέζια είναι ακόμα ανοιχτά'}
            </p>
            <p>Κανένα δεν έχει εκκρεμείς χρεώσεις. Θέλετε να κλείσουν όλα και να κλείσει η ημέρα;</p>
          </div>
          <div className="flex gap-3">
            <button onClick={onClose} className="flex-1 h-10 px-4 rounded-lg border border-gray-300 text-sm font-medium text-gray-700 hover:bg-gray-50">
              Ακύρωση
            </button>
            <button onClick={onConfirm} disabled={busy}
              className="flex-1 h-10 px-4 rounded-lg bg-primary-600 text-white text-sm font-semibold hover:bg-primary-700 disabled:opacity-60">
              {busy ? 'Κλείσιμο…' : 'Κλείσε Όλα & Κλείσε Ημέρα'}
            </button>
          </div>
        </div>
      </div>
    )
  }

  // Some tables have unpaid items — revenue will be lost, needs hard warning
  return (
    <div className="fixed inset-0 bg-black/40 flex items-center justify-center z-50 p-4"
      onClick={e => { if (e.target === e.currentTarget) onClose() }}>
      <div className="bg-white rounded-2xl shadow-xl w-full max-w-md p-6 space-y-4">
        <div className="flex items-center gap-3">
          <div className="w-10 h-10 rounded-full bg-red-100 flex items-center justify-center flex-shrink-0">
            <span className="text-red-600 text-lg font-bold">!</span>
          </div>
          <h2 className="text-lg font-bold text-gray-800">Εκκρεμείς Πληρωμές</h2>
        </div>
        <div className="bg-red-50 border border-red-200 rounded-xl p-4 text-sm text-red-800 space-y-2">
          <p className="font-semibold">
            {details.open_orders} {details.open_orders === 1 ? 'ανοιχτό τραπέζι' : 'ανοιχτά τραπέζια'},
            από τα οποία <span className="underline">{details.partially_paid} έχ{details.partially_paid === 1 ? 'ει' : 'ουν'} εκκρεμείς πληρωμές</span>.
          </p>
          <p>Αν κλείσετε αναγκαστικά, τα απλήρωτα ποσά θα χαθούν και δεν θα καταγραφούν στις αναφορές.</p>
        </div>
        <div className="rounded-xl border border-gray-200 p-3 text-xs text-gray-500 bg-gray-50">
          Επιλέξτε <strong>Ακύρωση</strong> για να χειριστείτε χειροκίνητα τα εκκρεμή τραπέζια πριν κλείσετε την ημέρα.
        </div>
        <div className="flex gap-3">
          <button onClick={onClose} className="flex-1 h-10 px-4 rounded-lg border border-gray-300 text-sm font-medium text-gray-700 hover:bg-gray-50">
            Ακύρωση
          </button>
          <button onClick={onConfirm} disabled={busy}
            className="flex-1 h-10 px-4 rounded-lg bg-red-600 text-white text-sm font-semibold hover:bg-red-700 disabled:opacity-60">
            {busy ? 'Κλείσιμο…' : 'Αναγκαστικό Κλείσιμο'}
          </button>
        </div>
      </div>
    </div>
  )
}

function BusinessDayPanel() {
  const qc = useQueryClient()
  const [showStartShift, setShowStartShift] = useState(false)
  const [closeDetails, setCloseDetails] = useState(null)
  const [forceClosing, setForceClosing] = useState(false)

  const { data: businessDay } = useQuery({
    queryKey: ['business-day'],
    queryFn: () => client.get('/api/business-day/current').then(r => r.data),
    refetchInterval: 15_000,
  })

  const { data: activeShifts = [] } = useQuery({
    queryKey: ['active-shifts'],
    queryFn: () => client.get('/api/shifts/?active_only=true').then(r => r.data.shifts ?? []),
    refetchInterval: 15_000,
  })

  const { data: allWaiters = [] } = useQuery({
    queryKey: ['waiters'],
    queryFn: () => client.get('/api/waiters/').then(r => r.data),
    staleTime: 60_000,
  })

  const waitersWithoutShift = allWaiters.filter(
    w => w.role === 'waiter' && !activeShifts.some(s => s.waiter_id === w.id)
  )

  const openDayMut = useMutation({
    mutationFn: () => client.post('/api/business-day/open', {}),
    onSuccess: () => { toast.success('Ημέρα ανοίχτηκε!'); qc.invalidateQueries({ queryKey: ['business-day'] }) },
    onError: (e) => toast.error(e.response?.data?.detail || 'Σφάλμα'),
  })

  async function handleCloseDay(force = false) {
    setForceClosing(force)
    try {
      await client.post('/api/business-day/close', { force })
      toast.success('Ημέρα έκλεισε!')
      setCloseDetails(null)
      qc.invalidateQueries({ queryKey: ['business-day'] })
      qc.invalidateQueries({ queryKey: ['active-shifts'] })
      qc.invalidateQueries({ queryKey: ['orders-active'] })
    } catch (e) {
      const detail = e.response?.data?.detail
      if (e.response?.status === 409 && detail?.open_orders) {
        setCloseDetails(detail)
      } else {
        toast.error(typeof detail === 'string' ? detail : 'Σφάλμα κλεισίματος')
      }
    } finally {
      setForceClosing(false)
    }
  }

  async function handleEndShift(shiftId, waiterName) {
    if (!window.confirm(`Να τελειώσει η βάρδια του ${waiterName};`)) return
    try {
      await client.post(`/api/shifts/manager/end/${shiftId}`, {})
      toast.success('Βάρδια έκλεισε')
      qc.invalidateQueries({ queryKey: ['active-shifts'] })
    } catch (e) {
      toast.error(e.response?.data?.detail || 'Σφάλμα')
    }
  }

  async function handleStartShift(waiterId, startingCash) {
    await client.post('/api/shifts/manager/start', { waiter_id: waiterId, starting_cash: startingCash })
    toast.success('Βάρδια ξεκίνησε!')
    qc.invalidateQueries({ queryKey: ['active-shifts'] })
  }

  const isOpen = !!businessDay

  return (
    <>
      <div className="rounded-2xl border overflow-hidden"
        style={{ borderColor: isOpen ? '#bbf7d0' : '#e5e7eb' }}>
        {/* Header row */}
        <div className="flex items-center justify-between px-5 py-3"
          style={{ background: isOpen ? '#f0fdf4' : '#f9fafb' }}>
          <div className="flex items-center gap-3">
            <div style={{
              width: 10, height: 10, borderRadius: '50%',
              background: isOpen ? '#16a34a' : '#9ca3af',
              boxShadow: isOpen ? '0 0 0 3px #bbf7d0' : 'none',
            }} />
            <div>
              <span className="font-bold text-sm" style={{ color: isOpen ? '#15803d' : '#6b7280' }}>
                {isOpen ? 'Εστιατόριο Ανοιχτό' : 'Εστιατόριο Κλειστό'}
              </span>
              {isOpen && businessDay?.opened_at && (
                <span className="text-xs text-gray-500 ml-2">
                  από {fmtTime(businessDay.opened_at)}
                </span>
              )}
            </div>
          </div>
          <div className="flex gap-2">
            {isOpen && waitersWithoutShift.length > 0 && (
              <button
                onClick={() => setShowStartShift(true)}
                className="h-8 px-3 rounded-lg bg-white border border-gray-300 text-xs font-semibold text-gray-700 hover:bg-gray-50"
              >
                + Βάρδια
              </button>
            )}
            {isOpen ? (
              <button
                onClick={() => handleCloseDay(false)}
                className="h-8 px-3 rounded-lg bg-red-600 text-white text-xs font-semibold hover:bg-red-700"
              >
                Κλείσιμο Ημέρας
              </button>
            ) : (
              <button
                onClick={() => openDayMut.mutate()}
                disabled={openDayMut.isPending}
                className="h-8 px-4 rounded-lg bg-green-600 text-white text-xs font-semibold hover:bg-green-700 disabled:opacity-60"
              >
                {openDayMut.isPending ? 'Άνοιγμα…' : '▶ Άνοιγμα Ημέρας'}
              </button>
            )}
          </div>
        </div>

        {/* Active shifts */}
        {isOpen && (
          <div className="px-5 py-3 border-t border-gray-100 bg-white">
            {activeShifts.length === 0 ? (
              <p className="text-xs text-gray-400">Κανένας σερβιτόρος σε βάρδια</p>
            ) : (
              <div className="flex flex-wrap gap-2">
                {activeShifts.map(s => (
                  <div key={s.id} className="flex items-center gap-2 bg-gray-50 border border-gray-200 rounded-xl px-3 py-1.5">
                    <div>
                      <span className="text-sm font-semibold text-gray-800">{s.waiter_name}</span>
                      <span className="text-xs text-gray-500 ml-2">{fmtTime(s.started_at)} · {fmtShiftDuration(s.started_at)}</span>
                      {s.total_collected > 0 && (
                        <span className="text-xs text-green-700 ml-2 font-medium">€{s.total_collected.toFixed(2)}</span>
                      )}
                    </div>
                    <button
                      onClick={() => handleEndShift(s.id, s.waiter_name)}
                      className="text-xs text-red-500 hover:text-red-700 ml-1 font-medium"
                      title="Τέλος βάρδιας"
                    >
                      ⏹
                    </button>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>

      {showStartShift && (
        <StartShiftModal
          waiters={waitersWithoutShift}
          onClose={() => setShowStartShift(false)}
          onStart={handleStartShift}
        />
      )}
      {closeDetails && (
        <CloseConfirmModal
          details={closeDetails}
          onClose={() => setCloseDetails(null)}
          onConfirm={() => handleCloseDay(true)}
          busy={forceClosing}
        />
      )}
    </>
  )
}

const API_URL = import.meta.env.VITE_API_URL || ''

const FILTERS = ['all', 'open', 'partially_paid', 'free']
const FILTER_LABELS = { all: 'Όλα', open: 'Ανοιχτά', partially_paid: 'Μερική πληρωμή', free: 'Ελεύθερα' }

// ─── Design tokens ────────────────────────────────────────────────────────────
const COLORS = {
  open: {
    label: 'Ανοιχτό',
    tint: '#eef7f0', tintStrong: '#d7ecdc',
    accent: '#2f9e5e', ink: '#1f7042',
  },
  partially_paid: {
    label: 'Μερική πληρ.',
    tint: '#f4eefb', tintStrong: '#e3d4f3',
    accent: '#7a44c9', ink: '#57309a',
  },
  free: {
    label: 'Ελεύθερο',
    tint: '#f4f4f2', tintStrong: '#dfe2e6',
    accent: '#8a9099', ink: '#5a6169',
  },
}

// ─── Helpers ──────────────────────────────────────────────────────────────────
function formatEuro(n) {
  return '€' + parseFloat(n).toFixed(2)
}

function formatDuration(openedAt) {
  const mins = Math.floor((Date.now() - new Date(openedAt).getTime()) / 60000)
  if (mins < 60) return `${mins}m`
  const h = Math.floor(mins / 60)
  const m = mins % 60
  return m === 0 ? `${h}h` : `${h}h ${m}m`
}

function occupiedMinsFromDate(openedAt) {
  return Math.floor((Date.now() - new Date(openedAt).getTime()) / 60000)
}

function orderTotal(items = []) {
  return items
    .filter(i => i.status !== 'cancelled')
    .reduce((s, i) => s + i.unit_price * i.quantity, 0)
}

function avatarColor(name) {
  const palette = ['#3758c9', '#7a44c9', '#2f9e5e', '#d94b26', '#8a6d2b', '#0d7a8a', '#c93775']
  let h = 0
  for (let i = 0; i < name.length; i++) h = (h * 31 + name.charCodeAt(i)) >>> 0
  return palette[h % palette.length]
}

function WaiterBubble({ waiter, size = 26 }) {
  // waiter: { name, avatarUrl }
  if (waiter.avatarUrl) {
    return (
      <img
        src={waiter.avatarUrl}
        alt={waiter.name}
        style={{
          width: size, height: size, borderRadius: '50%', objectFit: 'cover',
          flexShrink: 0, boxShadow: '0 0 0 2px var(--cardBg, white)',
        }}
      />
    )
  }
  const parts = waiter.name.trim().split(' ')
  const initials = (parts[0][0] + (parts[1]?.[0] || '')).toUpperCase()
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: avatarColor(waiter.name),
      color: 'white',
      fontSize: size * 0.42,
      fontWeight: 600,
      display: 'flex', alignItems: 'center', justifyContent: 'center',
      flexShrink: 0,
      boxShadow: '0 0 0 2px var(--cardBg, white)',
    }}>{initials}</div>
  )
}

// ─── V1 Table Card ────────────────────────────────────────────────────────────
function TableCardV1({ name, status, amount, openedAt, waiters = [], hasPendingPrint = false, onClick }) {
  const s = COLORS[status] || COLORS.free
  const [hover, setHover] = useState(false)
  const [pressed, setPressed] = useState(false)

  const occupiedMins = openedAt ? occupiedMinsFromDate(openedAt) : null
  const showMulti = waiters.length >= 3

  return (
    <button
      type="button"
      onClick={onClick}
      onMouseEnter={() => setHover(true)}
      onMouseLeave={() => { setHover(false); setPressed(false) }}
      onMouseDown={() => setPressed(true)}
      onMouseUp={() => setPressed(false)}
      style={{
        '--cardBg': s.tint,
        position: 'relative',
        width: '100%', minWidth: 330, height: 200,
        padding: '16px 18px 16px 24px',
        background: s.tint,
        border: '1px solid ' + s.tintStrong,
        borderRadius: 14,
        boxShadow: pressed
          ? 'inset 0 2px 4px rgba(16,20,24,0.08)'
          : hover
            ? '0 6px 18px rgba(16,20,24,0.08), 0 2px 4px rgba(16,20,24,0.04)'
            : '0 1px 2px rgba(16,20,24,0.04), 0 1px 1px rgba(16,20,24,0.03)',
        transform: pressed ? 'translateY(1px)' : hover ? 'translateY(-2px)' : 'translateY(0)',
        transition: 'transform 120ms ease, box-shadow 120ms ease',
        cursor: onClick ? 'pointer' : 'default',
        textAlign: 'left',
        font: 'inherit',
        color: 'inherit',
        display: 'flex', flexDirection: 'column',
        outline: 'none',
        flexShrink: 0,
      }}
    >
      {/* left accent bar */}
      <div style={{
        position: 'absolute', left: 0, top: 0, bottom: 0, width: 6,
        background: s.accent,
        borderRadius: '14px 0 0 14px',
      }} />

      {/* Header: name + status pill */}
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', gap: 10 }}>
        <div style={{
          fontSize: 34, fontWeight: 700, lineHeight: 1,
          letterSpacing: -0.5,
          color: '#111315',
          fontFamily: "'Geist Mono', 'ui-monospace', 'SFMono-Regular', monospace",
        }}>{name}</div>
        <div style={{
          display: 'inline-flex', alignItems: 'center', gap: 6,
          height: 26, padding: '0 10px',
          borderRadius: 999,
          background: s.accent,
          color: 'white',
          fontSize: 12, fontWeight: 600,
          letterSpacing: 0.2,
          whiteSpace: 'nowrap',
          flexShrink: 0,
        }}>
          <span style={{ width: 6, height: 6, borderRadius: '50%', background: 'rgba(255,255,255,0.9)' }} />
          {s.label}
        </div>
      </div>

      {/* Flags row */}
      <div style={{ marginTop: 8, height: 22, display: 'flex', alignItems: 'center', gap: 6 }}>
        {hasPendingPrint && (
          <span style={{
            fontSize: 11, fontWeight: 700,
            background: '#92400e', color: '#fcd34d',
            borderRadius: 999, padding: '2px 8px',
            display: 'inline-flex', alignItems: 'center', gap: 4,
          }}>
            ⏳ Εκκρεμής εκτύπωση
          </span>
        )}
      </div>

      {/* Stats row */}
      <div style={{
        marginTop: 'auto',
        display: 'grid',
        gridTemplateColumns: '1fr 1fr',
        gap: 8,
        alignItems: 'end',
      }}>
        <div>
          <div style={{ fontSize: 11, fontWeight: 600, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.6 }}>Total</div>
          <div style={{ fontSize: 22, fontWeight: 600, color: '#111315', marginTop: 2, fontFamily: "'Geist Mono', 'ui-monospace', 'SFMono-Regular', monospace" }}>
            {amount != null ? formatEuro(amount) : <span style={{ color: '#b8bdc4', letterSpacing: 2 }}>— —</span>}
          </div>
        </div>
        <div>
          <div style={{ fontSize: 11, fontWeight: 600, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.6 }}>Time</div>
          <div style={{
            fontSize: 22, marginTop: 2,
            fontFamily: "'Geist Mono', 'ui-monospace', 'SFMono-Regular', monospace",
            fontWeight: occupiedMins != null && occupiedMins >= 90 ? 700 : 500,
            color: '#111315',
          }}>
            {openedAt ? formatDuration(openedAt) : <span style={{ color: '#b8bdc4', letterSpacing: 2 }}>— —</span>}
          </div>
        </div>
      </div>

      {/* Waiter row */}
      <div style={{
        marginTop: 12,
        paddingTop: 10,
        borderTop: '1px solid ' + s.tintStrong,
        height: 36,
        display: 'flex', alignItems: 'center', gap: 8,
      }}>
        {waiters.length === 0 ? (
          <span style={{ color: '#8a9099', fontSize: 13 }}>Unassigned</span>
        ) : showMulti ? (
          <>
            <div style={{ display: 'flex' }}>
              {waiters.slice(0, 3).map((w, i) => (
                <div key={i} style={{ marginLeft: i === 0 ? 0 : -8 }}>
                  <WaiterBubble waiter={w} size={24} />
                </div>
              ))}
            </div>
            <span style={{
              fontSize: 13, fontWeight: 600, color: '#2b2f33',
              background: 'white', border: '1px solid #dfe2e6',
              borderRadius: 999, padding: '2px 8px',
            }}>Multiple ({waiters.length})</span>
          </>
        ) : (
          waiters.map((w, i) => (
            <div key={i} style={{ display: 'flex', alignItems: 'center', gap: 6 }}>
              <WaiterBubble waiter={w} size={24} />
              <span style={{ fontSize: 14, color: '#2b2f33', fontWeight: 500 }}>{w.shortName}</span>
            </div>
          ))
        )}
      </div>
    </button>
  )
}

// ─── Page ─────────────────────────────────────────────────────────────────────
export default function DashboardPage() {
  const [filter, setFilter] = useState('all')
  const [retryingId, setRetryingId] = useState(null)
  const navigate = useNavigate()
  const queryClient = useQueryClient()

  const { data: tables = [], isLoading: tablesLoading } = useQuery({
    queryKey: ['tables'],
    queryFn: () => client.get('/api/tables/').then(r => r.data),
    refetchInterval: 5_000,
  })

  const { data: orders = [], isLoading: ordersLoading } = useQuery({
    queryKey: ['orders-active'],
    queryFn: () => client.get('/api/orders/').then(r => r.data),
    refetchInterval: 5_000,
  })

  const { data: waiters = [] } = useQuery({
    queryKey: ['waiters'],
    queryFn: () => client.get('/api/waiters/').then(r => r.data),
    staleTime: 60_000,
  })

  // waiterMap: id → { name (display), shortName (nickname or first name), avatarUrl }
  const waiterMap = Object.fromEntries(waiters.map(w => {
    const name = w.full_name || w.nickname || w.username
    const shortName = w.nickname || (w.full_name ? w.full_name.split(' ')[0] : w.username)
    const avatarUrl = w.avatar_url ? API_URL + w.avatar_url : null
    return [w.id, { name, shortName, avatarUrl }]
  }))

  const tableCards = tables.map(table => {
    const order = orders.find(o =>
      o.table_id === table.id && ['open', 'partially_paid'].includes(o.status)
    )
    const tableStatus = order ? order.status : 'free'
    const hasPendingPrint = order
      ? order.items.some(i => i.status === 'active' && !i.printed)
      : false
    return { table, order, tableStatus, hasPendingPrint }
  })

  const pendingPrintOrders = tableCards.filter(c => c.hasPendingPrint)

  async function retrySingleOrder(orderId) {
    setRetryingId(orderId)
    try {
      const res = await client.post(`/api/orders/${orderId}/retry-print`)
      const results = res.data.print_results ?? []
      const allOk = results.length === 0 || results.every(r => r.success)
      if (allOk) {
        toast.success('Εκτυπώθηκε επιτυχώς')
      } else {
        const failed = results.filter(r => !r.success).map(r => r.printer_name).join(', ')
        toast.error(`Αποτυχία: ${failed}`)
      }
      queryClient.invalidateQueries({ queryKey: ['orders-active'] })
    } catch {
      toast.error('Σφάλμα επικοινωνίας')
    } finally {
      setRetryingId(null)
    }
  }

  async function retryAllOrders() {
    for (const { order } of pendingPrintOrders) {
      if (order) await retrySingleOrder(order.id)
    }
  }

  const filtered = filter === 'all'
    ? tableCards
    : tableCards.filter(c => c.tableStatus === filter)

  if (tablesLoading || ordersLoading) {
    return <div className="flex items-center justify-center h-64 text-gray-400">Φόρτωση…</div>
  }

  return (
    <div className="space-y-6">
      <BusinessDayPanel />

      <div className="flex items-center justify-between">
        <h1 className="text-xl font-bold text-gray-800">Dashboard</h1>
        <div className="flex gap-2">
          {FILTERS.map(f => (
            <button
              key={f}
              onClick={() => setFilter(f)}
              className={`btn text-sm ${filter === f ? 'btn-primary' : 'btn-secondary'}`}
            >
              {FILTER_LABELS[f]}
            </button>
          ))}
        </div>
      </div>

      {filtered.length === 0 && (
        <p className="text-center text-gray-400 py-16">Δεν βρέθηκαν τραπέζια.</p>
      )}

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fill, minmax(330px, 1fr))', gap: 16 }}>
        {filtered.map(({ table, order, tableStatus, hasPendingPrint }) => {
          const waiterNames = order
            ? order.waiters.map(w => waiterMap[w.waiter_id] || { name: `#${w.waiter_id}`, shortName: `#${w.waiter_id}`, avatarUrl: null })
            : []
          const amount = order ? orderTotal(order.items) : null

          return (
            <TableCardV1
              key={table.id}
              name={table.label || `T${table.number}`}
              status={tableStatus}
              amount={amount}
              openedAt={order?.opened_at ?? null}
              waiters={waiterNames}
              hasPendingPrint={hasPendingPrint}
              onClick={order ? () => navigate(`/orders/${order.id}`) : undefined}
            />
          )
        })}
      </div>

      {/* ── Draft Orders Panel ─────────────────────────────────────────────── */}
      {pendingPrintOrders.length > 0 && (
        <div className="bg-white rounded-2xl border border-orange-200 shadow-sm overflow-hidden">
          <div className="flex items-center justify-between px-5 py-4 border-b border-orange-100" style={{ background: '#fff7ed' }}>
            <div className="flex items-center gap-3">
              <span style={{ fontSize: 20 }}>⏳</span>
              <div>
                <h2 className="text-base font-bold text-orange-900">Εκκρεμείς Εκτυπώσεις</h2>
                <p className="text-xs text-orange-700 mt-0.5">
                  {pendingPrintOrders.length} παραγγελί{pendingPrintOrders.length !== 1 ? 'ες' : 'α'} δεν έχ{pendingPrintOrders.length !== 1 ? 'ουν' : 'ει'} σταλεί στην κουζίνα/μπαρ
                </p>
              </div>
            </div>
            <button
              className="btn btn-primary text-sm"
              style={{ background: '#c2410c', borderColor: '#c2410c' }}
              onClick={retryAllOrders}
              disabled={retryingId !== null}
            >
              {retryingId !== null ? 'Αποστολή…' : 'Αποστολή Όλων'}
            </button>
          </div>

          <div className="divide-y divide-orange-50">
            {pendingPrintOrders.map(({ table, order }) => {
              const unprinted = order.items.filter(i => i.status === 'active' && !i.printed)
              const tableName = table.label || `T${table.number}`
              return (
                <div key={order.id} className="flex items-center gap-4 px-5 py-3">
                  <div className="shrink-0 w-10 h-10 rounded-xl flex items-center justify-center font-bold text-sm"
                    style={{ background: '#fff7ed', color: '#c2410c', border: '1px solid #fed7aa' }}>
                    {tableName}
                  </div>
                  <div className="flex-1 min-w-0">
                    <p className="text-sm font-semibold text-gray-800">
                      {unprinted.length} αντικείμενο{unprinted.length !== 1 ? 'α' : ''} εκκρεμούν
                    </p>
                    <p className="text-xs text-gray-500 truncate">
                      {unprinted.map(i => i.product?.name || `#${i.product_id}`).join(', ')}
                    </p>
                  </div>
                  <div className="flex items-center gap-2 shrink-0">
                    <button
                      className="btn btn-secondary text-xs"
                      onClick={() => navigate(`/orders/${order.id}`)}
                    >
                      Λεπτομέρειες
                    </button>
                    <button
                      className="btn btn-primary text-xs"
                      style={{ background: '#c2410c', borderColor: '#c2410c' }}
                      onClick={() => retrySingleOrder(order.id)}
                      disabled={retryingId === order.id}
                    >
                      {retryingId === order.id ? '…' : 'Εκτύπωση'}
                    </button>
                  </div>
                </div>
              )
            })}
          </div>
        </div>
      )}
    </div>
  )
}
