import { useState, useEffect } 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'
import StatusBadge from '../components/StatusBadge'
import ConfirmModal from '../components/ConfirmModal'

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

// ─── Helpers ──────────────────────────────────────────────────────────────────

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

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

function fmtEuro(n) {
  return '€' + parseFloat(n || 0).toFixed(2)
}

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 Avatar({ name, avatarUrl, size = 36 }) {
  if (avatarUrl) {
    return (
      <img src={avatarUrl} alt={name}
        style={{ width: size, height: size, borderRadius: '50%', objectFit: 'cover', flexShrink: 0 }} />
    )
  }
  const parts = (name || '?').trim().split(' ')
  const initials = (parts[0][0] + (parts[1]?.[0] || '')).toUpperCase()
  return (
    <div style={{
      width: size, height: size, borderRadius: '50%',
      background: avatarColor(name || '?'),
      color: 'white', fontSize: size * 0.38, fontWeight: 700,
      display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0,
    }}>{initials}</div>
  )
}

// ─── Table color tokens ────────────────────────────────────────────────────────

const TABLE_COLORS = {
  open:           { bg: '#eef7f0', border: '#d7ecdc', dot: '#2f9e5e', text: '#1f7042', label: 'Ανοιχτό' },
  partially_paid: { bg: '#f4eefb', border: '#e3d4f3', dot: '#7a44c9', text: '#57309a', label: 'Μερική πληρ.' },
  free:           { bg: '#f4f4f2', border: '#dfe2e6', dot: '#8a9099', text: '#5a6169', label: 'Ελεύθερο' },
}

// ─── Business Day / Shift modals ───────────────────────────────────────────────

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 }) {
  if (!details.partially_paid) {
    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>
    )
  }
  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>
  )
}

// ─── Order quick-view modal ────────────────────────────────────────────────────

