(function (window, document) {
  'use strict';

  const config = window.foodordTableOrdering || null;
  if (!config || !config.token || !config.restUrl) {
    return;
  }

  const selectors = {
    checkout:
      '.wr-card__cta, .foodord-mobile-cart__checkout-btn, .foodord-mobile-cart__bottom-checkout-btn',
    addToCart:
      '.foodord-add-to-cart-btn, .add_to_cart_button, .single_add_to_cart_button, button[name="add-to-cart"], input[name="add-to-cart"], a[href*="add-to-cart="]',
  };

  const labels = Object.assign(
    {
      catalogOnly: 'This QR code is catalog only.',
      sendOrder: 'Place order',
      orderSent: 'Order sent.',
      orderFailed: 'Unable to send order.',
      orderPlacedTitle: 'Order placed successfully!',
      kitchenMessage: 'Your order has been sent to the kitchen.',
      prepareMessage: "We'll prepare your order with care.",
      continueLabel: 'Continue',
      closeLabel: 'Close',
    },
    config.i18n || {}
  );

  const SVG_NAMESPACE = 'http:' + '//www' + '.w3' + '.org/2000/svg';

  let state = {
    mode: 'invalid',
    canOrder: false,
    ready: false,
    submitting: false,
    orderSent: false,
  };

  let orderSentModal = null;

  function buildRestUrl(path) {
    return String(config.restUrl || '').replace(/\/$/, '') + path;
  }

  function buildRestHeaders(headers) {
    const requestHeaders = Object.assign({}, headers || {});
    if (config.restNonce) {
      requestHeaders['X-WP-Nonce'] = config.restNonce;
    }
    return requestHeaders;
  }

  function setOrderSentState(active) {
    state.orderSent = active === true;
    updateCheckoutLabels();
  }

  function showNotice(message, type) {
    let notice = document.querySelector('.foodord-table-ordering-notice');
    if (!notice) {
      notice = document.createElement('div');
      notice.className = 'foodord-table-ordering-notice';
      notice.setAttribute('role', 'status');
      document.body.appendChild(notice);
    }

    notice.dataset.type = type || 'info';
    notice.textContent = message;
    window.clearTimeout(showNotice.timer);
    showNotice.timer = window.setTimeout(function () {
      notice.remove();
    }, 3500);
  }

  function isDisabledButton(button) {
    return (
      !button ||
      button.disabled ||
      button.classList.contains('disabled') ||
      button.getAttribute('aria-disabled') === 'true'
    );
  }

  function blockEvent(event) {
    event.preventDefault();
    event.stopPropagation();
    if (typeof event.stopImmediatePropagation === 'function') {
      event.stopImmediatePropagation();
    }
  }

  function updateCheckoutLabels() {
    if (!state.ready) {
      return;
    }

    const checkoutLabel = state.orderSent && state.canOrder
      ? labels.orderSent
      : (state.canOrder ? labels.sendOrder : labels.catalogOnly);

    document.querySelectorAll(selectors.checkout).forEach(function (button) {
      syncCheckoutButton(button, checkoutLabel);
    });
  }

  function createCheckIcon() {
    const icon = document.createElementNS(SVG_NAMESPACE, 'svg');
    icon.setAttribute('class', 'foodord-table-ordering-cta__check');
    icon.setAttribute('viewBox', '0 0 24 24');
    icon.setAttribute('fill', 'none');
    icon.setAttribute('stroke', 'currentColor');
    icon.setAttribute('stroke-width', '2.5');
    icon.setAttribute('stroke-linecap', 'round');
    icon.setAttribute('stroke-linejoin', 'round');
    icon.setAttribute('aria-hidden', 'true');

    const path = document.createElementNS(SVG_NAMESPACE, 'path');
    path.setAttribute('d', 'M20 6 9 17l-5-5');
    icon.appendChild(path);

    return icon;
  }

  function createSvg(className, viewBox) {
    const svg = document.createElementNS(SVG_NAMESPACE, 'svg');
    svg.setAttribute('class', className);
    svg.setAttribute('viewBox', viewBox || '0 0 24 24');
    svg.setAttribute('fill', 'none');
    svg.setAttribute('stroke', 'currentColor');
    svg.setAttribute('stroke-width', '2');
    svg.setAttribute('stroke-linecap', 'round');
    svg.setAttribute('stroke-linejoin', 'round');
    svg.setAttribute('aria-hidden', 'true');
    return svg;
  }

  function appendSvgPath(svg, d) {
    const path = document.createElementNS(SVG_NAMESPACE, 'path');
    path.setAttribute('d', d);
    svg.appendChild(path);
  }

  function appendSvgLine(svg, x1, y1, x2, y2) {
    const line = document.createElementNS(SVG_NAMESPACE, 'line');
    line.setAttribute('x1', x1);
    line.setAttribute('y1', y1);
    line.setAttribute('x2', x2);
    line.setAttribute('y2', y2);
    svg.appendChild(line);
  }

  function createSuccessBadgeIcon() {
    const icon = createSvg('foodord-table-ordering-modal__success-icon', '0 0 24 24');
    appendSvgPath(icon, 'M22 11.08V12a10 10 0 1 1-5.93-9.14');
    appendSvgPath(icon, 'M22 4 12 14.01l-3-3');
    return icon;
  }

  function createPlateIcon() {
    const icon = createSvg('foodord-table-ordering-modal__plate-icon', '0 0 40 40');
    icon.setAttribute('stroke-width', '2.4');
    const circle = document.createElementNS(SVG_NAMESPACE, 'circle');
    circle.setAttribute('cx', '20');
    circle.setAttribute('cy', '20');
    circle.setAttribute('r', '10');
    icon.appendChild(circle);
    appendSvgLine(icon, '6', '9', '6', '31');
    appendSvgLine(icon, '10', '9', '10', '31');
    appendSvgLine(icon, '34', '9', '34', '31');
    appendSvgPath(icon, 'M30 9v10c0 3 2 4 4 4');
    return icon;
  }

  function createUtensilIcon() {
    const icon = createSvg('foodord-table-ordering-modal__message-icon', '0 0 24 24');
    icon.setAttribute('stroke-width', '2.2');
    appendSvgLine(icon, '4', '3', '4', '21');
    appendSvgLine(icon, '8', '3', '8', '21');
    appendSvgLine(icon, '2', '8', '10', '8');
    appendSvgPath(icon, 'M17 3v18');
    appendSvgPath(icon, 'M21 3v8a4 4 0 0 1-4 4');
    return icon;
  }

  function createClockIcon() {
    const icon = createSvg('foodord-table-ordering-modal__note-icon', '0 0 24 24');
    const circle = document.createElementNS(SVG_NAMESPACE, 'circle');
    circle.setAttribute('cx', '12');
    circle.setAttribute('cy', '12');
    circle.setAttribute('r', '9');
    icon.appendChild(circle);
    appendSvgPath(icon, 'M12 7v5l3 2');
    return icon;
  }

  function closeOrderSentModal() {
    if (!orderSentModal) {
      return;
    }
    orderSentModal.hidden = true;
    document.body.classList.remove('foodord-table-ordering-modal-open');
  }

  function handleModalKeydown(event) {
    if (event.key === 'Escape' && orderSentModal && !orderSentModal.hidden) {
      closeOrderSentModal();
    }
  }

  function createOrderSentModal() {
    const overlay = document.createElement('div');
    overlay.className = 'foodord-table-ordering-modal-overlay';
    overlay.hidden = true;

    const dialog = document.createElement('div');
    dialog.className = 'foodord-table-ordering-modal';
    dialog.setAttribute('role', 'dialog');
    dialog.setAttribute('aria-modal', 'true');
    dialog.setAttribute('aria-labelledby', 'foodord-table-ordering-modal-title');

    const header = document.createElement('div');
    header.className = 'foodord-table-ordering-modal__header';

    const closeButton = document.createElement('button');
    closeButton.type = 'button';
    closeButton.className = 'foodord-table-ordering-modal__close';
    closeButton.setAttribute('aria-label', labels.closeLabel);
    closeButton.addEventListener('click', closeOrderSentModal);

    const plateWrap = document.createElement('div');
    plateWrap.className = 'foodord-table-ordering-modal__plate';
    plateWrap.appendChild(createPlateIcon());

    const titleRow = document.createElement('div');
    titleRow.className = 'foodord-table-ordering-modal__title-row';
    titleRow.appendChild(createSuccessBadgeIcon());

    const title = document.createElement('h2');
    title.id = 'foodord-table-ordering-modal-title';
    title.className = 'foodord-table-ordering-modal__title';
    title.textContent = labels.orderPlacedTitle;
    titleRow.appendChild(title);

    header.appendChild(closeButton);
    header.appendChild(plateWrap);
    header.appendChild(titleRow);

    const body = document.createElement('div');
    body.className = 'foodord-table-ordering-modal__body';

    const message = document.createElement('div');
    message.className = 'foodord-table-ordering-modal__message';
    message.appendChild(createUtensilIcon());
    const messageText = document.createElement('p');
    messageText.textContent = labels.kitchenMessage;
    message.appendChild(messageText);

    const note = document.createElement('div');
    note.className = 'foodord-table-ordering-modal__note';
    note.appendChild(createClockIcon());
    const noteText = document.createElement('p');
    noteText.textContent = labels.prepareMessage;
    note.appendChild(noteText);

    const continueButton = document.createElement('button');
    continueButton.type = 'button';
    continueButton.className = 'foodord-table-ordering-modal__continue';
    continueButton.textContent = labels.continueLabel;
    continueButton.addEventListener('click', closeOrderSentModal);

    body.appendChild(message);
    body.appendChild(note);
    body.appendChild(continueButton);

    dialog.appendChild(header);
    dialog.appendChild(body);
    overlay.appendChild(dialog);
    overlay.addEventListener('click', function (event) {
      if (event.target === overlay) {
        closeOrderSentModal();
      }
    });

    document.body.appendChild(overlay);
    document.addEventListener('keydown', handleModalKeydown);
    return overlay;
  }

  function showOrderSentModal() {
    if (!orderSentModal) {
      orderSentModal = createOrderSentModal();
    }
    orderSentModal.hidden = false;
    document.body.classList.add('foodord-table-ordering-modal-open');

    const continueButton = orderSentModal.querySelector('.foodord-table-ordering-modal__continue');
    if (continueButton) {
      continueButton.focus();
    }
  }

  function getCheckoutLabel(button) {
    if (!button) {
      return null;
    }
    return button.querySelector('.wr-card__cta-label, .foodord-mobile-cart__title');
  }

  function syncCheckoutButton(button, checkoutLabel) {
    const label = getCheckoutLabel(button);
    if (!label) {
      return;
    }

    button.classList.add('foodord-table-ordering-cta');
    button.classList.toggle('foodord-table-ordering-cta--sent', state.orderSent && state.canOrder);

    if (label.parentNode && !button.querySelector('.foodord-table-ordering-cta__check')) {
      label.parentNode.insertBefore(createCheckIcon(), label);
    }

    if (label.textContent !== checkoutLabel) {
      label.textContent = checkoutLabel;
    }
  }

  function isLockedMode() {
    return (
      state.mode === 'online' ||
      state.mode === 'catalog' ||
      state.mode === 'invalid'
    );
  }

  function syncNavigationLock() {
    const shouldLock = isLockedMode();
    document
      .querySelectorAll('.site-branding a, .custom-logo-link, a.site-title')
      .forEach(function (link) {
        if (shouldLock) {
          link.setAttribute('aria-disabled', 'true');
          link.setAttribute('tabindex', '-1');
        } else {
          link.removeAttribute('aria-disabled');
          link.removeAttribute('tabindex');
        }
      });
  }

  function applyModeClasses() {
    document.body.classList.toggle(
      'foodord-table-ordering-catalog',
      state.mode === 'catalog'
    );
    document.body.classList.toggle(
      'foodord-table-ordering-online',
      state.mode === 'online'
    );
    document.body.classList.toggle(
      'foodord-table-ordering-invalid',
      state.mode === 'invalid'
    );
    syncNavigationLock();
    updateCheckoutLabels();
  }

  function buildClientOrderId() {
    if (window.crypto && typeof window.crypto.randomUUID === 'function') {
      return window.crypto.randomUUID();
    }
    return 'web-' + Date.now() + '-' + Math.random().toString(16).slice(2);
  }

  async function submitTableOrder() {
    if (state.submitting) {
      return;
    }

    state.submitting = true;
    setOrderSentState(false);

    try {
      const response = await window.fetch(buildRestUrl('/orders'), {
        method: 'POST',
        credentials: 'same-origin',
        headers: buildRestHeaders({
          'Content-Type': 'application/json',
        }),
        body: JSON.stringify({
          token: config.token,
          clientOrderId: buildClientOrderId(),
        }),
      });
      const payload = await response.json().catch(function () {
        return null;
      });
      if (!response.ok || !payload || payload.ok === false) {
        throw new Error((payload && payload.message) || labels.orderFailed);
      }

      setOrderSentState(true);
      showOrderSentModal();
      if (window.FoodordCard && typeof window.FoodordCard.loadCartItems === 'function') {
        window.FoodordCard.loadCartItems();
      }
      if (window.FoodordMobileCart && typeof window.FoodordMobileCart.loadData === 'function') {
        window.FoodordMobileCart.loadData();
      }
    } catch (error) {
      setOrderSentState(false);
      showNotice(error && error.message ? error.message : labels.orderFailed, 'error');
    } finally {
      state.submitting = false;
    }
  }

  function handleClick(event) {
    const checkout = event.target.closest(selectors.checkout);
    if (checkout) {
      if (!state.ready || state.mode === 'invalid') {
        blockEvent(event);
        return;
      }
      if (isDisabledButton(checkout)) {
        return;
      }
      blockEvent(event);
      if (state.canOrder) {
        submitTableOrder();
      } else {
        showNotice(labels.catalogOnly, 'info');
      }
      return;
    }

    const addToCart = event.target.closest(selectors.addToCart);
    if (addToCart && (!state.ready || state.mode === 'invalid')) {
      blockEvent(event);
      return;
    }

    if (addToCart && state.orderSent) {
      setOrderSentState(false);
    }

    if (state.mode === 'catalog' && addToCart) {
      blockEvent(event);
      showNotice(labels.catalogOnly, 'info');
      return;
    }

    if (isLockedMode()) {
      const brandingLink = event.target.closest(
        '.site-branding a, .custom-logo-link, a.site-title'
      );
      if (brandingLink) {
        blockEvent(event);
      }
    }
  }

  function markTokenInvalid() {
    state = Object.assign({}, state, {
      mode: 'invalid',
      canOrder: false,
      ready: true,
      orderSent: false,
    });
    applyModeClasses();
  }

  async function resolveToken() {
    try {
      const url = buildRestUrl('/resolve') + '?token=' + encodeURIComponent(config.token);
      const response = await window.fetch(url, {
        credentials: 'same-origin',
        headers: buildRestHeaders(),
      });
      const payload = await response.json().catch(function () {
        return null;
      });
      if (!response.ok || !payload || payload.ok === false) {
        markTokenInvalid();
        return;
      }

      state = Object.assign({}, state, {
        mode: payload.mode || 'disabled',
        canOrder: payload.canOrder === true,
        ready: true,
      });
      applyModeClasses();
    } catch {
      markTokenInvalid();
    }
  }

  function initTableOrdering() {
    document.addEventListener('click', handleClick, true);
    const observer = new MutationObserver(function () {
      syncNavigationLock();
      updateCheckoutLabels();
    });
    observer.observe(document.documentElement, {
      childList: true,
      characterData: true,
      subtree: true,
    });
    applyModeClasses();
    resolveToken();
  }

  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initTableOrdering);
  } else {
    initTableOrdering();
  }
})(window, document);
