/******/ (() => { // webpackBootstrap
/******/ 	"use strict";
/******/ 	// The require scope
/******/ 	const __webpack_require__ = {};
/******/ 	
/************************************************************************/
/******/ 	/* webpack/runtime/compat get default export */
/******/ 	(() => {
/******/ 		// getDefaultExport function for compatibility with non-harmony modules
/******/ 		__webpack_require__.n = (module) => {
/******/ 			const getter = module && module.__esModule ?
/******/ 				() => (module['default']) :
/******/ 				() => (module);
/******/ 			__webpack_require__.d(getter, { a: getter });
/******/ 			return getter;
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/define property getters */
/******/ 	(() => {
/******/ 		// define getter/value functions for harmony exports
/******/ 		__webpack_require__.d = (exports, definition) => {
/******/ 			if(Array.isArray(definition)) {
/******/ 				var i = 0;
/******/ 				while(i < definition.length) {
/******/ 					var key = definition[i++];
/******/ 					var binding = definition[i++];
/******/ 					if(!__webpack_require__.o(exports, key)) {
/******/ 						if(binding === 0) {
/******/ 							Object.defineProperty(exports, key, { enumerable: true, value: definition[i++] });
/******/ 						} else {
/******/ 							Object.defineProperty(exports, key, { enumerable: true, get: binding });
/******/ 						}
/******/ 					} else if(binding === 0) { i++; }
/******/ 				}
/******/ 			} else {
/******/ 				for(var key in definition) {
/******/ 					if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {
/******/ 						Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ 					}
/******/ 				}
/******/ 			}
/******/ 		};
/******/ 	})();
/******/ 	
/******/ 	/* webpack/runtime/hasOwnProperty shorthand */
/******/ 	(() => {
/******/ 		__webpack_require__.o = (obj, prop) => (Object.hasOwn(obj, prop))
/******/ 	})();
/******/ 	
/************************************************************************/

;// external "jQuery"
const external_jQuery_namespaceObject = window["jQuery"];
var external_jQuery_default = /*#__PURE__*/__webpack_require__.n(external_jQuery_namespaceObject);
;// ./src/js/admin-reschedule-booking.js
/**
 * Admin booking reschedule panel.
 *
 * Wraps the existing WC_Booking_Form markup rendered inside the booking details
 * meta box so staff can pick a new slot, keeping the original price.
 *
 * Mirrors the Add Booking screen (`html-create-booking-page-2.php` +
 * `booking-form.js`): the booking-form scripts handle date/time/persons/resource
 * selection and toggle the cost block, and the submit guard is a single visibility
 * check on `.wc-bookings-booking-cost`. The server (`ajax_apply_reschedule`) is
 * the source of truth for "is this a no-op", so we don't duplicate that here.
 */


external_jQuery_default()(function ($) {
  const $wrapper = $('.wc-bookings-reschedule-wrapper');
  if (!$wrapper.length) {
    return;
  }
  const $toggle = $wrapper.find('.wc-bookings-reschedule-toggle');
  const $dialog = $wrapper.find('.wc-bookings-reschedule-dialog');
  const dialog = $dialog.get(0);
  const $form = $wrapper.find('.wc-bookings-reschedule-form');
  const $cost = $wrapper.find('.wc-bookings-booking-cost');
  const $message = $wrapper.find('.wc-bookings-reschedule-message');
  const $spinner = $wrapper.find('.spinner');
  const $submit = $wrapper.find('.wc-bookings-reschedule-submit');
  const bookingId = $dialog.data('booking-id');
  const currentResource = String($dialog.data('current-resource') || '');
  const currentDuration = parseInt($dialog.data('current-duration'), 10) || 1;
  const nonce = $dialog.data('nonce');

  // `data-current-persons` is a JSON object keyed by person-type id (or "0" when the
  // product has no types). jQuery's `.data()` auto-parses JSON, but fall back to
  // `attr` + JSON.parse in case the attribute shape ever deviates from strict JSON.
  const currentPersons = function () {
    const parsed = $dialog.data('current-persons');
    if (parsed && typeof parsed === 'object') {
      return parsed;
    }
    try {
      return JSON.parse($dialog.attr('data-current-persons') || '{}');
    } catch {
      return {};
    }
  }();
  function clearPickerSelection() {
    if (window.wc_bookings_booking_form && window.wc_bookings_booking_form.wc_bookings_date_picker) {
      window.wc_bookings_booking_form.wc_bookings_date_picker.clear_selection();
    }
  }
  function closeDialog() {
    if (dialog) {
      dialog.close();
    }
    $message.empty();
    clearPickerSelection();
  }

  // Native <dialog> doesn't lock the underlying page scroll — the user can still
  // scroll the booking edit screen behind the modal. Toggle a body class so the
  // scroll is pinned for the lifetime of the dialog, regardless of how it closes
  // (button, backdrop, ESC).
  if (dialog) {
    dialog.addEventListener('close', function () {
      document.body.classList.remove('wc-bookings-reschedule-open');
    });
  }

  /**
   * Open the dialog and pre-fill inputs from the current booking.
   */
  $toggle.on('click', function () {
    if (!dialog) {
      return;
    }
    dialog.showModal();
    document.body.classList.add('wc-bookings-reschedule-open');

    // Force the datepicker open so the user sees the calendar without having to click the legend.
    $dialog.find('.picker').show();

    // The month block-picker (month-picker.js) measures each block and pins them all
    // to the largest width/height — but it runs once on document.ready, while this
    // dialog is still display:none, so every block gets pinned to 0×0 and the calendar
    // renders collapsed. Now that the dialog is laid out, clear those stale sizes and
    // re-measure so the blocks size to their content like the front-end picker.
    const $blocks = $dialog.find('.block-picker a');
    if ($blocks.length) {
      $blocks.css({
        width: '',
        height: ''
      });
      let maxWidth = 0;
      let maxHeight = 0;
      $blocks.each(function () {
        maxWidth = Math.max(maxWidth, $(this).width());
        maxHeight = Math.max(maxHeight, $(this).height());
      });
      $blocks.width(maxWidth).height(maxHeight);
    }

    // Preselect the resource dropdown.
    if (currentResource) {
      $dialog.find('#wc_bookings_field_resource').val(currentResource).trigger('change');
    }

    // Preselect the customer-defined duration so the full current range is proposed
    // by default — otherwise the duration input keeps its min value and reschedule
    // would silently shorten a multi-day booking.
    const $duration = $dialog.find('#wc_bookings_field_duration');
    if ($duration.length) {
      $duration.val(currentDuration).trigger('change');
    }

    // Preselect the persons fields to the booking's current counts. Without this the
    // inputs would sit at their min value and submitting would silently change the
    // booking's persons.
    Object.keys(currentPersons || {}).forEach(function (key) {
      const count = parseInt(currentPersons[key], 10);
      if (!(count > 0)) {
        return;
      }
      // Typed products use positive person-type ids; untyped products store under 0.
      const typeId = parseInt(key, 10);
      const selector = typeId > 0 ? '#wc_bookings_field_persons_' + typeId : '#wc_bookings_field_persons';
      const $input = $dialog.find(selector);
      if ($input.length) {
        $input.val(count).trigger('change');
      }
    });
  });
  $wrapper.on('click', '.wc-bookings-reschedule-cancel', closeDialog);

  // Close on backdrop click. Inner clicks have a different `target`, so this only fires when
  // the user clicks the dialog's outer area (the part covered by ::backdrop).
  $dialog.on('click', function (event) {
    if (event.target === dialog) {
      closeDialog();
    }
  });

  /**
   * Submit the reschedule.
   *
   * Mirrors the Add Booking submit guard (`booking-form.js` → `.add_custom_booking`):
   * only validates that the cost block has rendered without a booking-error. The
   * server returns a "no change" success when the new slot equals the current one,
   * so we don't duplicate that diff client-side.
   */
  $wrapper.on('click', '.wc-bookings-reschedule-submit', function (e) {
    e.preventDefault();
    if (!$cost.is(':visible') || $cost.find('.booking-error').is(':visible')) {
      $message.css('color', '#b32d2e').text(wc_bookings_reschedule_params.i18n_pick_slot);
      return;
    }

    // Block re-entry: disable the button for the lifetime of the request so a
    // double-click can't fire a second reschedule before the first resolves.
    $submit.prop('disabled', true);
    $spinner.addClass('is-active');
    $message.empty();

    // `$form` is a <div> (nested <form> tags would be stripped by the browser)
    // so serialize the inputs directly instead of relying on $form.serializeArray().
    // Push controls first so any inner field with the same name can't clobber them.
    const payload = [{
      name: 'action',
      value: 'wc_bookings_admin_reschedule_booking'
    }, {
      name: 'booking_id',
      value: bookingId
    }, {
      name: 'security',
      value: nonce
    }];
    // Drop `add-to-cart`: the booking form renders it for the frontend cart flow,
    // but WooCommerce core's `WC_Form_Handler::add_to_cart_action()` runs on every
    // `wp_loaded` (admin-ajax included) and would treat it as a real add-to-cart,
    // spawning a phantom in-cart booking on each reschedule.
    $form.find(':input').serializeArray().forEach(function (field) {
      if (field.name === 'add-to-cart') {
        return;
      }
      payload.push(field);
    });

    // Extract a user-facing error message from either a parsed success/failure response
    // body or a jqXHR whose HTTP status was non-2xx (the handler returns 400/403/404 for
    // validation errors and those route through jQuery's `fail`, not `done`).
    function extractErrorMessage(body) {
      if (body && body.data && body.data.message) {
        return body.data.message;
      }
      return wc_bookings_reschedule_params.i18n_generic_error;
    }
    $.post(wc_bookings_reschedule_params.ajax_url, $.param(payload)).done(function (response) {
      if (response && response.success) {
        // Keep the button disabled through to the reload — re-enabling here
        // would open a window for a second submit before the page refreshes.
        $message.css('color', '#1d7a44').text(wc_bookings_reschedule_params.i18n_success);
        window.setTimeout(function () {
          window.location.reload();
        }, 600);
        return;
      }
      // Re-enable only on a non-success response so the user can correct and retry.
      $message.css('color', '#b32d2e').text(extractErrorMessage(response));
      $submit.prop('disabled', false);
    }).fail(function (jqXHR) {
      $message.css('color', '#b32d2e').text(extractErrorMessage(jqXHR && jqXHR.responseJSON));
      $submit.prop('disabled', false);
    }).always(function () {
      $spinner.removeClass('is-active');
    });
  });
});
/******/ })()
;
//# sourceMappingURL=admin-reschedule-booking.js.map