(() => {
  'use strict';

  const config = window.foodordLiveOrdersAdmin;
  const root = document.querySelector('[data-foodord-live-orders]');

  if (!config || !root) {
    return;
  }

  const strings = config.strings || {};
  const receiptPrinter = window.FoodordLiveOrdersReceipt;
  const stageOrder = ['new', 'kitchen', 'ontheway'];
  const preparationTimeValues = [15, 20, 30, 45, 60, 70, 90];
  const alertAudio = config.soundUrl ? new window.Audio(config.soundUrl) : null;
  const state = {
    orders: new Map(),
    knownOrderIds: new Set(),
    pendingAlertOrderIds: new Set(),
    queuedModalOrderIds: new Set(),
    newOrderModalQueue: [],
    initialized: false,
    loading: false,
    audioUnlocked: false,
    activeColumn: 'new',
    activeOrderId: '',
    activeOrderDetails: null,
    modalRequestRevision: 0,
    modalTrigger: null,
    preparationMode: 'duration',
    preparationValues: preparationTimeValues.slice(),
    preparationIndex: preparationTimeValues.indexOf(30),
    refreshTimer: null,
    alertTimer: null,
    countdownTimer: null,
    countdowns: new Map(),
    requestController: null,
    stageUpdates: new Map(),
    refreshRevision: 0,
  };

  const board = root.querySelector('[data-live-board]');
  const notice = root.querySelector('[data-live-notice]');
  const quotaHeader = root.querySelector('[data-live-quota-header]');
  const quotaRemaining = quotaHeader?.querySelector(
    '[data-live-quota-remaining]'
  );
  const modal = document.querySelector('[data-live-modal]');
  const modalTitle = modal?.querySelector('[data-live-modal-title]');
  const modalStatus = modal?.querySelector('[data-live-modal-status]');
  const modalFulfillment = modal?.querySelector(
    '[data-live-modal-fulfillment]'
  );
  const modalPayment = modal?.querySelector('[data-live-modal-payment]');
  const modalStageControls = modal?.querySelector(
    '[data-live-modal-stage-controls]'
  );
  const modalBody = modal?.querySelector('[data-live-modal-body]');
  const modalFooter = modal?.querySelector('[data-live-modal-footer]');
  const modalPrintButton = modal?.querySelector('[data-live-modal-print]');

  if (alertAudio) {
    alertAudio.preload = 'auto';
  }

  function text(value) {
    return String(value ?? '').trim();
  }

  function positiveInteger(value, fallback = 0) {
    const parsed = Number.parseInt(value, 10);
    return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback;
  }

  function showNotice(message, variant = 'error') {
    if (!notice) {
      return;
    }

    notice.textContent = message;
    notice.className = `foodord-live-orders-admin__notice is-${variant}`;
    notice.hidden = false;
  }

  function hideNotice() {
    if (!notice) {
      return;
    }

    notice.hidden = true;
    notice.textContent = '';
  }

  function updateQuotaHeader(quota) {
    if (!quotaHeader || !quota || quota.known !== true) {
      return;
    }

    if (quota.licensed === true) {
      quotaHeader.hidden = true;
      quotaHeader.classList.remove('is-low');
      return;
    }

    const message = text(quota.message);
    if (!message || !quotaRemaining) {
      return;
    }

    quotaRemaining.textContent = message;
    quotaHeader.classList.toggle(
      'is-low',
      Number(quota.remaining) <= 10
    );
    quotaHeader.hidden = false;
  }

  function getReceiptOptions() {
    return {
      direction: config.direction,
      language: config.language,
      locale: config.currencyLocale,
      strings,
      stylesUrl: config.receiptStylesUrl,
      showToppingGroupLabels: config.groupLabels === 'yes',
      currencyFormat: config.currencyFormat,
    };
  }

  function setPrintButtonState({ busy = false, visible = true } = {}) {
    if (!modalPrintButton) {
      return;
    }

    modalPrintButton.hidden = !visible;
    modalPrintButton.disabled = busy;
    if (busy) {
      modalPrintButton.setAttribute('aria-busy', 'true');
    } else {
      modalPrintButton.removeAttribute('aria-busy');
    }
  }

  async function printOrder(order, preparedJob = null) {
    if (!receiptPrinter || !order || typeof order !== 'object') {
      preparedJob?.cancel?.();
      throw new Error(strings.printError || 'The receipt could not be prepared for printing.');
    }

    const job = preparedJob || receiptPrinter.createJob();
    await job.print(order, getReceiptOptions());
  }

  async function printActiveOrder() {
    if (!state.activeOrderDetails) {
      return;
    }

    setPrintButtonState({ busy: true });
    try {
      await printOrder(state.activeOrderDetails);
    } catch {
      showNotice(
        strings.printError || 'The receipt could not be prepared for printing.'
      );
    } finally {
      setPrintButtonState({
        busy: false,
        visible: Boolean(state.activeOrderDetails),
      });
    }
  }

  function isOrderConfirmed(order) {
    const confirmation = order?.confirmation || {};
    return (
      confirmation.confirmed === true ||
      confirmation.confirmed === 1 ||
      confirmation.confirmed === '1' ||
      Boolean(text(confirmation.confirmed_at)) ||
      Boolean(text(confirmation.confirmed_slot)) ||
      positiveInteger(confirmation.confirmed_minutes) > 0
    );
  }

  async function unlockAlertAudio() {
    if (!alertAudio || state.audioUnlocked) {
      return;
    }

    const previousMuted = alertAudio.muted;
    alertAudio.muted = true;
    alertAudio.currentTime = 0;

    try {
      await alertAudio.play();
      alertAudio.pause();
      alertAudio.currentTime = 0;
      state.audioUnlocked = true;
    } catch {
      state.audioUnlocked = false;
    } finally {
      alertAudio.muted = previousMuted;
    }
  }

  async function playAlertSound() {
    if (!alertAudio || state.pendingAlertOrderIds.size === 0) {
      return;
    }

    try {
      alertAudio.pause();
      alertAudio.currentTime = 0;
      await alertAudio.play();
      state.audioUnlocked = true;
    } catch {
      state.audioUnlocked = false;
    }
  }

  function stopAlertLoop() {
    if (!state.alertTimer) {
      return;
    }

    window.clearInterval(state.alertTimer);
    state.alertTimer = null;
  }

  function startAlertLoop() {
    if (state.alertTimer || state.pendingAlertOrderIds.size === 0) {
      return;
    }

    state.alertTimer = window.setInterval(() => {
      playAlertSound();
    }, positiveInteger(config.alertInterval, 5000));
  }

  function clearPendingAlert(orderId) {
    state.pendingAlertOrderIds.delete(text(orderId));
    if (state.pendingAlertOrderIds.size === 0) {
      stopAlertLoop();
      alertAudio?.pause();
    }
  }

  function synchronizePendingAlerts(orders) {
    const currentOrders = new Map(
      orders.map((order) => [getOrderId(order), order])
    );

    state.pendingAlertOrderIds.forEach((orderId) => {
      const order = currentOrders.get(orderId);
      if (!order || isOrderConfirmed(order)) {
        state.pendingAlertOrderIds.delete(orderId);
      }
    });

    if (state.pendingAlertOrderIds.size === 0) {
      stopAlertLoop();
      alertAudio?.pause();
      return;
    }

    startAlertLoop();
  }

  async function request(path = '', options = {}) {
    const response = await window.fetch(`${config.restBase}${path}`, {
      method: options.method || 'GET',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
        'X-WP-Nonce': config.nonce,
      },
      body: options.body ? JSON.stringify(options.body) : undefined,
      signal: options.signal,
      cache: 'no-store',
    });

    let payload = null;
    try {
      payload = await response.json();
    } catch {
      payload = null;
    }

    if (!response.ok) {
      const message =
        text(payload?.message) ||
        text(payload?.data?.message) ||
        strings.updateError ||
        'Request failed.';
      throw new Error(message);
    }

    return payload;
  }

  function getOrderId(order) {
    return text(order?.id || order?.order_id || order?.orderId);
  }

  function getStage(order) {
    const raw = text(
      order?.progress?.stage ||
        order?.order_stage ||
        order?.orderStage ||
        order?.stage
    ).toLowerCase();
    const aliases = {
      preparing: 'kitchen',
      in_kitchen: 'kitchen',
      'in-kitchen': 'kitchen',
      on_the_way: 'ontheway',
      'on-the-way': 'ontheway',
      ready: 'ontheway',
    };
    const normalized = aliases[raw] || raw;
    return stageOrder.includes(normalized) ? normalized : 'new';
  }

  function isActiveOrder(order) {
    const status = text(order?.status).replace(/^wc-/, '').toLowerCase();
    return status === 'processing';
  }

  function isSeen(order) {
    if (order?.seen === true || order?.seen === 1 || order?.seen === '1') {
      return true;
    }
    if (order?.is_new === false || order?.is_new === 0) {
      return true;
    }
    return false;
  }

  function getCustomerName(order) {
    return (
      text(order?.customer?.name) ||
      text(
        `${text(order?.billing?.first_name)} ${text(
          order?.billing?.last_name
        )}`
      ) ||
      strings.customer ||
      'Customer'
    );
  }

  function getFulfillment(order) {
    const mode = text(
      order?.fulfillment_type || order?.mode || order?.order_mode
    ).toLowerCase();
    return mode === 'pickup' ? 'pickup' : 'delivery';
  }

  function getRequestedTime(order) {
    return (
      text(order?.requested_time) ||
      text(order?.delivery_time) ||
      text(order?.pickup_time) ||
      text(order?.restaurant_confirmed_display)
    );
  }

  function getRequestedTimeDisplay(order) {
    return text(order?.requested_time_display) || getRequestedTime(order);
  }

  function parseClockMinutes(value) {
    const match = text(value).match(/^([01]\d|2[0-3]):([0-5]\d)$/u);
    if (!match) {
      return null;
    }

    return Number(match[1]) * 60 + Number(match[2]);
  }

  function formatClockMinutes(value) {
    const normalized = ((value % 1440) + 1440) % 1440;
    const hours = String(Math.floor(normalized / 60)).padStart(2, '0');
    const minutes = String(normalized % 60).padStart(2, '0');
    return `${hours}:${minutes}`;
  }

  function getAddress(order) {
    const fulfillment = getFulfillment(order);
    if (fulfillment === 'pickup') {
      return '';
    }

    const address = order?.shipping || order?.billing || {};
    const parts = [
      text(address.address_1),
      text(address.address_2),
      text(address.city),
      text(address.postcode),
    ].filter(Boolean);
    return parts.join(', ');
  }

  function formatMoney(value, currency) {
    const numeric = Number(value);
    if (!Number.isFinite(numeric)) {
      return text(value);
    }

    const settings = config.currencyFormat;
    if (settings && typeof settings === 'object') {
      const decimals = Math.max(
        0,
        Math.min(Number.parseInt(settings.decimals, 10) || 0, 8)
      );
      const [integerPart, fractionPart = ''] = numeric
        .toFixed(decimals)
        .split('.');
      const sign = integerPart.startsWith('-') ? '-' : '';
      const unsignedInteger = sign ? integerPart.slice(1) : integerPart;
      const thousandSeparator = String(settings.thousandSeparator ?? ',');
      const decimalSeparator = String(settings.decimalSeparator ?? '.');
      const groupedInteger = thousandSeparator
        ? unsignedInteger.replace(
            /\B(?=(\d{3})+(?!\d))/gu,
            thousandSeparator
          )
        : unsignedInteger;
      const amount = `${sign}${groupedInteger}${
        decimals > 0 ? `${decimalSeparator}${fractionPart}` : ''
      }`;
      const currencyCode = text(currency || settings.currency).toUpperCase();
      let symbol =
        currencyCode === text(settings.currency).toUpperCase()
          ? text(settings.symbol)
          : '';

      if (!symbol && currencyCode) {
        try {
          symbol =
            new Intl.NumberFormat(config.currencyLocale || undefined, {
              style: 'currency',
              currency: currencyCode,
              minimumFractionDigits: 0,
              maximumFractionDigits: 0,
            })
              .formatToParts(0)
              .find((part) => part.type === 'currency')?.value || currencyCode;
        } catch {
          symbol = currencyCode;
        }
      }

      switch (text(settings.position)) {
        case 'right':
          return `${amount}${symbol}`;
        case 'right_space':
          return `${amount} ${symbol}`.trim();
        case 'left_space':
          return `${symbol} ${amount}`.trim();
        default:
          return `${symbol}${amount}`;
      }
    }

    try {
      return new Intl.NumberFormat(config.currencyLocale || undefined, {
        style: 'currency',
        currency: text(currency) || 'EUR',
      }).format(numeric);
    } catch {
      return `${numeric.toFixed(2)} ${text(currency)}`.trim();
    }
  }

  function formatOrderNumber(order) {
    const number = text(order?.number || getOrderId(order));
    return (strings.orderNumber || 'Order #%s').replace('%s', number);
  }

  function createElement(tag, className = '', content = '') {
    const element = document.createElement(tag);
    if (className) {
      element.className = className;
    }
    if (content !== '') {
      element.textContent = content;
    }
    return element;
  }

  function createIcon(name) {
    const icon = createElement('span', `dashicons dashicons-${name}`);
    icon.setAttribute('aria-hidden', 'true');
    return icon;
  }

  function createFulfillmentIcon(fulfillment, className) {
    const pathData =
      fulfillment === 'pickup'
        ? [
            'M9.667 2.667a1.333 1.333 0 1 1-2.667 0 1.333 1.333 0 0 1 2.667 0M9.595 6.38a2.7 2.7 0 0 0-.037-.883l.525.525c.36.36.847.561 1.355.561h.562a.75.75 0 0 1 0 1.5h-.562c-.717 0-1.41-.225-1.987-.637.06-.39.11-.775.144-1.065M6.496 10.383l-.19-.187-.12.424a3.25 3.25 0 0 1-.658 1.222l-1.43 1.67a.75.75 0 1 0 1.138.976l1.431-1.67c.343-.4.617-.854.81-1.342a8 8 0 0 0-.753-.867l-.223-.221z',
            'M8.934 6.265c.071-.598-.096-1.276-.587-1.603a.9.9 0 0 0-.358-.106 1 1 0 0 0-.128-.018c-1.482-.077-2.49.626-3.1 1.51-.586.849-.813 1.863-.844 2.555a.75.75 0 0 0 1.499.067c.021-.483.19-1.206.579-1.77.169-.244.376-.458.638-.612l-.31 2.714a.75.75 0 0 0 .277.68c1.426 1.136 2.512 3.232 3.073 4.602a.75.75 0 0 0 1.388-.569c-.476-1.163-1.378-3.001-2.657-4.39l.043-.202c.07-.351.152-.764.206-1.023.12-.574.221-1.335.281-1.835',
          ]
        : [
            'M12 10.083a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5m-2.75 1.25a2.75 2.75 0 1 1 5.5 0 2.75 2.75 0 0 1-5.5 0M4 10.083a1.25 1.25 0 1 0 0 2.5 1.25 1.25 0 0 0 0-2.5m-2.75 1.25a2.75 2.75 0 1 1 5.5 0 2.75 2.75 0 0 1-5.5 0',
            'M7.47 5.136a.75.75 0 0 1 .946-.093l.227.152c.391.263.607.409.905.517.337.122.817.205 1.785.205a.75.75 0 0 1 0 1.5c-1.032 0-1.718-.085-2.298-.295a4 4 0 0 1-.41-.179c-.279.388-.668.798-1.069 1.086a5.27 5.27 0 0 1 1.194 3.304v.666a.75.75 0 0 1-1.5.001v-.667c0-1.105-.547-2.218-1.346-2.83-.481-.369-.648-1.153-.127-1.674zM10.667 3.333a1.333 1.333 0 1 1-2.667 0 1.333 1.333 0 0 1 2.667 0M6.256 2.98a.833.833 0 0 0-1.179 0l-1.93 1.93a.833.833 0 0 0 0 1.18l.597.597a.833.833 0 0 0 1.179 0l1.93-1.931a.833.833 0 0 0 0-1.179z',
          ];
    const iconWrapper = createElement('span', className);
    iconWrapper.setAttribute('aria-hidden', 'true');

    const icon = document.createElementNS('http://www.w3.org/2000/svg', 'svg');
    icon.setAttribute('viewBox', '0 0 16 16');
    icon.setAttribute('width', '16');
    icon.setAttribute('height', '16');
    icon.setAttribute('fill', 'currentColor');
    icon.setAttribute('role', 'presentation');
    icon.setAttribute('aria-hidden', 'true');
    icon.setAttribute('focusable', 'false');

    pathData.forEach((data) => {
      const path = document.createElementNS(
        'http://www.w3.org/2000/svg',
        'path'
      );
      path.setAttribute('d', data);
      icon.appendChild(path);
    });
    iconWrapper.appendChild(icon);
    return iconWrapper;
  }

  function createFulfillmentBadge(fulfillment) {
    const label =
      fulfillment === 'pickup'
        ? strings.pickup || 'Pickup'
        : strings.delivery || 'Delivery';
    const badge = createElement(
      'span',
      `foodord-live-order-card__badge is-${fulfillment}`
    );
    badge.setAttribute('aria-label', label);

    const labelElement = createElement(
      'span',
      'foodord-live-order-card__badge-text',
      label
    );
    badge.append(
      createFulfillmentIcon(
        fulfillment,
        'foodord-live-order-card__badge-icon'
      ),
      labelElement
    );
    return badge;
  }

  function parseTimestamp(value) {
    const raw = text(value);
    if (!raw) {
      return null;
    }

    const timestamp = Date.parse(raw.includes('T') ? raw : raw.replace(' ', 'T'));
    return Number.isFinite(timestamp) ? timestamp : null;
  }

  function getRequestedTimestamp(order) {
    const explicitTimestamp = parseTimestamp(order?.requested_datetime);
    if (explicitTimestamp !== null) {
      return explicitTimestamp;
    }

    const requestedTime = getRequestedTime(order);
    if (!requestedTime) {
      return null;
    }

    const directTimestamp = parseTimestamp(requestedTime);
    if (directTimestamp !== null && /\d{4}-\d{2}-\d{2}/u.test(requestedTime)) {
      return directTimestamp;
    }

    const match = requestedTime.match(
      /\b([01]?\d|2[0-3])(?:[:.]([0-5]\d))?\s*(am|pm)?\b/iu
    );
    const referenceTimestamp = parseTimestamp(order?.date);
    if (!match || referenceTimestamp === null) {
      return null;
    }

    let hour = Number(match[1]);
    const minute = Number(match[2] || 0);
    const meridiem = text(match[3]).toLowerCase();
    if (meridiem === 'pm' && hour < 12) {
      hour += 12;
    } else if (meridiem === 'am' && hour === 12) {
      hour = 0;
    }

    const requestedDate = new Date(referenceTimestamp);
    requestedDate.setHours(hour, minute, 0, 0);
    return requestedDate.getTime();
  }

  function deriveCountdown(order) {
    const confirmation = order?.confirmation || {};
    const confirmedMinutes = positiveInteger(
      confirmation.confirmed_minutes ||
        order?.restaurant_confirmed_minutes ||
        order?.confirmed_minutes
    );
    const confirmedSlot = parseTimestamp(
      confirmation.confirmed_slot ||
        confirmation.confirmed_slot_local ||
        order?.restaurant_confirmed_time
    );

    if (confirmedSlot !== null) {
      return {
        mode: 'scheduled',
        targetTimestamp: confirmedSlot,
        initialMinutes:
          confirmedMinutes ||
          Math.max(Math.round((confirmedSlot - Date.now()) / 60000), 0),
      };
    }

    const confirmedAt = parseTimestamp(
      confirmation.confirmed_at || confirmation.confirmed_at_local
    );
    if (confirmedAt !== null && confirmedMinutes > 0) {
      return {
        mode: 'duration',
        targetTimestamp: confirmedAt + confirmedMinutes * 60000,
        initialMinutes: confirmedMinutes,
      };
    }

    const requestedTimestamp = getRequestedTimestamp(order);
    if (requestedTimestamp === null) {
      return null;
    }

    return {
      mode: 'scheduled',
      targetTimestamp: requestedTimestamp,
      initialMinutes: Math.max(
        Math.round((requestedTimestamp - Date.now()) / 60000),
        0
      ),
    };
  }

  function getCountdown(order) {
    const orderId = getOrderId(order);
    if (!orderId) {
      return null;
    }

    const derived = deriveCountdown(order);
    if (!derived) {
      state.countdowns.delete(orderId);
      return null;
    }

    const current = state.countdowns.get(orderId);
    if (
      !current ||
      Math.abs(current.targetTimestamp - derived.targetTimestamp) > 30000 ||
      current.mode !== derived.mode
    ) {
      state.countdowns.set(orderId, derived);
    }

    return state.countdowns.get(orderId);
  }

  function coerceTimestamp(value) {
    if (value instanceof Date) {
      const timestamp = value.getTime();
      return Number.isFinite(timestamp) ? timestamp : null;
    }
    if (typeof value === 'number') {
      if (!Number.isFinite(value) || value <= 0) {
        return null;
      }
      return Math.round(value < 1e12 ? value * 1000 : value);
    }
    if (typeof value !== 'string') {
      return null;
    }

    const normalized = value.trim();
    if (!normalized) {
      return null;
    }

    const numeric = Number(normalized);
    if (Number.isFinite(numeric)) {
      return coerceTimestamp(numeric);
    }

    const timestamp = Date.parse(normalized);
    return Number.isFinite(timestamp) ? timestamp : null;
  }

  function getOrderCreatedSortTimestamp(order) {
    const candidates = [
      order?.date_created_gmt,
      order?.date_created,
      order?.dateCreated,
      order?.created_at,
      order?.createdAt,
      order?.date,
    ];

    for (const candidate of candidates) {
      const timestamp = coerceTimestamp(candidate);
      if (timestamp !== null) {
        return timestamp;
      }
    }

    return Number.POSITIVE_INFINITY;
  }

  function getOrderUrgencySortValue(order) {
    const countdown = getCountdown(order);
    if (!countdown || !Number.isFinite(countdown.targetTimestamp)) {
      return Number.POSITIVE_INFINITY;
    }

    return Math.floor((countdown.targetTimestamp - Date.now()) / 60000);
  }

  function sortOrdersByUrgency(orders) {
    return [...orders].sort((first, second) => {
      const urgencyDifference =
        getOrderUrgencySortValue(first) - getOrderUrgencySortValue(second);
      if (urgencyDifference !== 0) {
        return urgencyDifference;
      }

      const createdDifference =
        getOrderCreatedSortTimestamp(first) -
        getOrderCreatedSortTimestamp(second);
      if (createdDifference !== 0) {
        return createdDifference;
      }

      return getOrderId(first).localeCompare(getOrderId(second));
    });
  }

  function updateCountdownElement(element, order) {
    const countdown = getCountdown(order);
    element.className = 'foodord-live-order-card__countdown';

    const value = element.querySelector(
      '.foodord-live-order-card__countdown-value'
    );
    const progress = element.querySelector(
      '.foodord-live-order-card__countdown-progress-value'
    );
    progress?.setAttribute('stroke-dashoffset', '100');
    if (!value) {
      return;
    }
    if (!countdown) {
      element.classList.add('is-empty');
      value.textContent = '--';
      element.setAttribute('aria-label', strings.notAvailable || 'Not available');
      return;
    }

    const remainingMs = countdown.targetTimestamp - Date.now();
    const remainingMinutes = Math.floor(remainingMs / 60000);
    const expired = remainingMs <= 0;
    const critical =
      !expired && remainingMinutes >= 0 && remainingMinutes <= 15;
    value.textContent = String(remainingMinutes);
    element.classList.toggle('is-expired', expired);
    element.classList.toggle('is-critical', critical);
    element.classList.toggle('is-negative', remainingMinutes < 0);

    if (!expired && countdown.initialMinutes > 0) {
      const totalMs = countdown.initialMinutes * 60000;
      const elapsedRatio = Math.min(
        Math.max((totalMs - Math.max(remainingMs, 0)) / totalMs, 0),
        1
      );
      element.classList.add('has-progress');
      progress?.setAttribute(
        'stroke-dashoffset',
        String((100 - elapsedRatio * 100).toFixed(2))
      );
    }

    const absoluteMinutes = Math.abs(remainingMinutes);
    element.setAttribute(
      'aria-label',
      `${absoluteMinutes} ${strings.minutes || 'minutes'}`
    );
  }

  function createCountdown(order) {
    const countdown = createElement(
      'span',
      'foodord-live-order-card__countdown'
    );
    const progress = document.createElementNS(
      'http://www.w3.org/2000/svg',
      'svg'
    );
    progress.setAttribute(
      'class',
      'foodord-live-order-card__countdown-progress'
    );
    progress.setAttribute('viewBox', '0 0 50 50');
    progress.setAttribute('aria-hidden', 'true');
    progress.setAttribute('focusable', 'false');

    const progressTrack = document.createElementNS(
      'http://www.w3.org/2000/svg',
      'circle'
    );
    progressTrack.setAttribute(
      'class',
      'foodord-live-order-card__countdown-progress-track'
    );
    progressTrack.setAttribute('cx', '25');
    progressTrack.setAttribute('cy', '25');
    progressTrack.setAttribute('r', '23');
    progressTrack.setAttribute('pathLength', '100');

    const progressValue = document.createElementNS(
      'http://www.w3.org/2000/svg',
      'circle'
    );
    progressValue.setAttribute(
      'class',
      'foodord-live-order-card__countdown-progress-value'
    );
    progressValue.setAttribute('cx', '25');
    progressValue.setAttribute('cy', '25');
    progressValue.setAttribute('r', '23');
    progressValue.setAttribute('pathLength', '100');
    progressValue.setAttribute('stroke-dasharray', '100');
    progressValue.setAttribute('stroke-dashoffset', '100');
    progress.append(progressTrack, progressValue);

    countdown.append(
      progress,
      createElement('span', 'foodord-live-order-card__countdown-value', '--'),
      createElement('span', 'foodord-live-order-card__countdown-icon', '′')
    );
    countdown
      .querySelector('.foodord-live-order-card__countdown-icon')
      ?.setAttribute('aria-hidden', 'true');
    updateCountdownElement(countdown, order);
    return countdown;
  }

  function updateVisibleCountdowns() {
    root.querySelectorAll('.foodord-live-order-card').forEach((card) => {
      const order = state.orders.get(text(card.dataset.orderId));
      const countdown = card.querySelector(
        '.foodord-live-order-card__countdown'
      );
      if (order && countdown) {
        updateCountdownElement(countdown, order);
      }
    });
  }

  function getStageAction(stage, direction) {
    if (stage === 'new' && direction === 'next') {
      return {
        target: 'kitchen',
        label: strings.moveToKitchen || 'Send to kitchen',
      };
    }
    if (stage === 'kitchen' && direction === 'next') {
      return {
        target: 'ontheway',
        label: strings.moveToOnTheWay || 'Mark as on the way',
      };
    }
    if (stage === 'ontheway' && direction === 'previous') {
      return {
        target: 'kitchen',
        label: strings.moveBackToKitchen || 'Move back to kitchen',
      };
    }
    return null;
  }

  function createStageButton(orderId, action) {
    const button = createElement(
      'button',
      'foodord-live-order-card__stage-button'
    );
    button.type = 'button';
    button.dataset.orderStage = action.target;
    button.dataset.orderId = orderId;
    button.setAttribute('aria-label', action.label);
    button.title = action.label;
    button.disabled = state.stageUpdates.has(orderId);
    const imageUrl = text(config.emptyStateImages?.[action.target]);

    if (imageUrl) {
      const image = createElement(
        'img',
        'foodord-live-order-card__stage-image'
      );
      image.src = imageUrl;
      image.alt = '';
      image.setAttribute('aria-hidden', 'true');
      button.appendChild(image);
    } else {
      button.appendChild(createIcon('arrow-right-alt'));
    }

    return button;
  }

  function createOrderCard(order) {
    const orderId = getOrderId(order);
    const stage = getStage(order);
    const card = createElement('article', 'foodord-live-order-card');
    card.dataset.orderId = orderId;
    card.dataset.stage = stage;
    card.tabIndex = 0;
    card.draggable = !state.stageUpdates.has(orderId);
    card.setAttribute('role', 'button');
    card.setAttribute('aria-label', `${formatOrderNumber(order)}, ${getCustomerName(order)}`);

    if (!isSeen(order)) {
      card.classList.add('is-new');
    }

    const header = createElement('div', 'foodord-live-order-card__header');
    const identityGroup = createElement(
      'div',
      'foodord-live-order-card__identity'
    );
    const identity = createElement(
      'span',
      'foodord-live-order-card__number',
      `#${text(order?.number || orderId)}`
    );
    const fulfillment = getFulfillment(order);
    identityGroup.append(identity, createFulfillmentBadge(fulfillment));
    header.append(identityGroup, createCountdown(order));

    const customer = createElement(
      'h3',
      'foodord-live-order-card__customer',
      getCustomerName(order)
    );

    const addressText = getAddress(order);
    card.append(header, customer);
    if (addressText) {
      const address = createElement(
        'p',
        'foodord-live-order-card__address',
        addressText
      );
      card.appendChild(address);
    }

    const footer = createElement('footer', 'foodord-live-order-card__footer');
    const total = createElement(
      'strong',
      'foodord-live-order-card__total',
      formatMoney(order?.total, order?.currency)
    );
    const actions = createElement('div', 'foodord-live-order-card__actions');
    const previousAction = getStageAction(stage, 'previous');
    const nextAction = getStageAction(stage, 'next');

    if (previousAction) {
      actions.appendChild(createStageButton(orderId, previousAction));
    }
    if (nextAction) {
      actions.appendChild(createStageButton(orderId, nextAction));
    }

    footer.append(total, actions);
    card.appendChild(footer);
    return card;
  }

  function getEmptyMessage(stage) {
    if (stage === 'kitchen') {
      return strings.noKitchenOrders || 'Orders being prepared will appear here.';
    }
    if (stage === 'ontheway') {
      return strings.noOnTheWayOrders || 'Orders ready for delivery will appear here.';
    }
    return strings.noNewOrders || 'New orders will appear here automatically.';
  }

  function createEmptyState(stage) {
    const empty = createElement(
      'div',
      `foodord-live-orders-column__empty foodord-live-orders-column__empty--${stage}`
    );
    const iconNames = {
      new: 'bell',
      kitchen: 'food',
      ontheway: 'location-alt',
    };
    const imageUrl = text(config.emptyStateImages?.[stage]);

    if (imageUrl) {
      const image = createElement(
        'img',
        'foodord-live-orders-column__empty-image'
      );
      image.src = imageUrl;
      image.alt = '';
      image.setAttribute('aria-hidden', 'true');
      empty.appendChild(image);
    } else {
      empty.appendChild(createIcon(iconNames[stage] || 'cart'));
    }

    empty.appendChild(createElement('p', '', getEmptyMessage(stage)));
    return empty;
  }

  function renderBoard(isLoading = false) {
    const grouped = {
      new: [],
      kitchen: [],
      ontheway: [],
    };

    state.orders.forEach((order) => {
      grouped[getStage(order)].push(order);
    });

    stageOrder.forEach((stage) => {
      grouped[stage] = sortOrdersByUrgency(grouped[stage]);

      const content = root.querySelector(
        `[data-live-column-content="${stage}"]`
      );
      const count = root.querySelector(`[data-live-count="${stage}"]`);
      const tabCount = root.querySelector(`[data-live-tab-count="${stage}"]`);

      if (count) {
        count.classList.toggle('is-loading', isLoading);
        count.toggleAttribute('aria-hidden', isLoading);
        count.textContent = isLoading ? '' : String(grouped[stage].length);
      }
      if (tabCount) {
        tabCount.textContent = String(grouped[stage].length);
      }
      if (!content) {
        return;
      }

      content.replaceChildren();
      if (grouped[stage].length === 0) {
        content.appendChild(createEmptyState(stage));
        return;
      }

      grouped[stage].forEach((order) => {
        content.appendChild(createOrderCard(order));
      });
    });

    board?.setAttribute('aria-busy', isLoading ? 'true' : 'false');
    applyActiveColumn();
  }

  function normalizeOrders(payload) {
    const source = Array.isArray(payload?.orders)
      ? payload.orders
      : Array.isArray(payload?.data)
        ? payload.data
        : [];
    return source.filter((order) => getOrderId(order) && isActiveOrder(order));
  }

  function openNextQueuedOrder() {
    if (!modal || !modal.hidden || state.activeOrderId) {
      return;
    }

    while (state.newOrderModalQueue.length > 0) {
      const orderId = state.newOrderModalQueue.shift();
      state.queuedModalOrderIds.delete(orderId);
      const order = state.orders.get(orderId);
      if (!order || isOrderConfirmed(order)) {
        continue;
      }

      const trigger = Array.from(
        root.querySelectorAll('.foodord-live-order-card')
      ).find((card) => text(card.dataset.orderId) === orderId);
      openOrderModal(orderId, trigger || null);
      return;
    }
  }

  function announceNewOrders(orders) {
    if (!state.initialized) {
      return;
    }

    const newlyArrived = orders.filter((order) => {
      const orderId = getOrderId(order);
      return (
        orderId &&
        !state.knownOrderIds.has(orderId) &&
        !isOrderConfirmed(order)
      );
    });

    if (newlyArrived.length > 0) {
      newlyArrived.forEach((order) => {
        const orderId = getOrderId(order);
        state.pendingAlertOrderIds.add(orderId);
        if (
          orderId !== state.activeOrderId &&
          !state.queuedModalOrderIds.has(orderId)
        ) {
          state.queuedModalOrderIds.add(orderId);
          state.newOrderModalQueue.push(orderId);
        }
      });
      playAlertSound();
      startAlertLoop();
    }
  }

  async function refreshOrders() {
    if (state.loading) {
      return;
    }

    state.loading = true;
    const requestRevision = state.refreshRevision;

    if (state.requestController) {
      state.requestController.abort();
    }
    state.requestController = new AbortController();

    try {
      const payload = await request('?page=1&per_page=100', {
        signal: state.requestController.signal,
      });
      if (
        requestRevision !== state.refreshRevision ||
        state.stageUpdates.size > 0
      ) {
        return;
      }
      updateQuotaHeader(payload?.quota);
      const orders = normalizeOrders(payload);
      announceNewOrders(orders);
      synchronizePendingAlerts(orders);

      state.orders.clear();
      orders.forEach((order) => {
        const orderId = getOrderId(order);
        state.orders.set(orderId, order);
        state.knownOrderIds.add(orderId);
      });
      state.countdowns.forEach((_countdown, orderId) => {
        if (!state.orders.has(orderId)) {
          state.countdowns.delete(orderId);
        }
      });

      state.initialized = true;
      renderBoard();
      openNextQueuedOrder();
      if (state.activeOrderId) {
        const activeOrder = state.orders.get(state.activeOrderId);
        if (activeOrder) {
          updateModalStageControls(activeOrder);
        }
      }
      hideNotice();
    } catch (error) {
      if (error?.name !== 'AbortError') {
        if (!state.initialized) {
          showNotice(
            error?.message || strings.loadError || 'Live orders could not be loaded.'
          );
        }
      }
    } finally {
      state.loading = false;
      scheduleRefresh();
    }
  }

  function scheduleRefresh() {
    if (state.refreshTimer) {
      window.clearTimeout(state.refreshTimer);
    }

    const interval = document.hidden
      ? positiveInteger(config.hiddenInterval, 30000)
      : positiveInteger(config.refreshInterval, 30000);

    state.refreshTimer = window.setTimeout(() => {
      refreshOrders();
    }, interval);
  }

  async function updateStage(orderId, targetStage, trigger) {
    const order = state.orders.get(orderId);
    if (
      !order ||
      !stageOrder.includes(targetStage) ||
      state.stageUpdates.has(orderId)
    ) {
      return;
    }

    trigger?.setAttribute('aria-busy', 'true');
    trigger?.setAttribute('disabled', 'disabled');

    const previousStage = getStage(order);
    state.stageUpdates.set(orderId, targetStage);
    state.refreshRevision += 1;
    order.progress = {
      ...(order.progress || {}),
      stage: targetStage,
    };
    state.orders.set(orderId, order);
    renderBoard();
    if (state.activeOrderId === orderId) {
      updateModalStageControls(order);
    }

    try {
      const response = await request(`/${orderId}/stage`, {
        method: 'POST',
        body: { stage: targetStage },
      });
      order.progress = {
        ...(order.progress || {}),
        ...(response?.progress || {}),
        stage: text(response?.stage || response?.progress?.stage) || targetStage,
      };
      state.orders.set(orderId, order);
      state.stageUpdates.delete(orderId);
      state.refreshRevision += 1;
      renderBoard();
      if (state.activeOrderId === orderId) {
        updateModalStageControls(order);
      }
      await refreshOrders();
    } catch (error) {
      state.stageUpdates.delete(orderId);
      state.refreshRevision += 1;
      order.progress = {
        ...(order.progress || {}),
        stage: previousStage,
      };
      state.orders.set(orderId, order);
      renderBoard();
      if (state.activeOrderId === orderId) {
        updateModalStageControls(order);
      }
      showNotice(
        error?.message ||
          strings.updateError ||
          'The order could not be updated.'
      );
    } finally {
      trigger?.removeAttribute('aria-busy');
      if (state.stageUpdates.has(orderId)) {
        trigger?.setAttribute('disabled', 'disabled');
      } else {
        trigger?.removeAttribute('disabled');
      }
    }
  }

  async function markSeen(orderId) {
    const order = state.orders.get(orderId);
    if (!order || isSeen(order)) {
      return;
    }

    order.seen = true;
    order.is_new = false;
    renderBoard();

    try {
      await request(`/${orderId}/seen`, {
        method: 'POST',
        body: { seen: true },
      });
    } catch {
      scheduleRefresh();
    }
  }

  function renderSkeleton() {
    if (!modalBody) {
      return;
    }

    modal?.classList.add('is-loading');
    setPrintButtonState({ visible: false });
    if (modalStatus) {
      modalStatus.hidden = false;
    }
    if (modalStageControls) {
      modalStageControls.hidden = false;
    }

    const skeleton = createElement(
      'div',
      'foodord-live-order-modal__skeleton'
    );
    skeleton.append(
      createElement('span', 'foodord-live-order-modal__skeleton-delivery'),
      createElement('span', 'foodord-live-order-modal__skeleton-note'),
      createElement('span', 'foodord-live-order-modal__skeleton-items'),
      createElement('span', 'foodord-live-order-modal__skeleton-summary')
    );
    modalBody.replaceChildren(skeleton);
    if (modalFooter) {
      const footerSkeleton = createElement(
        'div',
        'foodord-live-order-modal__footer-skeleton'
      );
      footerSkeleton.append(
        createElement('span'),
        createElement('span')
      );
      modalFooter.replaceChildren(footerSkeleton);
      modalFooter.hidden = false;
    }
  }

  function numericAmount(value) {
    if (value === null || value === undefined || value === '') {
      return null;
    }

    const parsed = Number(value);
    return Number.isFinite(parsed) ? parsed : null;
  }

  function isPaidOrder(order) {
    const paid =
      order?.is_paid === true ||
      order?.is_paid === 1 ||
      order?.is_paid === '1' ||
      order?.payment_verified === true ||
      order?.payment_verified === 1 ||
      order?.payment_verified === '1';
    const method = text(order?.payment_method).toLowerCase();
    const offlineMethods = [
      'bacs',
      'cash',
      'cheque',
      'cod',
      'pay_at_pickup',
      'pay-at-pickup',
      'pay_later',
      'pay-later',
    ];

    return paid && !offlineMethods.some((entry) => method.includes(entry));
  }

  function renderModalStatus(order) {
    if (!modalStatus || !modalFulfillment || !modalPayment) {
      return;
    }

    const fulfillment = getFulfillment(order);
    const fulfillmentLabel =
      fulfillment === 'pickup'
        ? strings.pickup || 'Pickup'
        : strings.delivery || 'Delivery';

    modalFulfillment.className = `foodord-live-order-modal__status is-${fulfillment}`;
    modalFulfillment.replaceChildren(
      createFulfillmentIcon(
        fulfillment,
        'foodord-live-order-modal__status-icon'
      ),
      createElement('span', '', fulfillmentLabel)
    );

    const paid = isPaidOrder(order);
    modalPayment.className = `foodord-live-order-modal__status ${
      paid ? 'is-paid' : 'is-unpaid'
    }`;
    modalPayment.replaceChildren(
      createElement(
        'span',
        '',
        paid
          ? strings.onlinePaid || 'Online paid'
          : `${strings.notPaid || 'Not paid'}!`
      )
    );
    modalStatus.hidden = false;
  }

  function updateModalStageControls(order) {
    if (!modalStageControls) {
      return;
    }

    const visible = isActiveOrder(order);
    const activeStage = getStage(order);
    const updatePending = state.stageUpdates.has(getOrderId(order));
    modalStageControls.hidden = !visible;
    modalStageControls
      .querySelectorAll('[data-live-modal-stage]')
      .forEach((button) => {
        const active = button.dataset.liveModalStage === activeStage;
        button.classList.toggle('is-active', active);
        button.setAttribute('aria-pressed', active ? 'true' : 'false');
        button.disabled = updatePending;
      });
  }

  function appendContactLine(container, label, value) {
    if (!value) {
      return;
    }

    const line = createElement('p', 'foodord-live-order-delivery__text');
    line.append(
      createElement('span', '', `${label}:`),
      document.createTextNode(` ${value}`)
    );
    container.appendChild(line);
  }

  function getOrderItems(order) {
    if (Array.isArray(order?.items)) {
      return order.items;
    }
    if (Array.isArray(order?.line_items)) {
      return order.line_items;
    }
    return [];
  }

  function renderItemMeta(item, container) {
    const entries = Array.isArray(item?.meta_data) ? item.meta_data : [];
    entries.forEach((entry) => {
      const label = text(entry?.display_key || entry?.key);
      const value = text(entry?.display_value || entry?.value);
      if (!label || !value || label.startsWith('_')) {
        return;
      }
      container.appendChild(
        createElement(
          'span',
          'foodord-live-order-item__meta-entry',
          `${label}: ${value}`
        )
      );
    });
  }

  function renderItemToppings(item, container, currency) {
    const toppingSets = Array.isArray(item?.toppings) ? item.toppings : [];

    toppingSets.forEach((set) => {
      const choices = Array.isArray(set?.items) ? set.items : [];
      const toppingGroup = createElement(
        'div',
        'foodord-live-order-item__topping-group'
      );
      const label =
        text(set?.set_name || set?.set_label || set?.name || set?.label) ||
        strings.toppings ||
        'Toppings';

      choices.forEach((choice) => {
        const choiceLabel =
          typeof choice === 'string'
            ? text(choice)
            : text(choice?.label || choice?.name || choice?.value);
        if (!choiceLabel) {
          return;
        }

        const price =
          choice && typeof choice === 'object'
            ? numericAmount(
                choice.price ??
                  choice.extra ??
                  choice.amount ??
                  choice.total
              )
            : null;
        const priceText =
          price !== null && price !== 0
            ? ` (+${formatMoney(price, currency)})`
            : '';

        toppingGroup.appendChild(
          createElement(
            'span',
            'foodord-live-order-item__topping-choice',
            `+ ${choiceLabel}${priceText}`
          )
        );
      });

      if (toppingGroup.childElementCount === 0) {
        return;
      }

      if (config.groupLabels === 'yes') {
        toppingGroup.prepend(
          createElement(
            'span',
            'foodord-live-order-item__topping-label',
            `${label}:`
          )
        );
      }
      container.appendChild(toppingGroup);
    });
  }

  function appendSummaryRow(
    container,
    label,
    value,
    currency,
    modifier = '',
    force = false
  ) {
    const amount = numericAmount(value);
    if (amount === null || (!force && amount <= 0)) {
      return;
    }

    const row = createElement(
      'div',
      `foodord-live-order-summary__row${
        modifier ? ` foodord-live-order-summary__row--${modifier}` : ''
      }`
    );
    row.append(
      createElement('span', '', label),
      createElement(
        'strong',
        '',
        `${modifier === 'discount' ? '-' : ''}${formatMoney(
          Math.abs(amount),
          currency
        )}`
      )
    );
    container.appendChild(row);
  }

  function renderOrderSummary(order, container) {
    const currency = text(order?.currency) || 'EUR';
    appendSummaryRow(
      container,
      strings.subtotal || 'Subtotal',
      order?.subtotal_incl_tax ?? order?.subtotal,
      currency,
      '',
      true
    );

    const taxLines = Array.isArray(order?.tax_lines)
      ? order.tax_lines
      : Array.isArray(order?.taxLines)
        ? order.taxLines
        : [];
    taxLines.forEach((entry) => {
      const rate = numericAmount(entry?.rate_percent ?? entry?.rate);
      const rawLabel = text(entry?.label || entry?.name) || 'VAT';
      const label =
        rate !== null && !rawLabel.includes('%')
          ? `${rawLabel} (${Number(rate.toFixed(3))}%)`
          : rawLabel;
      appendSummaryRow(
        container,
        label,
        entry?.total ?? entry?.amount,
        currency,
        'tax'
      );
    });

    appendSummaryRow(
      container,
      strings.deliveryFee || 'Delivery fee',
      order?.delivery_fee ?? order?.shipping_total,
      currency
    );
    appendSummaryRow(
      container,
      strings.tip || 'Tip',
      order?.tip_amount ?? order?.tip_total ?? order?.tip,
      text(order?.tip_currency) || currency
    );
    appendSummaryRow(
      container,
      strings.deposit || 'Deposit',
      order?.reservation_deposit_amount ??
        order?.deposit_amount ??
        order?.foodord_reservation_deposit?.amount,
      order?.foodord_reservation_deposit?.currency || currency
    );
    appendSummaryRow(
      container,
      strings.discount || 'Discount',
      order?.discount_total,
      currency,
      'discount'
    );
    appendSummaryRow(
      container,
      strings.total || 'Total',
      order?.total,
      currency,
      'total',
      true
    );
  }

  function updatePreparationControl() {
    const value = modalFooter?.querySelector(
      '[data-live-confirmation-duration]'
    );
    const decrease = modalFooter?.querySelector(
      '[data-live-preparation-decrease]'
    );
    const increase = modalFooter?.querySelector(
      '[data-live-preparation-increase]'
    );
    if (!value || !decrease || !increase) {
      return;
    }

    const values = state.preparationValues;
    if (!Array.isArray(values) || values.length === 0) {
      return;
    }

    const safeIndex = Math.min(
      Math.max(state.preparationIndex, 0),
      values.length - 1
    );
    state.preparationIndex = safeIndex;
    const selected = values[safeIndex];
    if (state.preparationMode === 'scheduled') {
      value.textContent = text(selected?.display);
      value.dataset.value = text(selected?.datetime);
      value.dataset.type = 'scheduled';
    } else {
      value.textContent = String(selected);
      value.dataset.value = String(selected);
      value.dataset.type = 'duration';
    }
    decrease.disabled = safeIndex === 0;
    increase.disabled =
      state.preparationMode !== 'scheduled' && safeIndex === values.length - 1;
  }

  function configurePreparationControl(order) {
    const requestedTimestamp = parseTimestamp(order?.requested_datetime);
    const requestedClockMinutes = parseClockMinutes(order?.requested_time);

    if (
      requestedTimestamp !== null &&
      requestedTimestamp > Date.now() &&
      requestedClockMinutes !== null
    ) {
      const confirmedTimestamp = parseTimestamp(
        order?.confirmation?.confirmed_slot ||
          order?.restaurant_confirmed_time
      );
      const targetTimestamp =
        confirmedTimestamp !== null &&
        confirmedTimestamp >= requestedTimestamp
          ? confirmedTimestamp
          : requestedTimestamp;
      const targetOffsetMinutes = Math.max(
        Math.round((targetTimestamp - requestedTimestamp) / 60000),
        0
      );
      const intervalCount = Math.floor(targetOffsetMinutes / 15);
      state.preparationMode = 'scheduled';
      state.preparationValues = Array.from(
        { length: intervalCount + 1 },
        (_, index) => ({
          datetime: new Date(
            requestedTimestamp + index * 15 * 60000
          ).toISOString(),
          display: formatClockMinutes(
            requestedClockMinutes + index * 15
          ),
        })
      );
      if (targetOffsetMinutes % 15 !== 0) {
        state.preparationValues.push({
          datetime: new Date(targetTimestamp).toISOString(),
          display: formatClockMinutes(
            requestedClockMinutes + targetOffsetMinutes
          ),
        });
      }
      state.preparationIndex = state.preparationValues.length - 1;
      return;
    }

    const confirmedMinutes = positiveInteger(
      order?.confirmation?.confirmed_minutes ??
        order?.restaurant_confirmed_minutes
    );
    const confirmedIndex = preparationTimeValues.indexOf(confirmedMinutes);
    state.preparationMode = 'duration';
    state.preparationValues = preparationTimeValues.slice();
    state.preparationIndex =
      confirmedIndex >= 0
        ? confirmedIndex
        : preparationTimeValues.indexOf(30);
  }

  function adjustPreparationControl(step) {
    if (step > 0 && state.preparationMode === 'scheduled') {
      const values = state.preparationValues;
      if (state.preparationIndex + step >= values.length) {
        const last = values[values.length - 1];
        const lastTimestamp = parseTimestamp(last?.datetime);
        const lastClockMinutes = parseClockMinutes(last?.display);
        if (lastTimestamp !== null && lastClockMinutes !== null) {
          values.push({
            datetime: new Date(lastTimestamp + 15 * 60000).toISOString(),
            display: formatClockMinutes(lastClockMinutes + 15),
          });
        }
      }
    }

    state.preparationIndex += step;
    updatePreparationControl();
  }

  function renderModalFooter(order) {
    if (!modalFooter) {
      return;
    }

    modalFooter.replaceChildren();
    if (!isActiveOrder(order)) {
      modalFooter.hidden = true;
      return;
    }

    const content = createElement(
      'div',
      'foodord-live-order-modal__footer-content'
    );
    const requestedTime = getRequestedTimeDisplay(order);
    if (requestedTime) {
      const timingNote = createElement(
        'p',
        'foodord-live-order-modal__timing-note'
      );
      const fulfillment = getFulfillment(order);
      const timingLabel =
        fulfillment === 'pickup'
          ? strings.pickupTimingLabel || 'Customer preferred pickup time:'
          : strings.deliveryTimingLabel ||
            'Customer preferred delivery time:';

      timingNote.append(
        createElement('span', '', timingLabel),
        document.createTextNode(' '),
        createElement(
          'span',
          'foodord-live-order-modal__timing-value',
          requestedTime
        )
      );
      content.appendChild(timingNote);
    }

    configurePreparationControl(order);

    const actions = createElement(
      'div',
      'foodord-live-order-modal__actions'
    );
    const preparation = createElement(
      'div',
      'foodord-live-order-modal__preparation'
    );
    const decrease = createElement(
      'button',
      'foodord-live-order-modal__preparation-button',
      '−'
    );
    decrease.type = 'button';
    decrease.dataset.livePreparationDecrease = '';
    decrease.setAttribute(
      'aria-label',
      strings.decreasePreparation || 'Decrease preparation time'
    );

    const value = createElement(
      'span',
      'foodord-live-order-modal__preparation-value'
    );
    value.dataset.liveConfirmationDuration = '';

    const increase = createElement(
      'button',
      'foodord-live-order-modal__preparation-button',
      '+'
    );
    increase.type = 'button';
    increase.dataset.livePreparationIncrease = '';
    increase.setAttribute(
      'aria-label',
      strings.increasePreparation || 'Increase preparation time'
    );
    preparation.append(decrease, value, increase);

    const confirmButton = createElement(
      'button',
      'foodord-live-order-modal__primary-button',
      strings.acceptOrder || 'Confirm'
    );
    confirmButton.type = 'button';
    confirmButton.dataset.liveConfirmOrder = getOrderId(order);
    actions.append(preparation, confirmButton);
    content.appendChild(actions);

    modalFooter.appendChild(content);
    modalFooter.hidden = content.childElementCount === 0;
    updatePreparationControl();
  }

  function renderOrderDetails(order) {
    if (!modalBody || !modalFooter) {
      return;
    }

    modal?.classList.remove('is-loading');
    state.activeOrderDetails = order;
    setPrintButtonState({ visible: true });
    renderModalStatus(order);
    updateModalStageControls(order);

    const content = createElement('div', 'foodord-live-order-details');
    const deliverySection = createElement(
      'section',
      'foodord-live-order-details__section foodord-live-order-details__delivery'
    );
    const deliveryHeader = createElement(
      'div',
      'foodord-live-order-details__header'
    );
    deliveryHeader.appendChild(
      createElement('h3', '', strings.deliveryDetails || 'Delivery details')
    );
    if (modalPrintButton) {
      deliveryHeader.appendChild(modalPrintButton);
    }
    deliverySection.appendChild(deliveryHeader);
    const deliveryContent = createElement(
      'div',
      'foodord-live-order-delivery'
    );
    const contactBlock = createElement(
      'div',
      'foodord-live-order-delivery__block'
    );
    contactBlock.appendChild(
      createElement(
        'span',
        'foodord-live-order-delivery__label',
        strings.contact || 'Contact'
      )
    );
    const contactDetails = createElement(
      'div',
      'foodord-live-order-delivery__contact'
    );
    appendContactLine(
      contactDetails,
      strings.name || 'Name',
      getCustomerName(order)
    );
    appendContactLine(
      contactDetails,
      strings.phone || 'Phone',
      text(order?.customer?.phone || order?.billing?.phone)
    );
    contactBlock.appendChild(contactDetails);
    deliveryContent.appendChild(contactBlock);

    const address = getAddress(order);
    if (address) {
      const addressBlock = createElement(
        'div',
        'foodord-live-order-delivery__block'
      );
      addressBlock.append(
        createElement(
          'span',
          'foodord-live-order-delivery__label',
          strings.address || 'Address'
        ),
        createElement('p', 'foodord-live-order-delivery__text', address)
      );
      deliveryContent.appendChild(addressBlock);
    }
    deliverySection.appendChild(deliveryContent);
    content.appendChild(deliverySection);

    const note = text(order?.customer_note || order?.note);
    if (note) {
      const noteSection = createElement(
        'section',
        'foodord-live-order-details__section foodord-live-order-details__note'
      );
      noteSection.append(
        createElement('h3', '', strings.notes || 'Notes'),
        createElement('p', '', note)
      );
      content.appendChild(noteSection);
    }

    const itemsSection = createElement(
      'section',
      'foodord-live-order-details__section'
    );
    itemsSection.appendChild(
      createElement('h3', '', strings.items || 'Items')
    );
    const itemsList = createElement('div', 'foodord-live-order-items');

    getOrderItems(order).forEach((item) => {
      const itemRow = createElement('article', 'foodord-live-order-item');
      const itemHeading = createElement(
        'div',
        'foodord-live-order-item__heading'
      );
      const quantity = positiveInteger(item?.quantity, 1);
      itemHeading.append(
        createElement(
          'span',
          'foodord-live-order-item__quantity',
          `${quantity}x`
        ),
        createElement('strong', '', text(item?.name)),
        createElement(
          'span',
          'foodord-live-order-item__price',
          formatMoney(
            item?.line_total_incl_tax ?? item?.total_incl_tax ?? item?.total,
            item?.currency || order?.currency
          )
        )
      );
      const itemMeta = createElement('div', 'foodord-live-order-item__meta');
      renderItemMeta(item, itemMeta);
      renderItemToppings(
        item,
        itemMeta,
        item?.currency || order?.currency
      );
      itemRow.appendChild(itemHeading);
      if (itemMeta.childElementCount > 0) {
        itemRow.appendChild(itemMeta);
      }
      const itemNote = text(item?.note || item?.foodord_note);
      if (itemNote) {
        itemRow.appendChild(
          createElement('p', 'foodord-live-order-item__note', itemNote)
        );
      }
      itemsList.appendChild(itemRow);
    });
    itemsSection.appendChild(itemsList);
    content.appendChild(itemsSection);

    const summary = createElement(
      'section',
      'foodord-live-order-summary'
    );
    renderOrderSummary(order, summary);
    content.appendChild(summary);
    modalBody.replaceChildren(content);
    renderModalFooter(order);
  }

  async function openOrderModal(orderId, trigger) {
    if (!modal || !modalTitle || !modalBody) {
      return;
    }

    state.activeOrderId = orderId;
    state.activeOrderDetails = null;
    setPrintButtonState({ visible: false });
    state.queuedModalOrderIds.delete(orderId);
    state.newOrderModalQueue = state.newOrderModalQueue.filter(
      (queuedOrderId) => queuedOrderId !== orderId
    );
    const requestRevision = state.modalRequestRevision + 1;
    state.modalRequestRevision = requestRevision;
    state.modalTrigger = trigger || null;
    const summaryOrder = state.orders.get(orderId);
    modalTitle.textContent = summaryOrder
      ? formatOrderNumber(summaryOrder)
      : (strings.loading || 'Loading...');
    renderSkeleton();
    modal.hidden = false;
    document.body.classList.add('foodord-live-order-modal-open');
    modal.querySelector('[data-live-modal-close]')?.focus();
    markSeen(orderId);

    try {
      const payload = await request(`/${orderId}`);
      if (
        requestRevision !== state.modalRequestRevision ||
        state.activeOrderId !== orderId
      ) {
        return;
      }
      const order = payload?.order || payload?.data || payload;
      if (!order || typeof order !== 'object') {
        throw new Error(strings.detailsError || 'Order details could not be loaded.');
      }
      modalTitle.textContent = formatOrderNumber(order);
      renderOrderDetails(order);
    } catch (error) {
      if (
        requestRevision !== state.modalRequestRevision ||
        state.activeOrderId !== orderId
      ) {
        return;
      }
      modal.classList.remove('is-loading');
      if (modalStatus) {
        modalStatus.hidden = true;
      }
      if (modalStageControls) {
        modalStageControls.hidden = true;
      }
      modalBody.replaceChildren(
        createElement(
          'p',
          'foodord-live-order-modal__error',
          error?.message || strings.detailsError || 'Order details could not be loaded.'
        )
      );
      if (modalFooter) {
        modalFooter.hidden = true;
        modalFooter.replaceChildren();
      }
      state.activeOrderDetails = null;
      setPrintButtonState({ visible: false });
    }
  }

  function closeOrderModal() {
    if (!modal || modal.hidden) {
      return;
    }

    state.modalRequestRevision += 1;
    modal.classList.add('is-closing');
    window.setTimeout(() => {
      modal.hidden = true;
      modal.classList.remove('is-closing');
      document.body.classList.remove('foodord-live-order-modal-open');
      state.modalTrigger?.focus();
      state.modalTrigger = null;
      state.activeOrderId = '';
      state.activeOrderDetails = null;
      setPrintButtonState({ visible: false });
      openNextQueuedOrder();
    }, 180);
  }

  async function confirmOrder(orderId, trigger) {
    const durationDisplay = modal?.querySelector(
      '[data-live-confirmation-duration]'
    );
    const selectionType =
      durationDisplay?.dataset.type === 'scheduled'
        ? 'scheduled'
        : 'duration';
    const selectionValue =
      selectionType === 'scheduled'
        ? text(durationDisplay?.dataset.value)
        : positiveInteger(durationDisplay?.dataset.value, 30);
    const printJob = receiptPrinter?.createJob?.() || null;
    trigger.disabled = true;
    trigger.setAttribute('aria-busy', 'true');

    try {
      const response = await request(`/${orderId}/confirmation`, {
        method: 'POST',
        body: {
          confirmed_at: new Date().toISOString(),
          selection: {
            type: selectionType,
            value: selectionValue,
          },
        },
      });
      const printableOrder = {
        ...(state.activeOrderDetails || state.orders.get(orderId) || {}),
        confirmation:
          response?.confirmation ||
          state.activeOrderDetails?.confirmation ||
          {},
        restaurant_confirmed_display:
          response?.confirmation?.confirmed_display ||
          state.activeOrderDetails?.restaurant_confirmed_display ||
          '',
        restaurant_confirmed_minutes:
          response?.confirmation?.confirmed_minutes ??
          state.activeOrderDetails?.restaurant_confirmed_minutes ??
          null,
        restaurant_confirmed_time:
          response?.confirmation?.confirmed_slot ||
          response?.confirmation?.confirmed_at ||
          state.activeOrderDetails?.restaurant_confirmed_time ||
          '',
      };
      state.activeOrderDetails = printableOrder;
      clearPendingAlert(orderId);
      try {
        await printOrder(printableOrder, printJob);
      } catch {
        showNotice(
          strings.printError ||
            'The receipt could not be prepared for printing.'
        );
      }
      closeOrderModal();
      await refreshOrders();
    } catch (error) {
      printJob?.cancel?.();
      showNotice(
        error?.message ||
          strings.updateError ||
          'The order could not be updated.'
      );
    } finally {
      trigger.disabled = false;
      trigger.removeAttribute('aria-busy');
    }
  }

  function applyActiveColumn() {
    root.querySelectorAll('[data-live-column]').forEach((column) => {
      column.classList.toggle(
        'is-mobile-active',
        column.dataset.liveColumn === state.activeColumn
      );
    });
    root.querySelectorAll('[data-live-tab]').forEach((tab) => {
      const active = tab.dataset.liveTab === state.activeColumn;
      tab.classList.toggle('is-active', active);
      tab.setAttribute('aria-pressed', active ? 'true' : 'false');
    });
  }

  function handleRootClick(event) {
    const upgradeButton = event.target.closest('[data-live-quota-upgrade]');
    if (upgradeButton) {
      const upgradeUrl = text(upgradeButton.dataset.upgradeUrl);
      if (upgradeUrl) {
        window.open(upgradeUrl, '_blank', 'noopener,noreferrer');
      }
      return;
    }

    const tab = event.target.closest('[data-live-tab]');
    if (tab) {
      state.activeColumn = tab.dataset.liveTab || 'new';
      applyActiveColumn();
      return;
    }

    const stageButton = event.target.closest('[data-order-stage]');
    if (stageButton) {
      event.stopPropagation();
      updateStage(
        text(stageButton.dataset.orderId),
        text(stageButton.dataset.orderStage),
        stageButton
      );
      return;
    }

    const card = event.target.closest('.foodord-live-order-card');
    if (card) {
      openOrderModal(text(card.dataset.orderId), card);
    }
  }

  function handleRootKeydown(event) {
    const card = event.target.closest('.foodord-live-order-card');
    if (card && (event.key === 'Enter' || event.key === ' ')) {
      event.preventDefault();
      openOrderModal(text(card.dataset.orderId), card);
    }
  }

  function handleDragStart(event) {
    const card = event.target.closest('.foodord-live-order-card');
    if (
      !card ||
      !event.dataTransfer ||
      state.stageUpdates.has(text(card.dataset.orderId))
    ) {
      event.preventDefault();
      return;
    }
    card.classList.add('is-dragging');
    event.dataTransfer.effectAllowed = 'move';
    event.dataTransfer.setData('text/plain', text(card.dataset.orderId));
  }

  function handleDragEnd(event) {
    event.target
      .closest('.foodord-live-order-card')
      ?.classList.remove('is-dragging');
    root
      .querySelectorAll('.foodord-live-orders-column.is-drag-over')
      .forEach((column) => column.classList.remove('is-drag-over'));
  }

  function handleDragOver(event) {
    const column = event.target.closest('[data-live-column]');
    if (!column || !event.dataTransfer) {
      return;
    }
    event.preventDefault();
    event.dataTransfer.dropEffect = 'move';
    column.classList.add('is-drag-over');
  }

  function handleDragLeave(event) {
    const column = event.target.closest('[data-live-column]');
    if (column && !column.contains(event.relatedTarget)) {
      column.classList.remove('is-drag-over');
    }
  }

  function handleDrop(event) {
    const column = event.target.closest('[data-live-column]');
    if (!column || !event.dataTransfer) {
      return;
    }

    event.preventDefault();
    column.classList.remove('is-drag-over');
    const orderId = text(event.dataTransfer.getData('text/plain'));
    const targetStage = text(column.dataset.liveColumn);
    const order = state.orders.get(orderId);
    if (!order || getStage(order) === targetStage) {
      return;
    }
    updateStage(orderId, targetStage);
  }

  function handleModalClick(event) {
    if (event.target.closest('[data-live-modal-close]')) {
      closeOrderModal();
      return;
    }

    if (event.target.closest('[data-live-modal-print]')) {
      printActiveOrder();
      return;
    }

    const stageButton = event.target.closest('[data-live-modal-stage]');
    if (stageButton) {
      const orderId = text(state.activeOrderId);
      const targetStage = text(stageButton.dataset.liveModalStage);
      const order = state.orders.get(orderId);
      if (order && getStage(order) !== targetStage) {
        updateStage(orderId, targetStage, stageButton);
      }
      return;
    }

    if (event.target.closest('[data-live-preparation-decrease]')) {
      adjustPreparationControl(-1);
      return;
    }

    if (event.target.closest('[data-live-preparation-increase]')) {
      adjustPreparationControl(1);
      return;
    }

    const confirmButton = event.target.closest('[data-live-confirm-order]');
    if (confirmButton) {
      confirmOrder(text(confirmButton.dataset.liveConfirmOrder), confirmButton);
    }
  }

  root.addEventListener('click', handleRootClick);
  root.addEventListener('keydown', handleRootKeydown);
  root.addEventListener('dragstart', handleDragStart);
  root.addEventListener('dragend', handleDragEnd);
  root.addEventListener('dragover', handleDragOver);
  root.addEventListener('dragleave', handleDragLeave);
  root.addEventListener('drop', handleDrop);
  modal?.addEventListener('click', handleModalClick);

  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape' && modal && !modal.hidden) {
      closeOrderModal();
    }
  });

  document.addEventListener('visibilitychange', () => {
    if (!document.hidden) {
      refreshOrders();
      return;
    }
    scheduleRefresh();
  });

  document.addEventListener('pointerdown', unlockAlertAudio, {
    capture: true,
    once: true,
  });
  document.addEventListener('keydown', unlockAlertAudio, {
    capture: true,
    once: true,
  });

  window.addEventListener('beforeunload', () => {
    if (state.refreshTimer) {
      window.clearTimeout(state.refreshTimer);
    }
    if (state.countdownTimer) {
      window.clearInterval(state.countdownTimer);
    }
    stopAlertLoop();
    alertAudio?.pause();
    state.requestController?.abort();
  });

  renderBoard(true);
  state.countdownTimer = window.setInterval(updateVisibleCountdowns, 1000);
  refreshOrders();
})();
