(() => {
  'use strict';

  const config = window.calioInlineProducts;
  const root = document.querySelector('[data-calio-inline-products]');

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

  const body = root.querySelector('[data-inline-body]');
  const search = root.querySelector('[data-inline-search]');
  const sort = root.querySelector('[data-inline-sort]');
  const refresh = root.querySelector('[data-inline-refresh]');
  const loading = root.querySelector('[data-inline-loading]');
  const notice = root.querySelector('[data-inline-notice]');
  const results = root.querySelector('[data-inline-results]');
  const pageLabel = root.querySelector('[data-inline-page]');
  const previous = root.querySelector('[data-inline-prev]');
  const next = root.querySelector('[data-inline-next]');
  const modal = root.querySelector('[data-inline-modal]');
  const modalTitle = root.querySelector('[data-inline-modal-title]');
  const modalContent = root.querySelector('[data-inline-modal-content]');
  const modalClose = Array.from(root.querySelectorAll('[data-inline-modal-close]'));
  let currentPage = 1;
  let maxPages = 1;
  let searchTimer = 0;
  let lastFocused = null;

  if (!body || !search || !sort || !refresh || !loading || !notice || !results || !pageLabel || !previous || !next) {
    return;
  }

  const setNotice = (message, type = '') => {
    notice.textContent = message;
    notice.className = `calio-inline-products__notice${type ? ` is-${type}` : ''}`;
  };

  const request = async (action, data = {}) => {
    const payload = new URLSearchParams({
      action,
      nonce: config.nonce,
      ...data,
    });
    const response = await fetch(config.ajaxUrl, {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
      },
      body: payload.toString(),
    });
    const json = await response.json();

    if (!response.ok || !json.success) {
      const message = json?.data?.message || config.labels.loadFailed;
      throw new Error(message);
    }

    return json.data;
  };

  const element = (tag, className = '', text = '') => {
    const node = document.createElement(tag);
    node.className = className;
    node.textContent = text;
    return node;
  };

  const createPriceInput = (product, field) => {
    const wrapper = element('label', 'calio-inline-products__price');
    const currency = element('span', '', config.currency);
    const input = document.createElement('input');

    input.type = 'number';
    input.min = '0';
    input.step = '0.01';
    input.inputMode = 'decimal';
    input.value = product[field] || '';
    input.dataset.priceField = field;
    input.disabled = !product.editable;
    wrapper.append(currency, input);

    return wrapper;
  };

  const openModal = (product, trigger) => {
    if (!modal || !modalTitle || !modalContent) {
      return;
    }

    lastFocused = trigger;
    modalTitle.textContent = product.name;
    modalContent.innerHTML = product.description || `<p>${config.labels.noDescription}</p>`;
    modal.hidden = false;
    document.body.classList.add('calio-inline-products-modal-open');

    const closeButton = modal.querySelector('.calio-inline-products__modal-close');
    if (closeButton) {
      closeButton.focus();
    }
  };

  const closeModal = () => {
    if (!modal) {
      return;
    }

    modal.hidden = true;
    document.body.classList.remove('calio-inline-products-modal-open');
    if (lastFocused instanceof HTMLElement) {
      lastFocused.focus();
    }
  };

  const saveRow = async (row, product, button) => {
    const regular = row.querySelector('[data-price-field="regularPrice"]');
    const sale = row.querySelector('[data-price-field="salePrice"]');

    if (!(regular instanceof HTMLInputElement) || !(sale instanceof HTMLInputElement)) {
      return;
    }

    button.disabled = true;
    button.textContent = config.labels.saving;
    setNotice('');

    try {
      const data = await request(config.actions.save, {
        productId: String(product.id),
        regularPrice: regular.value,
        salePrice: sale.value,
      });

      regular.value = data.product.regularPrice || '';
      sale.value = data.product.salePrice || '';
      button.textContent = config.labels.saved;
      setNotice(data.message || config.labels.saved, 'success');
      window.setTimeout(() => {
        button.textContent = config.labels.save;
      }, 1400);
    } catch (error) {
      button.textContent = config.labels.save;
      setNotice(error instanceof Error ? error.message : config.labels.saveFailed, 'error');
    } finally {
      button.disabled = false;
    }
  };

  const createRow = (product, index) => {
    const row = document.createElement('tr');
    const productCell = document.createElement('td');
    const title = element('strong', 'calio-inline-products__product-name', product.name);
    const meta = element('span', 'calio-inline-products__product-meta', `${product.type} · #${product.id}`);
    const skuCell = element('td', '', product.sku || '—');
    const regularCell = document.createElement('td');
    const saleCell = document.createElement('td');
    const stockCell = document.createElement('td');
    const statusCell = document.createElement('td');
    const actionCell = document.createElement('td');
    const actionWrap = element('div', 'calio-inline-products__actions');
    const descriptionButton = element('button', 'button button-small', config.labels.description);
    const editLink = element('a', 'button button-small', config.labels.edit);
    const saveButton = element('button', 'button button-primary button-small', config.labels.save);
    const stock = product.stock === null ? product.stockStatus : String(product.stock);
    const status = element('span', `calio-inline-products__status is-${product.status}`, product.status);

    row.className = 'calio-inline-products__row';
    row.style.animationDelay = `${Math.min(index * 24, 280)}ms`;
    productCell.append(title, meta);
    regularCell.appendChild(createPriceInput(product, 'regularPrice'));
    saleCell.appendChild(createPriceInput(product, 'salePrice'));
    stockCell.appendChild(element('span', `calio-inline-products__stock is-${product.stockStatus}`, stock));
    statusCell.appendChild(status);

    descriptionButton.type = 'button';
    descriptionButton.addEventListener('click', () => openModal(product, descriptionButton));
    actionWrap.appendChild(descriptionButton);

    if (product.editUrl) {
      editLink.href = product.editUrl;
      actionWrap.appendChild(editLink);
    }

    if (product.editable) {
      saveButton.type = 'button';
      saveButton.addEventListener('click', () => saveRow(row, product, saveButton));
      actionWrap.appendChild(saveButton);
    } else {
      actionWrap.appendChild(element('small', 'calio-inline-products__readonly', config.labels.variableNotice));
    }

    actionCell.appendChild(actionWrap);
    row.append(productCell, skuCell, regularCell, saleCell, stockCell, statusCell, actionCell);

    return row;
  };

  const renderProducts = (products) => {
    const fragment = document.createDocumentFragment();

    products.forEach((product, index) => fragment.appendChild(createRow(product, index)));
    body.replaceChildren(fragment);

    if (products.length === 0) {
      const row = document.createElement('tr');
      const cell = element('td', 'calio-inline-products__empty', config.labels.empty);
      cell.colSpan = 7;
      row.appendChild(cell);
      body.appendChild(row);
    }
  };

  const loadProducts = async (page = 1) => {
    const [orderby, order] = sort.value.split(':');

    loading.hidden = false;
    body.setAttribute('aria-busy', 'true');
    setNotice(config.labels.loading);
    refresh.disabled = true;

    try {
      const data = await request(config.actions.list, {
        page: String(page),
        search: search.value.trim(),
        orderby: orderby || 'title',
        order: order || 'ASC',
      });

      currentPage = data.page || 1;
      maxPages = Math.max(1, data.pages || 1);
      renderProducts(data.products || []);
      results.textContent = `${data.total || 0} ${config.labels.products}`;
      pageLabel.textContent = `${config.labels.page} ${currentPage} ${config.labels.of} ${maxPages}`;
      previous.disabled = currentPage <= 1;
      next.disabled = currentPage >= maxPages;
      setNotice('');
    } catch (error) {
      renderProducts([]);
      setNotice(error instanceof Error ? error.message : config.labels.loadFailed, 'error');
    } finally {
      loading.hidden = true;
      body.removeAttribute('aria-busy');
      refresh.disabled = false;
    }
  };

  search.addEventListener('input', () => {
    window.clearTimeout(searchTimer);
    searchTimer = window.setTimeout(() => loadProducts(1), 320);
  });
  sort.addEventListener('change', () => loadProducts(1));
  refresh.addEventListener('click', () => loadProducts(currentPage));
  previous.addEventListener('click', () => {
    if (currentPage > 1) {
      loadProducts(currentPage - 1);
    }
  });
  next.addEventListener('click', () => {
    if (currentPage < maxPages) {
      loadProducts(currentPage + 1);
    }
  });
  modalClose.forEach((control) => control.addEventListener('click', closeModal));
  document.addEventListener('keydown', (event) => {
    if (event.key === 'Escape' && modal && !modal.hidden) {
      closeModal();
    }
  });

  loadProducts();
})();