function OrderQuickModal({ orderId, tableName, onClose, onOpenFull }) {
  const qc = useQueryClient()

  const { data: order, isLoading } = useQuery({
    queryKey: ['order', orderId],
    queryFn: () => client.get(`/api/orders/${orderId}`).then(r => r.data),
    enabled: !!orderId,
  })

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

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

  const [confirmAction, setConfirmAction] = useState(null)
  const [printerId, setPrinterId] = useState('')

  const waiterMap = Object.fromEntries(waiters.map(w => [w.id, w.nickname || w.full_name || w.username]))

  const invalidate = () => {
    qc.invalidateQueries({ queryKey: ['order', orderId] })
    qc.invalidateQueries({ queryKey: ['orders-active'] })
  }

  const payItems = useMutation({
    mutationFn: (item_ids) => client.post(`/api/orders/${orderId}/pay`, { item_ids }),
    onSuccess: () => { toast.success('Πληρώθηκε'); invalidate() },
    onError: () => toast.error('Σφάλμα πληρωμής'),
  })

  const cancelItem = useMutation({
    mutationFn: (itemId) => client.delete(`/api/orders/${orderId}/items/${itemId}`),
    onSuccess: () => { toast.success('Αντικείμενο ακυρώθηκε'); invalidate() },
    onError: () => toast.error('Σφάλμα ακύρωσης'),
  })

  const cancelOrder = useMutation({
    mutationFn: () => client.delete(`/api/orders/${orderId}`),
    onSuccess: () => { toast.success('Παραγγελία ακυρώθηκε'); invalidate(); onClose() },
    onError: () => toast.error('Σφάλμα ακύρωσης παραγγελίας'),
  })

  const closeOrder = useMutation({
    mutationFn: () => client.post(`/api/orders/${orderId}/close`),
    onSuccess: () => { toast.success('Παραγγελία έκλεισε'); invalidate(); onClose() },
    onError: () => toast.error('Σφάλμα κλεισίματος'),
  })

  const printOrder = useMutation({
    mutationFn: (pid) => client.post(`/api/orders/${orderId}/print`, { printer_id: pid }),
    onSuccess: () => toast.success('Αποστολή στον εκτυπωτή…'),
    onError: () => toast.error('Σφάλμα εκτύπωσης'),
  })

  function handleConfirm() {
    if (!confirmAction) return
    if (confirmAction.type === 'cancelItem') cancelItem.mutate(confirmAction.payload)
    if (confirmAction.type === 'cancelOrder') cancelOrder.mutate()
    if (confirmAction.type === 'closeOrder') closeOrder.mutate()
    setConfirmAction(null)
  }

  const total = order ? orderTotal(order.items) : 0
  const activeItems = order ? order.items.filter(i => i.status === 'active') : []
  const isOpen = order ? ['open', 'partially_paid'].includes(order.status) : 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 style={{
        background: 'white', borderRadius: 20, width: '100%', maxWidth: 720,
        maxHeight: '90vh', display: 'flex', flexDirection: 'column',
        boxShadow: '0 20px 60px rgba(0,0,0,0.2)',
        overflow: 'hidden',
      }}>
        {/* Modal header */}
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '18px 22px', borderBottom: '1px solid #edeff1', flexShrink: 0,
        }}>
          <div>
            <div style={{ fontSize: 18, fontWeight: 700, color: '#111315' }}>
              Τραπέζι {tableName}
            </div>
            {order && (
              <div style={{ fontSize: 12, color: '#5a6169', marginTop: 2 }}>
                Παραγγελία #{order.id} · από {fmtTime(order.opened_at)} · {fmtDuration(order.opened_at)}
              </div>
            )}
          </div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>
            {order && (
              <span style={{
                fontSize: 18, fontWeight: 700,
                color: '#111315',
                fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace",
              }}>{fmtEuro(total)}</span>
            )}
            {order && (
              <StatusBadge status={order.status} />
            )}
            <button
              onClick={onClose}
              style={{
                width: 32, height: 32, borderRadius: 8, border: '1px solid #dfe2e6',
                background: 'white', cursor: 'pointer', fontSize: 16, color: '#5a6169',
                display: 'flex', alignItems: 'center', justifyContent: 'center',
              }}
            >✕</button>
          </div>
        </div>

        {/* Scrollable body */}
        <div style={{ flex: 1, overflowY: 'auto', padding: '0 0 8px' }}>
          {isLoading && (
            <div style={{ padding: 40, textAlign: 'center', color: '#8a9099' }}>Φόρτωση…</div>
          )}

          {order && (
            <>
              {/* Waiters row */}
              {order.waiters.length > 0 && (
                <div style={{ padding: '12px 22px', borderBottom: '1px solid #f4f4f2', display: 'flex', alignItems: 'center', gap: 8 }}>
                  <span style={{ fontSize: 12, color: '#8a9099', fontWeight: 600, textTransform: 'uppercase', letterSpacing: 0.5 }}>Προσωπικό</span>
                  <div style={{ display: 'flex', gap: 6, flexWrap: 'wrap' }}>
                    {order.waiters.map(w => (
                      <span key={w.waiter_id} style={{
                        padding: '3px 10px', borderRadius: 999,
                        background: '#f0f4ff', color: '#3758c9',
                        fontSize: 12, fontWeight: 600,
                      }}>{waiterMap[w.waiter_id] || `#${w.waiter_id}`}</span>
                    ))}
                  </div>
                </div>
              )}

              {/* Items list */}
              <div>
                {order.items.length === 0 && (
                  <div style={{ padding: '24px', textAlign: 'center', color: '#8a9099', fontSize: 13 }}>Κανένα αντικείμενο.</div>
                )}
                {order.items.map(item => (
                  <div key={item.id} style={{
                    display: 'flex', alignItems: 'center', gap: 12,
                    padding: '10px 22px',
                    borderBottom: '1px solid #f9f9f8',
                    opacity: item.status === 'cancelled' ? 0.4 : 1,
                    textDecoration: item.status === 'cancelled' ? 'line-through' : 'none',
                  }}>
                    <div style={{ flex: 1, minWidth: 0 }}>
                      <div style={{ fontSize: 14, fontWeight: 600, color: '#111315' }}>
                        {item.product?.name ?? `#${item.product_id}`}
                        <span style={{ color: '#8a9099', fontWeight: 400, marginLeft: 6 }}>×{item.quantity}</span>
                      </div>
                      {item.notes && <div style={{ fontSize: 11, color: '#8a9099', marginTop: 1 }}>{item.notes}</div>}
                      {item.paid_by && (
                        <div style={{ fontSize: 11, color: '#2f9e5e', marginTop: 1, fontWeight: 600 }}>
                          Πληρώθηκε
                        </div>
                      )}
                    </div>
                    <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexShrink: 0 }}>
                      <span style={{
                        fontSize: 14, fontWeight: 700, color: '#111315',
                        fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace",
                        minWidth: 52, textAlign: 'right',
                      }}>{fmtEuro(item.unit_price * item.quantity)}</span>
                      {isOpen && item.status === 'active' && (
                        <>
                          <button
                            onClick={() => payItems.mutate([item.id])}
                            style={{
                              height: 28, padding: '0 10px', borderRadius: 6,
                              border: '1px solid #d7ecdc', background: '#eef7f0',
                              color: '#1f7042', fontSize: 11, fontWeight: 700, cursor: 'pointer',
                            }}
                          >Πληρωμή</button>
                          <button
                            onClick={() => setConfirmAction({ type: 'cancelItem', payload: item.id })}
                            style={{
                              height: 28, padding: '0 10px', borderRadius: 6,
                              border: '1px solid #fecaca', background: '#fef2f2',
                              color: '#dc2626', fontSize: 11, fontWeight: 700, cursor: 'pointer',
                            }}
                          >✕</button>
                        </>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </>
          )}
        </div>

        {/* Footer actions */}
        {order && (
          <div style={{
            padding: '14px 22px', borderTop: '1px solid #edeff1',
            display: 'flex', gap: 8, flexWrap: 'nowrap', flexShrink: 0,
            background: '#fafafa', alignItems: 'center',
          }}>
            {isOpen && activeItems.length > 0 && (
              <button
                onClick={() => payItems.mutate(activeItems.map(i => i.id))}
                style={{
                  height: 36, padding: '0 16px', borderRadius: 8,
                  background: '#3758c9', border: 'none', color: 'white',
                  fontSize: 13, fontWeight: 700, cursor: 'pointer',
                }}
              >Πληρωμή όλων</button>
            )}
            {isOpen && (
              <>
                <button
                  onClick={() => setConfirmAction({ type: 'closeOrder' })}
                  style={{
                    height: 36, padding: '0 14px', borderRadius: 8,
                    border: '1px solid #dfe2e6', background: 'white',
                    color: '#2b2f33', fontSize: 13, fontWeight: 600, cursor: 'pointer',
                  }}
                >Κλείσιμο</button>
                <button
                  onClick={() => setConfirmAction({ type: 'cancelOrder' })}
                  style={{
                    height: 36, padding: '0 14px', borderRadius: 8,
                    border: '1px solid #fecaca', background: '#fef2f2',
                    color: '#dc2626', fontSize: 13, fontWeight: 600, cursor: 'pointer',
                  }}
                >Ακύρωση</button>
              </>
            )}
            {printers.length > 0 && (
              <div style={{ display: 'flex', gap: 6, alignItems: 'center', marginLeft: 'auto' }}>
                <select
                  value={printerId}
                  onChange={e => setPrinterId(e.target.value)}
                  style={{
                    height: 36, paddingLeft: 10, paddingRight: 28, borderRadius: 8,
                    border: '1px solid #dfe2e6', background: 'white',
                    color: '#2b2f33', fontSize: 12, cursor: 'pointer',
                  }}
                >
                  <option value="">Εκτυπωτής…</option>
                  {printers.map(p => <option key={p.id} value={p.id}>{p.name}</option>)}
                </select>
                <button
                  onClick={() => { if (printerId) printOrder.mutate(Number(printerId)) }}
                  disabled={!printerId}
                  style={{
                    height: 36, padding: '0 14px', borderRadius: 8,
                    border: '1px solid #dfe2e6', background: 'white',
                    color: '#2b2f33', fontSize: 13, fontWeight: 600,
                    cursor: printerId ? 'pointer' : 'not-allowed', opacity: printerId ? 1 : 0.5,
                  }}
                >🖨 Εκτύπωση</button>
              </div>
            )}
            <button
              onClick={onOpenFull}
              style={{
                height: 36, padding: '0 14px', borderRadius: 8,
                border: '1px solid #dfe2e6', background: 'white',
                color: '#5a6169', fontSize: 12, fontWeight: 500, cursor: 'pointer',
                marginLeft: printers.length > 0 ? 0 : 'auto',
              }}
            >Πλήρης εικόνα →</button>
          </div>
        )}
      </div>

      {confirmAction && (
        <ConfirmModal
          title={
            confirmAction.type === 'cancelItem' ? 'Ακύρωση αντικειμένου;' :
            confirmAction.type === 'cancelOrder' ? 'Ακύρωση παραγγελίας;' :
            'Κλείσιμο παραγγελίας;'
          }
          message={confirmAction.type === 'cancelOrder' ? 'Η παραγγελία θα ακυρωθεί οριστικά.' : undefined}
          confirmLabel={confirmAction.type === 'closeOrder' ? 'Κλείσιμο' : 'Ακύρωση'}
          confirmClass={confirmAction.type === 'closeOrder' ? 'btn-primary' : 'btn-danger'}
          onConfirm={handleConfirm}
          onCancel={() => setConfirmAction(null)}
        />
      )}
    </div>
  )
}

// ─── KPI Card ─────────────────────────────────────────────────────────────────

function KpiCard({ label, value, sub, accent = '#3758c9', pct }) {
  return (
    <div style={{
      background: 'white',
      border: '1px solid #edeff1',
      borderRadius: 16,
      padding: '20px 22px',
      display: 'flex', flexDirection: 'column', gap: 6,
      boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
      flex: 1,
    }}>
      <div style={{ fontSize: 11, fontWeight: 700, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.7 }}>{label}</div>
      <div style={{ fontSize: 30, fontWeight: 700, color: '#111315', letterSpacing: -0.5, lineHeight: 1.1, fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace" }}>{value}</div>
      {sub && <div style={{ fontSize: 12, color: '#5a6169' }}>{sub}</div>}
      {pct != null && (
        <div style={{ marginTop: 4, height: 6, borderRadius: 3, background: '#edeff1', overflow: 'hidden' }}>
          <div style={{ width: `${Math.min(100, pct)}%`, height: '100%', background: accent, borderRadius: 3, transition: 'width 300ms ease' }} />
        </div>
      )}
    </div>
  )
}

// ─── Mini table chip ──────────────────────────────────────────────────────────

function TableChip({ name, status, amount, onClick }) {
  const c = TABLE_COLORS[status] || TABLE_COLORS.free
  return (
    <button
      onClick={onClick}
      title={amount != null ? fmtEuro(amount) : name}
      style={{
        aspectRatio: '1', minHeight: 52,
        borderRadius: 10,
        background: c.bg,
        border: '1px solid ' + c.border,
        color: c.text,
        display: 'flex', alignItems: 'center', justifyContent: 'center',
        fontSize: 12, fontWeight: 700,
        fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace",
        cursor: onClick ? 'pointer' : 'default',
        transition: 'transform 100ms ease, box-shadow 100ms ease',
      }}
      onMouseEnter={e => { if (onClick) { e.currentTarget.style.transform = 'translateY(-1px)'; e.currentTarget.style.boxShadow = '0 4px 12px rgba(0,0,0,0.08)' } }}
      onMouseLeave={e => { e.currentTarget.style.transform = ''; e.currentTarget.style.boxShadow = '' }}
    >
      {name}
    </button>
  )
}

// ─── Shifts card ──────────────────────────────────────────────────────────────

// ─── End shift confirmation modal ─────────────────────────────────────────────

function EndShiftConfirmModal({ shift, onClose, onConfirm, busy }) {
  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 gap-3">
          <div style={{ width: 40, height: 40, borderRadius: '50%', background: '#fef2f2', display: 'flex', alignItems: 'center', justifyContent: 'center', flexShrink: 0 }}>
            <span style={{ fontSize: 18 }}>⏹</span>
          </div>
          <div>
            <div style={{ fontSize: 16, fontWeight: 700, color: '#111315' }}>Τέλος βάρδιας;</div>
            <div style={{ fontSize: 13, color: '#5a6169', marginTop: 2 }}>{shift.waiter_name}</div>
          </div>
        </div>
        <div style={{ background: '#fafafa', borderRadius: 12, padding: '12px 16px', fontSize: 13, color: '#374151' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
            <span>Έναρξη</span><span style={{ fontWeight: 600 }}>{fmtTime(shift.started_at)}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: 4 }}>
            <span>Διάρκεια</span><span style={{ fontWeight: 600 }}>{fmtDuration(shift.started_at)}</span>
          </div>
          <div style={{ display: 'flex', justifyContent: 'space-between' }}>
            <span>Είσπραξη</span><span style={{ fontWeight: 700, color: '#2f9e5e' }}>{fmtEuro(shift.total_collected)}</span>
          </div>
        </div>
        <p style={{ fontSize: 12, color: '#8a9099' }}>Μετά την επιβεβαίωση θα εμφανιστεί η αναλυτική σύνοψη βάρδιας.</p>
        <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>
  )
}

// ─── Shift summary modal ───────────────────────────────────────────────────────

function ShiftSummaryModal({ shiftId, onConfirm }) {
  const [summary, setSummary] = useState(null)
  const [loading, setLoading] = useState(true)

  useEffect(() => {
    client.get(`/api/shifts/${shiftId}/summary`)
      .then(r => setSummary(r.data))
      .catch(() => setSummary(null))
      .finally(() => setLoading(false))
  }, [shiftId])

  function fmtMins(mins) {
    if (mins == null) return '—'
    const h = Math.floor(mins / 60)
    const m = mins % 60
    return h > 0 ? `${h}ω ${m}λ` : `${m}λ`
  }

  const totalItems = summary?.orders?.reduce((s, o) => s + o.items.reduce((ss, i) => ss + i.quantity, 0), 0) ?? 0

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.55)', zIndex: 9999,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20,
    }}>
      <div style={{
        background: 'white', borderRadius: 20, width: '100%', maxWidth: 560,
        maxHeight: '90vh', display: 'flex', flexDirection: 'column',
        boxShadow: '0 24px 64px rgba(0,0,0,0.25)',
      }}>
        {/* Header */}
        <div style={{ padding: '20px 24px', borderBottom: '1px solid #edeff1', flexShrink: 0 }}>
          <div style={{ fontSize: 18, fontWeight: 700, color: '#111315' }}>Σύνοψη Βάρδιας</div>
          {summary && <div style={{ fontSize: 13, color: '#5a6169', marginTop: 3 }}>{summary.waiter_name}</div>}
        </div>

        {loading && <div style={{ padding: 40, textAlign: 'center', color: '#8a9099' }}>Φόρτωση…</div>}

        {!loading && summary && (
          <div style={{ flex: 1, overflowY: 'auto', padding: '16px 24px' }}>
            {/* KPI row */}
            <div style={{ display: 'grid', gridTemplateColumns: 'repeat(4, 1fr)', gap: 10, marginBottom: 20 }}>
              {[
                { label: 'Έναρξη', value: fmtTime(summary.started_at) },
                { label: 'Ώρες', value: fmtMins(summary.duration_minutes) },
                { label: 'Αρχικά μετρητά', value: summary.starting_cash != null ? fmtEuro(summary.starting_cash) : '—' },
                { label: 'Είσπραξη', value: fmtEuro(summary.total_collected), accent: '#2f9e5e' },
              ].map(k => (
                <div key={k.label} style={{ background: '#f9fafb', borderRadius: 12, padding: '12px 14px' }}>
                  <div style={{ fontSize: 10, fontWeight: 700, color: '#8a9099', textTransform: 'uppercase', letterSpacing: 0.6, marginBottom: 4 }}>{k.label}</div>
                  <div style={{ fontSize: 18, fontWeight: 700, color: k.accent || '#111315', fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace" }}>{k.value}</div>
                </div>
              ))}
            </div>

            {/* Net to deliver */}
            <div style={{ background: '#eff6ff', borderRadius: 12, padding: '12px 16px', marginBottom: 20, display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
              <div>
                <div style={{ fontSize: 12, fontWeight: 600, color: '#3758c9', textTransform: 'uppercase', letterSpacing: 0.5 }}>Σύνολο προς παράδοση</div>
                <div style={{ fontSize: 11, color: '#5a6169', marginTop: 2 }}>Είσπραξη + αρχικά μετρητά</div>
              </div>
              <div style={{ fontSize: 24, fontWeight: 700, color: '#3758c9', fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace" }}>
                {fmtEuro(summary.net_to_deliver)}
              </div>
            </div>

            {/* Orders breakdown */}
            <div style={{ fontSize: 12, fontWeight: 700, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.6, marginBottom: 10 }}>
              Παραγγελίες ({summary.orders.length}) · {totalItems} αντικείμενα
            </div>
            {summary.orders.length === 0 && (
              <p style={{ color: '#b8bdc4', fontSize: 13, textAlign: 'center', padding: '16px 0' }}>Δεν υπάρχουν πληρωμές σε αυτή τη βάρδια</p>
            )}
            {summary.orders.map(o => (
              <div key={o.order_id} style={{ borderRadius: 10, border: '1px solid #edeff1', marginBottom: 8, overflow: 'hidden' }}>
                <div style={{ padding: '8px 14px', background: '#f9fafb', display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
                  <span style={{ fontSize: 12, fontWeight: 600, color: '#374151' }}>
                    Παραγγελία #{o.order_id}
                    {o.table_id && <span style={{ color: '#8a9099', fontWeight: 400, marginLeft: 6 }}>· Τραπέζι {o.table_id}</span>}
                  </span>
                  <span style={{ fontSize: 12, fontWeight: 700, color: '#2f9e5e' }}>
                    {fmtEuro(o.items.reduce((s, i) => s + i.subtotal, 0))}
                  </span>
                </div>
                {o.items.map(item => (
                  <div key={item.id} style={{ display: 'flex', justifyContent: 'space-between', padding: '6px 14px', fontSize: 13, borderTop: '1px solid #f4f4f2' }}>
                    <span style={{ color: '#374151' }}>{item.product_name} <span style={{ color: '#8a9099' }}>×{item.quantity}</span></span>
                    <span style={{ color: '#111315', fontWeight: 500 }}>{fmtEuro(item.subtotal)}</span>
                  </div>
                ))}
              </div>
            ))}
          </div>
        )}

        {!loading && !summary && (
          <div style={{ padding: 40, textAlign: 'center', color: '#8a9099' }}>Σφάλμα φόρτωσης</div>
        )}

        {/* Footer — no close on outside click, must confirm */}
        <div style={{ padding: '16px 24px', borderTop: '1px solid #edeff1', flexShrink: 0 }}>
          <button
            onClick={onConfirm}
            style={{
              width: '100%', height: 44, borderRadius: 12,
              background: '#3758c9', color: 'white', border: 'none',
              fontSize: 15, fontWeight: 700, cursor: 'pointer',
            }}
          >✓ Επιβεβαίωση και Κλείσιμο</button>
        </div>
      </div>
    </div>
  )
}

// ─── Compose for single waiter (quick message from shift row) ─────────────────

function QuickMessageModal({ waiter, tables, templates, onClose, onSent }) {
  const [body, setBody] = useState('')
  const sendMut = useMutation({
    mutationFn: (payload) => client.post('/api/messages/send', payload),
    onSuccess: () => { toast.success('Εστάλη!'); onSent(); onClose() },
    onError: () => toast.error('Σφάλμα αποστολής'),
  })
  function send() {
    if (!body.trim()) return
    sendMut.mutate({ body: body.trim(), target_waiter_ids: [waiter.id], table_ids: [] })
  }
  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-5 space-y-4">
        <div className="flex items-center justify-between">
          <div style={{ fontSize: 15, fontWeight: 700, color: '#111315' }}>💬 Μήνυμα σε {waiter.name}</div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', fontSize: 18, cursor: 'pointer', color: '#8a9099' }}>✕</button>
        </div>
        {templates.length > 0 && (
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {templates.map(t => (
              <button key={t.id} onClick={() => setBody(t.body)} style={{
                height: 26, padding: '0 10px', borderRadius: 6,
                border: `1px solid ${body === t.body ? '#3758c9' : '#dfe2e6'}`,
                background: body === t.body ? '#eff3ff' : '#f9fafb',
                color: body === t.body ? '#3758c9' : '#374151',
                fontSize: 11, cursor: 'pointer', fontFamily: 'inherit',
              }}>{t.body}</button>
            ))}
          </div>
        )}
        <textarea
          placeholder="Μήνυμα…"
          value={body}
          onChange={e => setBody(e.target.value)}
          rows={3}
          style={{ width: '100%', borderRadius: 10, border: '1.5px solid #dfe2e6', padding: '10px 14px', fontSize: 14, fontFamily: 'inherit', resize: 'vertical', outline: 'none', boxSizing: 'border-box', color: '#111315' }}
        />
        <div style={{ display: 'flex', gap: 8, justifyContent: 'flex-end' }}>
          <button onClick={onClose} style={{ height: 36, padding: '0 16px', borderRadius: 8, border: '1px solid #dfe2e6', background: 'white', fontSize: 13, cursor: 'pointer' }}>Άκυρο</button>
          <button onClick={send} disabled={!body.trim() || sendMut.isPending}
            style={{ height: 36, padding: '0 16px', borderRadius: 8, background: '#3758c9', color: 'white', border: 'none', fontSize: 13, fontWeight: 600, cursor: 'pointer', opacity: !body.trim() ? 0.5 : 1 }}>
            {sendMut.isPending ? 'Αποστολή…' : '📤 Αποστολή'}
          </button>
        </div>
      </div>
    </div>
  )
}

function ShiftsCard({ activeShifts, waitersWithoutShift, isOpen, onStartShift, onEndShift, onMessageWaiter }) {
  return (
    <div style={{
      background: 'white', border: '1px solid #edeff1',
      borderRadius: 16, overflow: 'hidden',
      boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '16px 20px', borderBottom: '1px solid #edeff1',
      }}>
        <div style={{ fontSize: 14, fontWeight: 700, color: '#111315' }}>Βάρδιες σε εξέλιξη</div>
        {isOpen && waitersWithoutShift.length > 0 && (
          <button
            onClick={onStartShift}
            style={{
              height: 30, padding: '0 12px', borderRadius: 8,
              border: '1px solid #dfe2e6', background: 'white',
              color: '#2b2f33', fontSize: 12, fontWeight: 600, cursor: 'pointer',
            }}
          >+ Έναρξη</button>
        )}
      </div>
      <div style={{ padding: '12px 20px', display: 'flex', flexDirection: 'column', gap: 8 }}>
        {activeShifts.length === 0 ? (
          <p style={{ fontSize: 13, color: '#8a9099', padding: '8px 0' }}>Κανένας σερβιτόρος σε βάρδια</p>
        ) : (
          activeShifts.map(s => {
            const activeBreak = Array.isArray(s.breaks) ? s.breaks.find(b => !b.ended_at) : null
            return (
              <div key={s.id} style={{
                display: 'flex', alignItems: 'center', gap: 12,
                padding: '10px 12px', borderRadius: 12,
                border: activeBreak ? '1px solid #fed7aa' : '1px solid #edeff1',
                background: activeBreak ? '#fff7ed' : '#fafafa',
                transition: 'background 200ms, border-color 200ms',
              }}>
                <Avatar name={s.waiter_name} avatarUrl={s.avatar_url ? API_URL + s.avatar_url : null} size={36} />
                <div style={{ flex: 1, minWidth: 0 }}>
                  <div style={{ display: 'flex', alignItems: 'center', gap: 8, flexWrap: 'wrap' }}>
                    <span style={{ fontSize: 14, fontWeight: 600, color: '#111315' }}>{s.waiter_name}</span>
                    {activeBreak && (
                      <span style={{
                        display: 'inline-flex', alignItems: 'center', gap: 4,
                        padding: '2px 8px', borderRadius: 999,
                        background: '#fed7aa', color: '#9a3412',
                        fontSize: 11, fontWeight: 700,
                      }}>
                        ☕ Διάλειμμα · {fmtDuration(activeBreak.started_at)}
                      </span>
                    )}
                  </div>
                  <div style={{ fontSize: 11, color: '#5a6169', marginTop: 1 }}>
                    από {fmtTime(s.started_at)} · {fmtDuration(s.started_at)}
                    {s.total_collected > 0 && (
                      <span style={{ color: '#2f9e5e', fontWeight: 600, marginLeft: 6 }}>{fmtEuro(s.total_collected)}</span>
                    )}
                  </div>
                </div>
                <button
                  onClick={() => onMessageWaiter(s)}
                  title="Αποστολή μηνύματος"
                  style={{
                    height: 28, width: 28, borderRadius: 8, flexShrink: 0,
                    border: '1px solid #dfe2e6', background: 'white',
                    display: 'flex', alignItems: 'center', justifyContent: 'center',
                    fontSize: 14, cursor: 'pointer',
                  }}
                >💬</button>
                <button
                  onClick={() => onEndShift(s)}
                  style={{
                    height: 28, padding: '0 10px', borderRadius: 8,
                    border: '1px solid #fecaca', background: '#fef2f2',
                    color: '#dc2626', fontSize: 11, fontWeight: 600, cursor: 'pointer', flexShrink: 0,
                  }}
                >Τέλος</button>
              </div>
            )
          })
        )}
      </div>
    </div>
  )
}

// ─── Revenue bar chart ─────────────────────────────────────────────────────────

function RevenueChart({ orders }) {
  const now = new Date()
  const currentHour = now.getHours()
  const buckets = {}
  for (let h = 10; h <= 23; h++) buckets[h] = 0
  orders.forEach(o => {
    const h = new Date(o.opened_at).getHours()
    if (h >= 10 && h <= 23) buckets[h] = (buckets[h] || 0) + orderTotal(o.items)
  })
  const hours = Object.keys(buckets).map(Number)
  const max = Math.max(...Object.values(buckets), 1)

  return (
    <div style={{
      background: 'white', border: '1px solid #edeff1',
      borderRadius: 16, padding: '16px 20px',
      boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
    }}>
      <div style={{ fontSize: 14, fontWeight: 700, color: '#111315', marginBottom: 16 }}>Έσοδα ανά ώρα</div>
      <div style={{ display: 'flex', alignItems: 'flex-end', gap: 3, height: 90 }}>
        {hours.map(h => {
          const val = buckets[h]
          const heightPct = (val / max) * 100
          const isCurrent = h === currentHour
          const isFuture = h > currentHour
          return (
            <div key={h} style={{ flex: 1, display: 'flex', flexDirection: 'column', alignItems: 'center', gap: 4, height: '100%' }}>
              <div style={{ flex: 1, width: '100%', display: 'flex', alignItems: 'flex-end' }}>
                <div title={fmtEuro(val)} style={{
                  width: '100%', height: val > 0 ? `${heightPct}%` : '3px',
                  minHeight: val > 0 ? 4 : 3, borderRadius: 4,
                  background: isCurrent ? '#3758c9' : isFuture ? '#edeff1' : '#c2cff0',
                  transition: 'height 300ms ease',
                }} />
              </div>
              <div style={{
                fontSize: 9, fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace",
                color: isCurrent ? '#3758c9' : '#8a9099', fontWeight: isCurrent ? 700 : 500,
              }}>{h}</div>
            </div>
          )
        })}
      </div>
    </div>
  )
}

// ─── Reservations stub ────────────────────────────────────────────────────────

function ReservationsCard() {
  return (
    <div style={{
      background: 'white', border: '1px solid #edeff1',
      borderRadius: 16, overflow: 'hidden',
      boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '16px 20px', borderBottom: '1px solid #edeff1',
      }}>
        <div style={{ fontSize: 14, fontWeight: 700, color: '#111315' }}>Κρατήσεις σήμερα</div>
        <button style={{
          height: 28, padding: '0 12px', borderRadius: 8,
          border: '1px solid #dfe2e6', background: 'white',
          color: '#5a6169', fontSize: 12, fontWeight: 600, cursor: 'pointer',
        }}>+ Νέα</button>
      </div>
      <div style={{
        padding: '32px 20px', textAlign: 'center',
        color: '#b8bdc4', fontSize: 13,
      }}>
        <div style={{ fontSize: 28, marginBottom: 8 }}>📅</div>
        Σύντομα — σύστημα κρατήσεων υπό ανάπτυξη
      </div>
    </div>
  )
}

// ─── Messages card ────────────────────────────────────────────────────────────

function ComposeModal({ waiters, tables, templates, onClose, onSent }) {
  const [selectedWaiters, setSelectedWaiters] = useState([])   // [] = all
  const [selectedTables, setSelectedTables] = useState([])
  const [body, setBody] = useState('')

  const sendMut = useMutation({
    mutationFn: (payload) => client.post('/api/messages/send', payload),
    onSuccess: () => { toast.success('Εστάλη!'); onSent(); onClose() },
    onError: () => toast.error('Σφάλμα αποστολής'),
  })

  function toggleWaiter(id) {
    setSelectedWaiters(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id])
  }
  function toggleTable(id) {
    setSelectedTables(prev => prev.includes(id) ? prev.filter(x => x !== id) : [...prev, id])
  }

  function send() {
    if (!body.trim()) return
    sendMut.mutate({
      body: body.trim(),
      target_waiter_ids: selectedWaiters,  // [] = broadcast all
      table_ids: selectedTables,
    })
  }

  return (
    <div style={{
      position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.5)', zIndex: 9999,
      display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20,
    }} onClick={onClose}>
      <div style={{
        background: 'white', borderRadius: 20, width: '100%', maxWidth: 520,
        padding: 24, boxShadow: '0 24px 64px rgba(0,0,0,0.22)',
      }} onClick={e => e.stopPropagation()}>
        <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 20 }}>
          <div style={{ fontSize: 16, fontWeight: 700, color: '#111315' }}>Νέο Μήνυμα</div>
          <button onClick={onClose} style={{ background: 'none', border: 'none', fontSize: 20, cursor: 'pointer', color: '#8a9099' }}>✕</button>
        </div>

        {/* Recipients */}
        <div style={{ marginBottom: 16 }}>
          <div style={{ fontSize: 12, fontWeight: 600, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>
            Παραλήπτες {selectedWaiters.length === 0 && <span style={{ color: '#3758c9', fontWeight: 700 }}>(Όλοι)</span>}
          </div>
          <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
            {waiters.map(w => {
              const name = w.nickname || w.full_name || w.username
              const sel = selectedWaiters.includes(w.id)
              return (
                <button key={w.id} onClick={() => toggleWaiter(w.id)} style={{
                  height: 30, padding: '0 12px', borderRadius: 999,
                  border: '1.5px solid ' + (sel ? '#3758c9' : '#dfe2e6'),
                  background: sel ? '#eff3ff' : 'white',
                  color: sel ? '#3758c9' : '#374151',
                  fontSize: 12, fontWeight: sel ? 700 : 500, cursor: 'pointer',
                }}>{name}</button>
              )
            })}
          </div>
        </div>

        {/* Tables (optional) */}
        {tables.length > 0 && (
          <div style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>
              Σχετικά Τραπέζια (προαιρετικό)
            </div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6, maxHeight: 80, overflowY: 'auto' }}>
              {tables.map(t => {
                const name = t.label || `T${t.number}`
                const sel = selectedTables.includes(t.id)
                return (
                  <button key={t.id} onClick={() => toggleTable(t.id)} style={{
                    height: 28, padding: '0 10px', borderRadius: 6,
                    border: '1.5px solid ' + (sel ? '#7a44c9' : '#dfe2e6'),
                    background: sel ? '#f5eeff' : 'white',
                    color: sel ? '#7a44c9' : '#374151',
                    fontSize: 12, fontWeight: sel ? 700 : 500, cursor: 'pointer',
                  }}>{name}</button>
                )
              })}
            </div>
          </div>
        )}

        {/* Quick templates */}
        {templates.length > 0 && (
          <div style={{ marginBottom: 16 }}>
            <div style={{ fontSize: 12, fontWeight: 600, color: '#5a6169', textTransform: 'uppercase', letterSpacing: 0.5, marginBottom: 8 }}>Γρήγορα Μηνύματα</div>
            <div style={{ display: 'flex', flexWrap: 'wrap', gap: 6 }}>
              {templates.map(t => (
                <button key={t.id} onClick={() => setBody(t.body)} style={{
                  height: 28, padding: '0 12px', borderRadius: 6,
                  border: '1px solid ' + (body === t.body ? '#3758c9' : '#dfe2e6'),
                  background: body === t.body ? '#eff3ff' : '#f9fafb',
                  color: body === t.body ? '#3758c9' : '#374151',
                  fontSize: 12, cursor: 'pointer', fontFamily: 'inherit',
                }}>{t.body}</button>
              ))}
            </div>
          </div>
        )}

        {/* Custom body */}
        <textarea
          placeholder="Ή γράψτε το δικό σας μήνυμα…"
          value={body}
          onChange={e => setBody(e.target.value)}
          rows={3}
          style={{
            width: '100%', borderRadius: 10, border: '1.5px solid #dfe2e6',
            padding: '10px 14px', fontSize: 14, fontFamily: 'inherit',
            resize: 'vertical', outline: 'none', boxSizing: 'border-box',
            color: '#111315',
          }}
        />

        <div style={{ display: 'flex', gap: 10, marginTop: 16, justifyContent: 'flex-end' }}>
          <button onClick={onClose} style={{ height: 38, padding: '0 18px', borderRadius: 8, border: '1px solid #dfe2e6', background: 'white', fontSize: 13, cursor: 'pointer' }}>Άκυρο</button>
          <button
            onClick={send}
            disabled={!body.trim() || sendMut.isPending}
            style={{ height: 38, padding: '0 20px', borderRadius: 8, background: '#3758c9', color: 'white', border: 'none', fontSize: 13, fontWeight: 600, cursor: 'pointer', opacity: !body.trim() ? 0.5 : 1 }}
          >{sendMut.isPending ? 'Αποστολή…' : '📤 Αποστολή'}</button>
        </div>
      </div>
    </div>
  )
}

function MessagesCard({ waiters, tables }) {
  const qc = useQueryClient()
  const [composing, setComposing] = useState(false)

  const { data: messages = [] } = useQuery({
    queryKey: ['messages-all'],
    queryFn: () => client.get('/api/messages/all?limit=20').then(r => r.data),
    refetchInterval: 10_000,
  })

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

  function parseJsonField(val) {
    if (Array.isArray(val)) return val
    try { return JSON.parse(val || '[]') } catch { return [] }
  }

  function fmtTargets(msg) {
    const ids = parseJsonField(msg.target_waiter_ids)
    if (ids.length === 0) return 'Όλοι'
    return ids.map(id => {
      const w = waiters.find(w => w.id === id)
      return w ? (w.nickname || w.full_name || w.username) : `#${id}`
    }).join(', ')
  }

  return (
    <>
      {composing && (
        <ComposeModal
          waiters={waiters}
          tables={tables}
          templates={templates}
          onClose={() => setComposing(false)}
          onSent={() => qc.invalidateQueries({ queryKey: ['messages-all'] })}
        />
      )}
      <div style={{
        background: 'white', border: '1px solid #edeff1',
        borderRadius: 16, overflow: 'hidden',
        boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
      }}>
        <div style={{
          display: 'flex', alignItems: 'center', justifyContent: 'space-between',
          padding: '16px 20px', borderBottom: '1px solid #edeff1',
        }}>
          <div style={{ fontSize: 14, fontWeight: 700, color: '#111315' }}>Μηνύματα</div>
          <button
            onClick={() => setComposing(true)}
            style={{
              height: 28, padding: '0 12px', borderRadius: 8,
              border: '1px solid #dfe2e6', background: 'white',
              color: '#5a6169', fontSize: 12, fontWeight: 600, cursor: 'pointer',
            }}
          >+ Νέο</button>
        </div>

        {messages.length === 0 ? (
          <div style={{ padding: '32px 20px', textAlign: 'center', color: '#b8bdc4', fontSize: 13 }}>
            <div style={{ fontSize: 28, marginBottom: 8 }}>💬</div>
            Δεν υπάρχουν μηνύματα ακόμα
          </div>
        ) : (
          <div style={{ maxHeight: 300, overflowY: 'auto' }}>
            {messages.map(msg => {
              const ackedIds = parseJsonField(msg.acked_by).length
              const totalTargets = parseJsonField(msg.target_waiter_ids).length || waiters.length
              return (
                <div key={msg.id} style={{
                  padding: '10px 20px', borderBottom: '1px solid #f4f4f2',
                  display: 'flex', gap: 12, alignItems: 'flex-start',
                }}>
                  <div style={{ flex: 1, minWidth: 0 }}>
                    <div style={{ fontSize: 13, fontWeight: 600, color: '#111315', marginBottom: 2 }}>{msg.body}</div>
                    <div style={{ fontSize: 11, color: '#8a9099' }}>
                      Προς: {fmtTargets(msg)} · {new Date(msg.created_at).toLocaleTimeString('el-GR', { hour: '2-digit', minute: '2-digit' })}
                    </div>
                  </div>
                  <div style={{
                    fontSize: 11, fontWeight: 700,
                    color: ackedIds >= totalTargets ? '#16a34a' : '#f59e0b',
                    background: ackedIds >= totalTargets ? '#f0fdf4' : '#fffbeb',
                    border: `1px solid ${ackedIds >= totalTargets ? '#bbf7d0' : '#fde68a'}`,
                    borderRadius: 999, padding: '2px 8px', whiteSpace: 'nowrap', flexShrink: 0,
                  }}>
                    {ackedIds}/{totalTargets} ✓
                  </div>
                </div>
              )
            })}
          </div>
        )}
      </div>
    </>
  )
}

// ─── Pending prints panel ──────────────────────────────────────────────────────

function PendingPrintsPanel({ pendingPrintOrders, onRetryAll, onRetrySingle, onViewOrder, retryingId }) {
  if (pendingPrintOrders.length === 0) return null
  return (
    <div style={{
      background: 'white', borderRadius: 16, overflow: 'hidden',
      border: '1px solid #fed7aa', boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
    }}>
      <div style={{
        display: 'flex', alignItems: 'center', justifyContent: 'space-between',
        padding: '14px 20px', background: '#fff7ed', borderBottom: '1px solid #fed7aa',
      }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
          <span style={{ fontSize: 18 }}>⏳</span>
          <div>
            <div style={{ fontSize: 14, fontWeight: 700, color: '#9a3412' }}>Εκκρεμείς Εκτυπώσεις</div>
            <div style={{ fontSize: 12, color: '#c2410c', marginTop: 1 }}>
              {pendingPrintOrders.length} παραγγελί{pendingPrintOrders.length !== 1 ? 'ες' : 'α'} δεν έχ{pendingPrintOrders.length !== 1 ? 'ουν' : 'ει'} σταλεί
            </div>
          </div>
        </div>
        <button
          onClick={onRetryAll} disabled={retryingId !== null}
          style={{
            height: 32, padding: '0 14px', borderRadius: 8,
            background: '#c2410c', border: 'none', color: 'white',
            fontSize: 12, fontWeight: 600, cursor: 'pointer',
          }}
        >{retryingId !== null ? 'Αποστολή…' : 'Αποστολή Όλων'}</button>
      </div>
      {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} style={{
            display: 'flex', alignItems: 'center', gap: 14,
            padding: '10px 20px', borderBottom: '1px solid #fff7ed',
          }}>
            <div style={{
              width: 36, height: 36, borderRadius: 8, flexShrink: 0,
              display: 'flex', alignItems: 'center', justifyContent: 'center',
              fontWeight: 700, fontSize: 12, background: '#fff7ed', color: '#c2410c',
              border: '1px solid #fed7aa', fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace",
            }}>{tableName}</div>
            <div style={{ flex: 1, minWidth: 0 }}>
              <div style={{ fontSize: 13, fontWeight: 600, color: '#111315' }}>
                {unprinted.length} αντικείμενο{unprinted.length !== 1 ? 'α' : ''} εκκρεμούν
              </div>
              <div style={{ fontSize: 11, color: '#5a6169', marginTop: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
                {unprinted.map(i => i.product?.name || `#${i.product_id}`).join(', ')}
              </div>
            </div>
            <div style={{ display: 'flex', gap: 6, flexShrink: 0 }}>
              <button onClick={() => onViewOrder(order.id)} className="btn btn-secondary text-xs">Λεπτομέρειες</button>
              <button
                onClick={() => onRetrySingle(order.id)} disabled={retryingId === order.id}
                style={{
                  height: 28, padding: '0 10px', borderRadius: 6,
                  background: '#c2410c', border: 'none', color: 'white',
                  fontSize: 11, fontWeight: 600, cursor: 'pointer',
                }}
              >{retryingId === order.id ? '…' : 'Εκτύπωση'}</button>
            </div>
          </div>
        )
      })}
    </div>
  )
}

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

