/* global bootstrap, jQuery, SzybkaPaczkaMap */
(function () {
  'use strict';

  if (typeof window === 'undefined' || typeof document === 'undefined') {
    return;
  }

  // The carrier template now ships its own inline ParcelShop handler.
  // Keep this script as a fallback only when that handler is unavailable.
  if (window.glsPolandInlineParcelShopInit) {
    return;
  }

  var selectors = {
    modal: '#gls_poland_parcel_shop_map_modal',
    map: '#gls_poland_parcel_shop_map',
    button: '.js-gls-poland-parcel-shop-select-button',
    form: '.js-gls-poland-delivery-options-form',
    input: '.js-gls-poland-parcel-shop-input',
    info: '.js-gls-poland-parcel-shop-info-container',
    name: '.js-gls-poland-parcel-shop-name',
    address: '.js-gls-poland-parcel-shop-address'
  };

  var activeForm = null;
  var activeCarrierReferenceId = null;
  var activeCartId = null;
  var activeParcelShopType = null;

  function debug() {
    if (!window.console || typeof window.console.log !== 'function') {
      return;
    }

    var args = Array.prototype.slice.call(arguments);
    args.unshift('[GLS fallback]');
    window.console.log.apply(window.console, args);
  }

  debug('script loaded');

  function createModal() {
    debug('creating modal dynamically');

    var wrapper = document.createElement('div');
    wrapper.innerHTML =
      '<div id="gls_poland_parcel_shop_map_modal" class="modal fade" tabindex="-1" role="dialog" style="display: none;" aria-hidden="true">' +
      '  <div class="modal-dialog gls-poland-parcel-shop-map-modal modal-lg">' +
      '    <div id="gls_poland_parcel_shop_map" class="modal-content gls-poland-parcel-shop-map-modal-content"></div>' +
      '  </div>' +
      '</div>';

    document.body.appendChild(wrapper.firstChild);

    return document.querySelector(selectors.modal);
  }

  function getModal() {
    if (window.glsPolandInlineParcelShopInit) {
      return null;
    }

    var modal = document.querySelector(selectors.modal);

    if (modal) {
      if (modal.parentNode !== document.body) {
        document.body.appendChild(modal);
      }
      debug('modal found in DOM');

      return modal;
    }

    debug('modal missing in DOM');

    return createModal();
  }

  function getMap() {
    return document.querySelector(selectors.map);
  }

  function openModal(modal, onShown) {
    if (!modal) {
      debug('openModal aborted: modal is missing');
      return;
    }

    var called = false;
    var invokeWhenShown = function () {
      if (called) {
        return;
      }

      called = true;
      if (typeof onShown === 'function') {
        window.requestAnimationFrame(function () {
          window.requestAnimationFrame(onShown);
        });
      }
    };
    var isActuallyVisible = function () {
      if (!modal || !modal.isConnected) {
        return false;
      }

      var styles = window.getComputedStyle(modal);
      if (styles.display === 'none' || styles.visibility === 'hidden') {
        return false;
      }

      return modal.offsetHeight > 0 && modal.offsetWidth > 0;
    };
    var waitForVisibility = function (attemptsLeft) {
      if (called) {
        return;
      }

      if (isActuallyVisible()) {
        invokeWhenShown();
        return;
      }

      if (attemptsLeft <= 0) {
        return;
      }

      window.requestAnimationFrame(function () {
        waitForVisibility(attemptsLeft - 1);
      });
    };

    modal.addEventListener('shown.bs.modal', invokeWhenShown, { once: true });
    waitForVisibility(120);

    debug('opening modal');

    if (window.bootstrap && window.bootstrap.Modal) {
      debug('opening modal via bootstrap.Modal');
      window.bootstrap.Modal.getOrCreateInstance(modal).show();
      return;
    }

    if (window.jQuery && window.jQuery.fn && typeof window.jQuery.fn.modal === 'function') {
      debug('opening modal via jQuery.modal');
      window.jQuery(modal).modal('show');
      return;
    }

    debug('opening modal via CSS fallback');
    modal.style.display = 'block';
    modal.classList.add('show');
    window.setTimeout(invokeWhenShown, 0);
  }

  function hideModal(modal) {
    if (!modal) {
      return;
    }

    if (window.bootstrap && window.bootstrap.Modal) {
      window.bootstrap.Modal.getOrCreateInstance(modal).hide();
      return;
    }

    if (window.jQuery && window.jQuery.fn && typeof window.jQuery.fn.modal === 'function') {
      window.jQuery(modal).modal('hide');
      return;
    }

    modal.style.display = 'none';
    modal.classList.remove('show');
  }

  function initMap(zipCode) {
    var map = getMap();

    if (!map || !window.SzybkaPaczkaMap || typeof window.SzybkaPaczkaMap.init !== 'function') {
      debug('map init aborted', {
        hasMapElement: !!map,
        hasSdk: !!window.SzybkaPaczkaMap,
        hasInit: !!(window.SzybkaPaczkaMap && window.SzybkaPaczkaMap.init)
      });
      return;
    }

    var config = window.glsPolandCheckoutConfig || {};
    var options = {
      lang: config.language || 'PL',
      country_parcelshops: config.country || 'PL',
      parcel_weight: config.weight || 0.01,
      el: map.id
    };

    if (zipCode) {
      options.center_point = zipCode;
    }

    if (activeParcelShopType) {
      options.parcelshop_type = activeParcelShopType;
    }

    debug('initializing map', options);
    map.innerHTML = '';
    window.SzybkaPaczkaMap.init(options);
  }

  function updateForm(parcelShop) {
    if (!activeForm || !parcelShop) {
      debug('updateForm aborted', {
        hasActiveForm: !!activeForm,
        hasParcelShop: !!parcelShop
      });
      return;
    }

    debug('updating form with parcel shop', parcelShop);

    var input = activeForm.querySelector(selectors.input);
    var info = activeForm.querySelector(selectors.info);
    var name = activeForm.querySelector(selectors.name);
    var address = activeForm.querySelector(selectors.address);
    var button = activeForm.querySelector(selectors.button);

    if (input) {
      input.value = parcelShop.id || '';
    }

    if (name) {
      name.textContent = parcelShop.name || '';
    }

    if (address) {
      address.textContent = [parcelShop.street, parcelShop.postal_code, parcelShop.city]
        .filter(Boolean)
        .join(' ');
    }

    if (info) {
      info.style.removeProperty('display');
    }

    if (button) {
      if (parcelShop.postal_code) {
        button.setAttribute('data-zip-code', parcelShop.postal_code);
      }

      var selectedText = button.getAttribute('data-selected-text');
      if (selectedText) {
        button.textContent = selectedText;
      }
    }
  }

  function getCsrfToken() {
    if (window.prestashop && window.prestashop.static_token) {
      return window.prestashop.static_token;
    }

    if (window.static_token) {
      return window.static_token;
    }

    var meta = document.querySelector('meta[name="csrf-token"]');

    return meta ? meta.getAttribute('content') : null;
  }

  function persistParcelShop(parcelShop) {
    var routes = window.glsPolandRoutes || {};
    var token = getCsrfToken();

    if (!parcelShop || !parcelShop.id || !routes.selectParcelShop || !token || typeof window.fetch !== 'function') {
      debug('persist skipped', {
        hasParcelShop: !!parcelShop,
        parcelShopId: parcelShop && parcelShop.id,
        hasRoute: !!routes.selectParcelShop,
        hasToken: !!token,
        hasFetch: typeof window.fetch === 'function'
      });
      return Promise.resolve();
    }

    debug('persisting parcel shop', {
      parcelShopId: parcelShop.id,
      carrierReferenceId: activeCarrierReferenceId,
      cartId: activeCartId
    });
    return window.fetch(routes.selectParcelShop, {
      method: 'POST',
      credentials: 'same-origin',
      headers: {
        'Content-Type': 'application/json',
        'X-CSRF-Token': token,
        'X-Requested-With': 'XMLHttpRequest'
      },
      body: JSON.stringify({
        parcelShopId: parcelShop.id,
        carrierReferenceId: activeCarrierReferenceId,
        cartId: activeCartId || (window.glsPolandCheckoutConfig && window.glsPolandCheckoutConfig.cartId) || null
      })
    }).then(function (response) {
      debug('persist response', response.status);

      return response;
    }).catch(function () {
      debug('persist failed');
      return null;
    });
  }

  document.addEventListener('click', function (event) {
    if (window.glsPolandInlineParcelShopInit) {
      return;
    }

    var button = event.target.closest(selectors.button);
    if (!button) {
      return;
    }

    debug('button clicked', {
      text: button.textContent,
      zipCode: button.getAttribute('data-zip-code')
    });
    event.preventDefault();

    var modal = getModal();
    if (!modal) {
      debug('click aborted: modal unavailable');
      return;
    }

    activeForm = button.closest(selectors.form) || button.closest('form');
    activeCarrierReferenceId = activeForm ? activeForm.getAttribute('data-reference-id') : null;
    activeCartId = activeForm ? activeForm.getAttribute('data-cart-id') : null;
    activeParcelShopType = activeForm ? activeForm.getAttribute('data-parcelshop-type') : null;
    debug('active form resolved', {
      hasActiveForm: !!activeForm,
      carrierReferenceId: activeCarrierReferenceId,
      cartId: activeCartId,
      parcelShopType: activeParcelShopType
    });

    openModal(modal, function () {
      initMap(button.getAttribute('data-zip-code'));
    });
  });

  window.addEventListener('get_parcel_shop', function (event) {
    if (window.glsPolandInlineParcelShopInit) {
      return;
    }

    var parcelShop = event && event.target && event.target.ParcelShop && event.target.ParcelShop.selected;
    if (!parcelShop) {
      debug('get_parcel_shop received without selected point');
      return;
    }

    debug('get_parcel_shop received', parcelShop);
    updateForm(parcelShop);
    persistParcelShop(parcelShop);
    hideModal(getModal());
  });
})();

