/* Celena Shop — клиентская корзина в localStorage. */
(function () {
  'use strict';

  var STORAGE_KEY = 'celena_shop_cart';
  var STORAGE_VERSION = 1;

  function load() {
    try {
      var raw = localStorage.getItem(STORAGE_KEY);
      if (!raw) return { items: [], v: STORAGE_VERSION };
      var data = JSON.parse(raw);
      if (!data || typeof data !== 'object' || !Array.isArray(data.items)) {
        return { items: [], v: STORAGE_VERSION };
      }
      return data;
    } catch (e) {
      return { items: [], v: STORAGE_VERSION };
    }
  }

  function save(data) {
    try { localStorage.setItem(STORAGE_KEY, JSON.stringify(data)); } catch (e) {}
    window.dispatchEvent(new CustomEvent('celena:cart:changed'));
  }

  var Cart = {
    items: function () { return load().items; },
    count: function () {
      return load().items.reduce(function (s, it) { return s + (it.quantity | 0); }, 0);
    },
    total: function () {
      return load().items.reduce(function (s, it) { return s + (parseFloat(it.price) || 0) * (it.quantity | 0); }, 0);
    },
    add: function (product, qty) {
      qty = Math.max(1, qty | 0 || 1);
      var data = load();
      var pid = product.id | 0;
      var vid = product.variation_id ? (product.variation_id | 0) : 0;
      var existing = null;
      // Идентификатор строки корзины — пара (product_id, variation_id).
      // Один товар с разными вариациями — разные строки.
      for (var i = 0; i < data.items.length; i++) {
        if (data.items[i].product_id === pid && (data.items[i].variation_id | 0) === vid) {
          existing = data.items[i]; break;
        }
      }
      if (existing) {
        existing.quantity = (existing.quantity | 0) + qty;
      } else {
        data.items.push({
          product_id: pid,
          variation_id: vid,
          variation_label: String(product.variation_label || ''),
          title: String(product.title || ''),
          price: parseFloat(product.price) || 0,
          cover: String(product.cover || ''),
          sku: String(product.sku || ''),
          quantity: qty
        });
      }
      save(data);
    },
    update: function (productId, variationId, qty) {
      var data = load();
      productId = productId | 0;
      variationId = variationId | 0;
      qty = qty | 0;
      for (var i = 0; i < data.items.length; i++) {
        if (data.items[i].product_id === productId && (data.items[i].variation_id | 0) === variationId) {
          if (qty <= 0) data.items.splice(i, 1);
          else data.items[i].quantity = qty;
          break;
        }
      }
      save(data);
    },
    remove: function (productId, variationId) {
      var data = load();
      productId = productId | 0;
      variationId = variationId | 0;
      data.items = data.items.filter(function (it) {
        return !(it.product_id === productId && (it.variation_id | 0) === variationId);
      });
      save(data);
    },
    clear: function () {
      save({ items: [], v: STORAGE_VERSION });
    }
  };

  // Глобал window.CELENA_SHOP инжектится из <head> темы и содержит symbol/position
  // из настроек магазина. Если по какой-то причине не определён — фоллбэк '$'.
  function shopCfg() {
    var c = (typeof window !== 'undefined' && window.CELENA_SHOP) || {};
    return {
      symbol: c.symbol != null ? String(c.symbol) : '$',
      position: c.position === 'before' ? 'before' : 'after',
      decimals: typeof c.decimals === 'number' ? c.decimals : 2,
      thousands: c.thousands != null ? String(c.thousands) : ' ',
      decimal: c.decimal != null ? String(c.decimal) : '.'
    };
  }

  /** Числовой формат — без символа. */
  function fmt(n) {
    var cfg = shopCfg();
    n = parseFloat(n) || 0;
    var s = n.toFixed(Math.max(0, cfg.decimals));
    var parts = s.split('.');
    parts[0] = parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, cfg.thousands);
    return cfg.decimals > 0 ? parts.join(cfg.decimal) : parts[0];
  }

  /** Цена с символом — единая точка форматирования из настроек магазина. */
  function price(n) {
    var cfg = shopCfg();
    var num = fmt(n);
    if (cfg.symbol === '') return num;
    return cfg.position === 'before' ? cfg.symbol + ' ' + num : num + ' ' + cfg.symbol;
  }

  function escapeHtml(s) {
    return String(s).replace(/[&<>"']/g, function (c) {
      return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#39;' }[c];
    });
  }

  function renderWidget() {
    var root = document.querySelector('[data-cart-widget]');
    if (!root) return;
    var count = Cart.count();
    var total = Cart.total();
    root.innerHTML = '<a href="/cart" class="cart-widget">🛒 '
      + '<span class="cart-count">' + count + '</span> '
      + '<span class="cart-total">(' + price(total) + ')</span></a>';
  }

  function renderCartPage() {
    var root = document.querySelector('[data-cart-page]');
    if (!root) return;
    var items = Cart.items();
    if (items.length === 0) {
      root.innerHTML = '<div class="empty-state"><div class="icon">🛒</div>'
        + '<p>Корзина пуста.</p>'
        + '<p><a href="/shop" class="btn-primary">В магазин</a></p></div>';
      return;
    }
    var rows = '';
    var total = 0;
    items.forEach(function (it) {
      var sub = (parseFloat(it.price) || 0) * (it.quantity | 0);
      total += sub;
      var vid = (it.variation_id | 0);
      var titleHtml = escapeHtml(it.title);
      if (it.variation_label) {
        titleHtml += '<div class="cart-variation-label muted">' + escapeHtml(it.variation_label) + '</div>';
      }
      rows += '<tr data-cart-row="' + it.product_id + '-' + vid + '">'
        + '<td>' + (it.cover ? '<img src="' + escapeHtml(it.cover) + '" alt="" class="cart-thumb">' : '')
        + titleHtml + '</td>'
        + '<td>' + price(it.price) + '</td>'
        + '<td><input type="number" class="cart-qty" value="' + (it.quantity | 0)
        + '" min="0" max="999" data-cart-product="' + it.product_id + '" data-cart-variation="' + vid + '"></td>'
        + '<td data-cart-subtotal>' + price(sub) + '</td>'
        + '<td><button type="button" class="cart-del danger" title="Удалить" '
        + 'data-cart-product="' + it.product_id + '" data-cart-variation="' + vid + '">×</button></td>'
        + '</tr>';
    });
    root.innerHTML = '<table class="cart-table card">'
      + '<thead><tr><th>Товар</th><th>Цена</th><th>Кол-во</th><th>Сумма</th><th></th></tr></thead>'
      + '<tbody>' + rows + '</tbody>'
      + '<tfoot><tr><td colspan="3" style="text-align:right"><b>Итого:</b></td>'
      + '<td><b data-cart-total>' + price(total) + '</b></td><td></td></tr></tfoot>'
      + '</table>'
      + '<div class="cart-actions">'
      + '<a href="/shop" class="btn-secondary">← К покупкам</a>'
      + '<a href="/checkout" class="btn-primary">Оформить заказ →</a>'
      + '</div>';
  }

  // Состояние чекаута — обновляется при смене radio-доставки и применении промокода.
  // Используется для пересчёта итога в виджете summary справа.
  var Checkout = {
    promo: null,           // {code, type, discount, free_shipping}
    shippingId: 0,
    shippingCost: 0,
    shippingTitle: ''
  };

  function readSelectedShipping() {
    var sel = document.querySelector('input[name="shipping_method_id"]:checked');
    if (!sel) {
      Checkout.shippingId = 0;
      Checkout.shippingCost = 0;
      Checkout.shippingTitle = '';
      return;
    }
    Checkout.shippingId = parseInt(sel.value, 10) || 0;
    Checkout.shippingCost = parseFloat(sel.getAttribute('data-cost')) || 0;
    var label = sel.closest('label');
    var titleEl = label && label.querySelector('.bz-radio__title, .cm-radio__title');
    Checkout.shippingTitle = titleEl ? titleEl.textContent.trim() : '';
  }

  function renderCheckoutSummary() {
    var root = document.querySelector('[data-checkout-summary]');
    if (!root) return;
    var items = Cart.items();
    if (items.length === 0) {
      root.innerHTML = '<p class="muted">Корзина пуста. <a href="/shop">В магазин →</a></p>';
      return;
    }
    readSelectedShipping();

    var rows = '';
    var subtotal = 0;
    items.forEach(function (it) {
      var sub = (parseFloat(it.price) || 0) * (it.quantity | 0);
      subtotal += sub;
      var label = it.variation_label ? ' <span class="muted">(' + escapeHtml(it.variation_label) + ')</span>' : '';
      rows += '<tr><td>' + escapeHtml(it.title) + label + ' × ' + (it.quantity | 0) + '</td>'
        + '<td style="text-align:right">' + price(sub) + '</td></tr>';
    });

    // Применённый промокод и итоговая стоимость доставки.
    var discount = 0;
    var shippingCost = Checkout.shippingCost;
    if (Checkout.promo) {
      if (Checkout.promo.free_shipping) {
        shippingCost = 0;
      } else if (typeof Checkout.promo.discount === 'number') {
        discount = Math.min(subtotal, Checkout.promo.discount);
      }
    }
    var grandTotal = Math.max(0, subtotal - discount + shippingCost);

    var summary = '';
    summary += '<tr><td>Сумма товаров</td><td style="text-align:right">' + price(subtotal) + '</td></tr>';
    if (Checkout.shippingId > 0) {
      summary += '<tr><td>Доставка' + (Checkout.shippingTitle ? ' <span class="muted">(' + escapeHtml(Checkout.shippingTitle) + ')</span>' : '') + '</td>'
        + '<td style="text-align:right">' + (shippingCost > 0 ? price(shippingCost) : '<span class="muted">бесплатно</span>') + '</td></tr>';
    }
    if (discount > 0) {
      summary += '<tr><td>Скидка' + (Checkout.promo && Checkout.promo.code ? ' <span class="muted">(' + escapeHtml(Checkout.promo.code) + ')</span>' : '') + '</td>'
        + '<td style="text-align:right;color:#166534">−' + price(discount) + '</td></tr>';
    }

    var prevTotal = root.getAttribute('data-prev-total');
    var nextTotal = price(grandTotal);
    root.innerHTML = '<table class="cart-table"><tbody>' + rows
      + '<tr><td colspan="2" style="border-bottom:1px solid var(--bunzo-border, #e5e7eb)"></td></tr>'
      + summary
      + '<tr><td><b>Итого</b></td>'
      + '<td style="text-align:right"><b data-bz-grand>' + nextTotal + '</b></td></tr>'
      + '</tbody></table>';
    root.setAttribute('data-prev-total', nextTotal);
    if (prevTotal && prevTotal !== nextTotal) {
      var bump = root.querySelector('[data-bz-grand]');
      if (bump) {
        void bump.offsetWidth;
        bump.classList.add('bz-total--bump');
      }
    }
  }

  function renderAll() {
    renderWidget();
    renderCartPage();
    renderCheckoutSummary();
  }

  function showToast(msg) {
    var t = document.createElement('div');
    t.className = 'shop-toast';
    t.textContent = msg;
    document.body.appendChild(t);
    requestAnimationFrame(function () { t.classList.add('show'); });
    setTimeout(function () {
      t.classList.remove('show');
      setTimeout(function () { t.remove(); }, 300);
    }, 1800);
  }

  function onClick(e) {
    var addBtn = e.target.closest('[data-add-to-cart]');
    if (addBtn) {
      e.preventDefault();
      if (addBtn.disabled) return;
      var product = {
        id: parseInt(addBtn.getAttribute('data-pid'), 10) || 0,
        title: addBtn.getAttribute('data-ptitle') || '',
        price: parseFloat(addBtn.getAttribute('data-pprice')) || 0,
        cover: addBtn.getAttribute('data-pcover') || '',
        sku: addBtn.getAttribute('data-psku') || '',
        variation_id: parseInt(addBtn.getAttribute('data-variation-id'), 10) || 0,
        variation_label: addBtn.getAttribute('data-variation-label') || ''
      };
      if (product.id <= 0) return;
      var qty = 1;
      var scope = addBtn.closest('.add-to-cart') || addBtn.parentElement;
      if (scope) {
        var qtyInput = scope.querySelector('input[name="quantity"], [data-add-qty], [data-qty]');
        if (qtyInput) qty = Math.max(1, parseInt(qtyInput.value, 10) || 1);
      }
      Cart.add(product, qty);
      showToast('Добавлено в корзину');
      return;
    }
    var delBtn = e.target.closest('.cart-del');
    if (delBtn) {
      Cart.remove(
        parseInt(delBtn.getAttribute('data-cart-product'), 10) || 0,
        parseInt(delBtn.getAttribute('data-cart-variation'), 10) || 0
      );
      return;
    }
  }

  function onChange(e) {
    if (e.target && e.target.matches && e.target.matches('.cart-qty')) {
      var id = parseInt(e.target.getAttribute('data-cart-product'), 10) || 0;
      var vid = parseInt(e.target.getAttribute('data-cart-variation'), 10) || 0;
      var qty = Math.max(0, parseInt(e.target.value, 10) || 0);
      Cart.update(id, vid, qty);
    }
  }

  function attachCheckoutForm() {
    var form = document.querySelector('form[data-checkout-form]');
    if (!form) return;
    form.addEventListener('submit', function (ev) {
      var items = Cart.items();
      if (items.length === 0) {
        ev.preventDefault();
        showToast('Корзина пуста.');
        setTimeout(function () { window.location.href = '/shop'; }, 900);
        return;
      }
      var hidden = form.querySelector('input[name="cart"]');
      if (!hidden) {
        hidden = document.createElement('input');
        hidden.type = 'hidden';
        hidden.name = 'cart';
        form.appendChild(hidden);
      }
      hidden.value = JSON.stringify(items.map(function (it) {
        return {
          product_id: it.product_id,
          variation_id: (it.variation_id | 0),
          variation_label: it.variation_label || '',
          price: parseFloat(it.price) || 0,
          quantity: it.quantity
        };
      }));
    });

    // Смена способа доставки → перерисовать summary с новой стоимостью.
    form.addEventListener('change', function (e) {
      if (e.target && e.target.matches && e.target.matches('input[name="shipping_method_id"]')) {
        renderCheckoutSummary();
      }
    });
  }

  function csrfToken() {
    var meta = document.querySelector('meta[name="csrf-token"]');
    if (meta) return meta.getAttribute('content') || '';
    var inp = document.querySelector('input[name="_csrf"]');
    return inp ? (inp.value || '') : '';
  }

  function setPromoStatus(el, kind, text) {
    if (!el) return;
    el.hidden = false;
    // Снимаем все наши модификаторы, выставляем нужные. Базовые классы
    // (bz-promo__status / cm-checkout-promo__status) остаются — они зашиты в шаблоне темы.
    el.classList.remove('is-ok', 'is-err', 'cm-checkout-promo__status--ok', 'cm-checkout-promo__status--err');
    if (kind === 'ok')  el.classList.add('is-ok',  'cm-checkout-promo__status--ok');
    if (kind === 'err') el.classList.add('is-err', 'cm-checkout-promo__status--err');
    el.textContent = text;
  }

  function attachPromoApply() {
    var btn = document.querySelector('[data-promo-apply]');
    var input = document.querySelector('[data-promo-input]');
    var status = document.querySelector('[data-promo-status]');
    if (!btn || !input) return;

    function compute() {
      var subtotal = Cart.items().reduce(function (s, it) {
        return s + (parseFloat(it.price) || 0) * (it.quantity | 0);
      }, 0);
      return subtotal;
    }

    btn.addEventListener('click', function () {
      var code = (input.value || '').trim().toUpperCase();
      input.value = code;
      if (code === '') {
        setPromoStatus(status, 'err', 'Введите промокод.');
        return;
      }
      btn.disabled = true;
      var origText = btn.textContent;
      btn.textContent = '…';
      var fd = new FormData();
      fd.append('_csrf', csrfToken());
      fd.append('code', code);
      fd.append('subtotal', String(compute()));
      fetch('/checkout/promo-check', { method: 'POST', body: fd, credentials: 'same-origin' })
        .then(function (r) { return r.json().catch(function () { return { ok: false, message: 'Ошибка ответа сервера.' }; }); })
        .then(function (data) {
          if (data && data.ok) {
            Checkout.promo = {
              code: data.code,
              type: data.type,
              discount: parseFloat(data.discount) || 0,
              free_shipping: !!data.free_shipping
            };
            setPromoStatus(status, 'ok', data.message || 'Промокод принят.');
            renderCheckoutSummary();
            var evt = new CustomEvent('celena:promo:changed', { detail: { promo: Checkout.promo } });
            window.dispatchEvent(evt);
            document.dispatchEvent(evt);
          } else {
            Checkout.promo = null;
            setPromoStatus(status, 'err', (data && data.message) || 'Промокод не принят.');
            renderCheckoutSummary();
            var evt = new CustomEvent('celena:promo:changed', { detail: { promo: Checkout.promo } });
            window.dispatchEvent(evt);
            document.dispatchEvent(evt);
          }
        })
        .catch(function () {
          setPromoStatus(status, 'err', 'Сервер недоступен. Попробуйте позже.');
        })
        .then(function () {
          btn.disabled = false;
          btn.textContent = origText;
        });
    });

    // Если поле очистили — снимаем применённый промокод.
    input.addEventListener('input', function () {
      if (input.value.trim() === '' && Checkout.promo) {
        Checkout.promo = null;
        if (status) { status.hidden = true; status.textContent = ''; }
        renderCheckoutSummary();
        var evt = new CustomEvent('celena:promo:changed', { detail: { promo: null } });
        window.dispatchEvent(evt);
        document.dispatchEvent(evt);
      }
    });
  }

  function init() {
    document.addEventListener('click', onClick);
    document.addEventListener('change', onChange);
    window.addEventListener('celena:cart:changed', renderAll);
    window.addEventListener('storage', function (e) {
      if (e.key === STORAGE_KEY) renderAll();
    });
    // Async-блоки загружаются после DOMContentLoaded — перерисовать виджет,
    // когда контейнер появится в DOM.
    document.addEventListener('celena:loaded', function () { renderWidget(); });
    attachCheckoutForm();
    attachPromoApply();
    renderAll();
    if (window.CELENA_CART_CLEAR) Cart.clear();
  }

  if (document.readyState !== 'loading') init();
  else document.addEventListener('DOMContentLoaded', init);

  window.Celena = window.Celena || {};
  window.Celena.Shop = {
    cart: Cart,
    checkout: Checkout,
    rerender: renderAll
  };
  // Публичный API форматирования для тем — единый источник числа/символа.
  window.CelenaShop = { price: price, fmt: fmt };
})();