export default function OperationsPage() {
  const [showStartShift, setShowStartShift] = useState(false)
  const [closeDetails, setCloseDetails] = useState(null)
  const [forceClosing, setForceClosing] = useState(false)
  const [retryingId, setRetryingId] = useState(null)
  const [quickView, setQuickView] = useState(null)
  // End shift flow: confirm modal → summary modal
  const [endShiftTarget, setEndShiftTarget] = useState(null)   // shift object to confirm
  const [endShiftBusy, setEndShiftBusy] = useState(false)
  const [shiftSummaryId, setShiftSummaryId] = useState(null)   // show summary for this shift id
  // Quick message to single waiter
  const [messageWaiter, setMessageWaiter] = useState(null)     // { id, name }
  const navigate = useNavigate()
  const qc = useQueryClient()

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

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

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

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

  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 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'] })
      qc.invalidateQueries({ queryKey: ['tables'] })
      qc.invalidateQueries({ queryKey: ['messages-all'] })
    } 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 handleEndShiftConfirm() {
    if (!endShiftTarget) return
    setEndShiftBusy(true)
    try {
      await client.post(`/api/shifts/manager/end/${endShiftTarget.id}`, {})
      qc.invalidateQueries({ queryKey: ['active-shifts'] })
      const summaryId = endShiftTarget.id
      setEndShiftTarget(null)
      setShiftSummaryId(summaryId)
    } catch (e) {
      toast.error(e.response?.data?.detail || 'Σφάλμα')
    } finally {
      setEndShiftBusy(false)
    }
  }

  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'] })
  }

  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}`)
      }
      qc.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 isOpen = !!businessDay

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

  // Build table cards
  const tableCards = tables.map(table => {
    const order = orders.find(o =>
      o.table_id === table.id && ['open', 'partially_paid', '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)

  // KPIs — revenue scoped to orders that opened after business day start
  const businessDayStart = businessDay?.opened_at ? new Date(businessDay.opened_at) : null
  const dayOrders = businessDayStart
    ? orders.filter(o => new Date(o.opened_at) >= businessDayStart)
    : orders

  const totalRevenue = dayOrders.reduce((s, o) => s + orderTotal(o.items), 0)
  const openCount = tableCards.filter(c => c.tableStatus === 'open').length
  const partialCount = tableCards.filter(c => c.tableStatus === 'partially_paid').length
  const occupiedCount = openCount + partialCount
  const freeCount = tableCards.filter(c => c.tableStatus === 'free').length

  // Avg ticket: revenue divided by number of orders with at least one paid item
  const paidOrders = dayOrders.filter(o => o.items.some(i => i.paid_by))
  const avgTicket = paidOrders.length > 0 ? totalRevenue / paidOrders.length : 0

  // Total collected by all active shifts
  const totalCollected = activeShifts.reduce((s, sh) => s + (sh.total_collected || 0), 0)

  const todayStr = new Date().toLocaleDateString('el-GR', { weekday: 'long', day: 'numeric', month: 'long' })

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

  return (
    <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>

      {/* ── Header bar ─────────────────────────────────────────────────────── */}
      <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', flexWrap: 'wrap', gap: 12 }}>
        <div>
          <div style={{ display: 'flex', alignItems: 'center', gap: 10 }}>
            <h1 style={{ fontSize: 22, fontWeight: 700, color: '#111315', margin: 0 }}>Διοίκηση</h1>
            <span style={{
              display: 'inline-flex', alignItems: 'center', gap: 6,
              padding: '4px 10px', borderRadius: 999,
              background: isOpen ? '#eef7f0' : '#f4f4f2',
              color: isOpen ? '#1f7042' : '#5a6169',
              fontSize: 11, fontWeight: 700, textTransform: 'uppercase', letterSpacing: 0.5,
            }}>
              <span style={{
                width: 6, height: 6, borderRadius: 3,
                background: isOpen ? '#2f9e5e' : '#8a9099',
                boxShadow: isOpen ? '0 0 0 2px #bbf7d0' : 'none',
              }} />
              {isOpen ? 'Ημέρα Ανοιχτή' : 'Ημέρα Κλειστή'}
            </span>
          </div>
          <div style={{ fontSize: 13, color: '#5a6169', marginTop: 3 }}>
            {todayStr}
            {isOpen && businessDay?.opened_at && ` · από ${fmtTime(businessDay.opened_at)} · ${fmtDuration(businessDay.opened_at)}`}
          </div>
        </div>
        <div style={{ display: 'flex', gap: 8 }}>
          {isOpen ? (
            <button onClick={() => handleCloseDay(false)} style={{
              height: 38, padding: '0 18px', borderRadius: 10,
              background: '#dc2626', border: 'none', color: 'white',
              fontSize: 13, fontWeight: 700, cursor: 'pointer',
            }}>Κλείσιμο Ημέρας</button>
          ) : (
            <button onClick={() => openDayMut.mutate()} disabled={openDayMut.isPending} style={{
              height: 38, padding: '0 18px', borderRadius: 10,
              background: '#16a34a', border: 'none', color: 'white',
              fontSize: 13, fontWeight: 700, cursor: 'pointer',
            }}>{openDayMut.isPending ? 'Άνοιγμα…' : '▶ Άνοιγμα Ημέρας'}</button>
          )}
        </div>
      </div>

      {/* ── KPI strip — full-width flex row ────────────────────────────────── */}
      <div style={{ display: 'flex', gap: 14, flexWrap: 'wrap' }}>
        <KpiCard
          label="Έσοδα ημέρας"
          value={fmtEuro(totalRevenue)}
          sub={`${dayOrders.length} παραγγελί${dayOrders.length !== 1 ? 'ες' : 'α'} · μ.ο. ${fmtEuro(avgTicket)}`}
          accent="#3758c9"
        />
        <KpiCard
          label="Τραπέζια σε χρήση"
          value={`${occupiedCount} / ${tables.length}`}
          sub={`${freeCount} ελεύθερα · ${partialCount} μερική πληρ.`}
          accent="#7a44c9"
          pct={tables.length > 0 ? (occupiedCount / tables.length) * 100 : 0}
        />
        <KpiCard
          label="Βάρδιες ενεργές"
          value={String(activeShifts.length)}
          sub={activeShifts.length > 0 ? activeShifts.map(s => s.waiter_name.split(' ')[0]).join(', ') : 'Κανένας σε βάρδια'}
          accent="#2f9e5e"
        />
        <KpiCard
          label="Είσπραξη βαρδιών"
          value={fmtEuro(totalCollected)}
          sub={`Σύνολο από ${activeShifts.length} βάρδι${activeShifts.length === 1 ? 'α' : 'ες'}`}
          accent="#0d7a8a"
        />
        {pendingPrintOrders.length > 0 && (
          <KpiCard
            label="Εκκρεμείς εκτυπώσεις"
            value={String(pendingPrintOrders.length)}
            sub="Απαιτείται προσοχή"
            accent="#d94b26"
          />
        )}
      </div>

      {/* ── Main 2-column layout: 65 / 35 ──────────────────────────────────── */}
      <div style={{ display: 'grid', gridTemplateColumns: '65fr 35fr', gap: 20, alignItems: 'start' }}>

        {/* ── Left column — Shifts + Tables + Revenue + Pending prints ───────── */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>

          {/* Shifts card — FIRST */}
          <ShiftsCard
            activeShifts={activeShifts}
            waitersWithoutShift={waitersWithoutShift}
            isOpen={isOpen}
            onStartShift={() => setShowStartShift(true)}
            onEndShift={(shift) => setEndShiftTarget(shift)}
            onMessageWaiter={(s) => setMessageWaiter({ id: s.waiter_id, name: s.waiter_name })}
          />

          {/* Tables overview — SECOND */}
          <div style={{
            background: 'white', border: '1px solid #edeff1',
            borderRadius: 16, overflow: 'hidden',
            boxShadow: '0 1px 2px rgba(16,20,24,0.04)',
          }}>
            <div style={{
              display: 'flex', alignItems: 'center', justifyContent: 'space-between',
              padding: '16px 20px', borderBottom: '1px solid #edeff1',
            }}>
              <div style={{ fontSize: 14, fontWeight: 700, color: '#111315' }}>Τραπέζια τώρα</div>
              <button
                onClick={() => navigate('/tables')}
                style={{
                  height: 28, padding: '0 12px', borderRadius: 8,
                  border: '1px solid #dfe2e6', background: 'white',
                  color: '#2b2f33', fontSize: 12, fontWeight: 600, cursor: 'pointer',
                }}
              >Πλήρης εικόνα →</button>
            </div>
            <div style={{ padding: '16px 20px' }}>
              <div style={{
                display: 'grid',
                gridTemplateColumns: 'repeat(auto-fill, minmax(56px, 1fr))',
                gap: 8, marginBottom: 14,
              }}>
                {tableCards.map(({ table, tableStatus, order }) => (
                  <TableChip
                    key={table.id}
                    name={table.label || `T${table.number}`}
                    status={tableStatus}
                    amount={order ? orderTotal(order.items) : null}
                    onClick={order ? () => setQuickView({ orderId: order.id, tableName: table.label || `T${table.number}` }) : undefined}
                  />
                ))}
              </div>
              <div style={{ display: 'flex', flexWrap: 'wrap', gap: 8 }}>
                {Object.entries(TABLE_COLORS).map(([key, c]) => (
                  <div key={key} style={{
                    display: 'inline-flex', alignItems: 'center', gap: 6,
                    padding: '4px 10px', borderRadius: 999, background: '#edeff1',
                    fontSize: 12, fontWeight: 600, color: '#2b2f33',
                  }}>
                    <span style={{ width: 8, height: 8, borderRadius: 4, background: c.dot }} />
                    {c.label}
                    <span style={{ fontFamily: "'ui-monospace','SFMono-Regular','Menlo',monospace", color: '#111315' }}>
                      {tableCards.filter(tc => tc.tableStatus === key).length}
                    </span>
                  </div>
                ))}
              </div>
            </div>
          </div>

          {/* Revenue chart */}
          <RevenueChart orders={dayOrders} />

          {/* Pending prints */}
          <PendingPrintsPanel
            pendingPrintOrders={pendingPrintOrders}
            onRetryAll={retryAllOrders}
            onRetrySingle={retrySingleOrder}
            onViewOrder={id => setQuickView({ orderId: id, tableName: tables.find(t => tableCards.find(tc => tc.order?.id === id)?.table.id === t.id)?.label || '—' })}
            retryingId={retryingId}
          />
        </div>

        {/* ── Right column — Reservations + Messages ───────────────────────── */}
        <div style={{ display: 'flex', flexDirection: 'column', gap: 20 }}>
          <ReservationsCard />
          <MessagesCard waiters={allWaiters} tables={tables} />
        </div>
      </div>

      {/* ── Modals ─────────────────────────────────────────────────────────── */}
      {showStartShift && (
        <StartShiftModal
          waiters={waitersWithoutShift}
          onClose={() => setShowStartShift(false)}
          onStart={handleStartShift}
        />
      )}

      {endShiftTarget && (
        <EndShiftConfirmModal
          shift={endShiftTarget}
          onClose={() => setEndShiftTarget(null)}
          onConfirm={handleEndShiftConfirm}
          busy={endShiftBusy}
        />
      )}

      {shiftSummaryId && (
        <ShiftSummaryModal
          shiftId={shiftSummaryId}
          onConfirm={() => setShiftSummaryId(null)}
        />
      )}

      {messageWaiter && (
        <QuickMessageModal
          waiter={messageWaiter}
          tables={tables}
          templates={quickTemplates}
          onClose={() => setMessageWaiter(null)}
          onSent={() => qc.invalidateQueries({ queryKey: ['messages-all'] })}
        />
      )}
      {closeDetails && (
        <CloseConfirmModal
          details={closeDetails}
          onClose={() => setCloseDetails(null)}
          onConfirm={() => handleCloseDay(true)}
          busy={forceClosing}
        />
      )}
      {quickView && (
        <OrderQuickModal
          orderId={quickView.orderId}
          tableName={quickView.tableName}
          onClose={() => setQuickView(null)}
          onOpenFull={() => { navigate(`/orders/${quickView.orderId}`); setQuickView(null) }}
        />
      )}
    </div>
  )
}
