(function () {
	'use strict';

	var config = window.niwaAdminScheduler || {};
	var i18n = config.i18n || {};

	function all(selector, context) {
		return Array.prototype.slice.call((context || document).querySelectorAll(selector));
	}

	function replaceIndex(value, collection, index) {
		if (!value) {
			return value;
		}
		return value.replace(new RegExp(collection + '\\[\\d+\\]', 'g'), collection + '[' + index + ']');
	}

	function reindexCollection(containerSelector, rowSelector, collection) {
		var container = document.querySelector(containerSelector);
		if (!container) {
			return;
		}

		all(rowSelector, container).forEach(function (row, index) {
			row.dataset.index = String(index);
			var number = row.querySelector('.niwa-scheduler-repeatable__number');
			if (number) {
				number.textContent = String(index + 1);
			}
			all('[name]', row).forEach(function (field) {
				field.name = replaceIndex(field.name, collection, index);
			});
			all('[data-field-name]', row).forEach(function (field) {
				field.dataset.fieldName = replaceIndex(field.dataset.fieldName, collection, index);
			});
		});
	}

	function clearClone(row) {
		all('input, textarea, select', row).forEach(function (field) {
			if (field.type === 'hidden') {
				return;
			}
			if (field.type === 'checkbox' || field.type === 'radio') {
				field.checked = false;
			} else if (field.tagName === 'SELECT') {
				field.selectedIndex = 0;
			} else {
				field.value = '';
			}
		});
	}

	function uniqueId(prefix) {
		return prefix + '_' + Date.now().toString(36) + Math.random().toString(36).slice(2, 7);
	}

	function memberRows() {
		return all('.niwa-scheduler-member', document.querySelector('#niwa-scheduler-members'));
	}

	function syncServiceMembers() {
		var members = memberRows().map(function (row) {
			var idField = row.querySelector('.niwa-scheduler-member-id');
			var nameField = row.querySelector('.niwa-scheduler-member-name');
			return {
				id: idField ? idField.value : '',
				name: nameField && nameField.value.trim() ? nameField.value.trim() : (i18n.unnamedMember || 'Unnamed member')
			};
		}).filter(function (member) {
			return member.id;
		});

		all('.niwa-service-member-list').forEach(function (list) {
			var selected = all('input:checked', list).map(function (field) { return field.value; });
			var service = list.closest('.niwa-scheduler-service');
			var serviceIndex = service ? service.dataset.index : '0';
			list.innerHTML = '';

			if (!members.length) {
				var empty = document.createElement('span');
				empty.className = 'niwa-scheduler-empty-inline';
				empty.textContent = i18n.addMembersFirst || 'Add team members first.';
				list.appendChild(empty);
				return;
			}

			members.forEach(function (member) {
				var label = document.createElement('label');
				label.className = 'niwa-scheduler-check';
				var input = document.createElement('input');
				input.type = 'checkbox';
				input.name = list.dataset.fieldName || ('niwa_ai_scheduler_settings[services][' + serviceIndex + '][team_member_ids][]');
				input.value = member.id;
				input.checked = selected.indexOf(member.id) !== -1;
				label.appendChild(input);
				label.appendChild(document.createTextNode(' ' + member.name));
				list.appendChild(label);
			});
		});
	}

	function addCollectionRow(button) {
		var container = document.querySelector(button.dataset.target || '');
		var rowSelector = button.dataset.row || '';
		if (!container || !rowSelector) {
			return;
		}
		var source = container.querySelector(rowSelector);
		if (!source) {
			return;
		}
		var clone = source.cloneNode(true);
		clearClone(clone);
		all('.niwa-calendar-member-controls', clone).forEach(function (controls) {
			controls.innerHTML = '<span class="niwa-field__hint">' + (i18n.saveMemberBeforeCalendar || 'Save this member and email address before sending a calendar connection.') + '</span>';
		});
		all('.niwa-scheduler-break', clone).slice(1).forEach(function (row) { row.remove(); });
		all('.niwa-member-excluded-date', clone).slice(1).forEach(function (row) { row.remove(); });
		all('.niwa-member-excluded-range', clone).slice(1).forEach(function (row) { row.remove(); });
		var idField = clone.querySelector('.niwa-scheduler-member-id, .niwa-scheduler-service-id');
		if (idField) {
			idField.value = uniqueId(idField.classList.contains('niwa-scheduler-member-id') ? 'member' : 'service');
		}
		container.appendChild(clone);
		reindexCollection(button.dataset.target, rowSelector, button.dataset.collection || '');
		reindexBreaks(clone);
		reindexLocalRows(clone);
		syncServiceMembers();
		applyDayToggles(clone);
		var focus = clone.querySelector('input:not([type="hidden"]), textarea, select');
		if (focus) {
			focus.focus();
		}
	}

	function reindexBreaks(scope) {
		all('.niwa-scheduler-day', scope || document).forEach(function (day) {
			all('.niwa-scheduler-break', day).forEach(function (row, index) {
				all('[name]', row).forEach(function (field) {
					field.name = field.name.replace(/(\[breaks\]\[[^\]]+\])\[\d+\]/g, '$1[' + index + ']');
				});
			});
		});
	}

	function reindexLocalRows(scope) {
		all('.niwa-member-excluded-ranges', scope || document).forEach(function (list) {
			all('.niwa-member-excluded-range', list).forEach(function (row, index) {
				all('[name]', row).forEach(function (field) {
					field.name = field.name.replace(/\[excluded_ranges\]\[\d+\]/g, '[excluded_ranges][' + index + ']');
				});
			});
		});
	}

	function toggleDay(day) {
		var toggle = day ? day.querySelector('.niwa-scheduler-day-enabled') : null;
		if (!toggle) {
			return;
		}
		all('input[type="time"], .niwa-scheduler-add-break, .niwa-scheduler-remove-break, .niwa-scheduler-copy-day', day).forEach(function (field) {
			field.disabled = !toggle.checked;
		});
		day.classList.toggle('is-disabled', !toggle.checked);
	}

	function applyDayToggles(scope) {
		all('.niwa-scheduler-day', scope || document).forEach(toggleDay);
	}

	function copyScheduleToNextDay(button) {
		var sourceDay = button.closest('.niwa-scheduler-day');
		var week = sourceDay ? sourceDay.closest('.niwa-scheduler-week') : null;
		if (!sourceDay || !week) {
			return;
		}
		var days = all('.niwa-scheduler-day', week);
		var index = days.indexOf(sourceDay);
		var targetDay = index >= 0 && index < days.length - 1 ? days[index + 1] : null;
		if (!targetDay) {
			return;
		}

		var sourceToggle = sourceDay.querySelector('.niwa-scheduler-day-enabled');
		var targetToggle = targetDay.querySelector('.niwa-scheduler-day-enabled');
		if (sourceToggle && targetToggle) {
			targetToggle.checked = sourceToggle.checked;
		}
		var sourceHours = all('.niwa-scheduler-day__hours input[type="time"]', sourceDay);
		var targetHours = all('.niwa-scheduler-day__hours input[type="time"]', targetDay);
		targetHours.forEach(function (field, fieldIndex) {
			field.value = sourceHours[fieldIndex] ? sourceHours[fieldIndex].value : '';
		});

		var sourceBreaks = sourceDay.querySelector('.niwa-scheduler-breaks');
		var targetBreaks = targetDay.querySelector('.niwa-scheduler-breaks');
		if (sourceBreaks && targetBreaks) {
			targetBreaks.innerHTML = sourceBreaks.innerHTML;
			var sourceKey = sourceDay.dataset.dayKey || '';
			var targetKey = targetDay.dataset.dayKey || '';
			all('[name]', targetBreaks).forEach(function (field) {
				if (sourceKey && targetKey) {
					field.name = field.name.replace('[breaks][' + sourceKey + ']', '[breaks][' + targetKey + ']');
				}
			});
			reindexBreaks(targetDay);
		}
		toggleDay(targetDay);
		targetDay.classList.remove('is-copy-highlight');
		window.requestAnimationFrame(function () {
			targetDay.classList.add('is-copy-highlight');
			window.setTimeout(function () { targetDay.classList.remove('is-copy-highlight'); }, 900);
		});
	}

	function copyUsageValue(button) {
		var value = button.dataset.copyValue || '';
		var original = button.textContent;
		var finish = function (copied) {
			button.textContent = copied ? (i18n.copied || 'Copied') : (i18n.copyFailed || 'Copy failed');
			window.setTimeout(function () { button.textContent = original; }, 1400);
		};
		var fallback = function () {
			var field = document.createElement('textarea');
			field.value = value;
			field.style.position = 'fixed';
			field.style.opacity = '0';
			document.body.appendChild(field);
			field.select();
			var copied = document.execCommand('copy');
			field.remove();
			finish(copied);
		};

		if (navigator.clipboard && navigator.clipboard.writeText) {
			navigator.clipboard.writeText(value).then(function () { finish(true); }).catch(fallback);
		} else {
			fallback();
		}
	}

	function formatCalendarTime(raw, mode) {
		var parts = String(raw || '').split(':');
		var hour = parseInt(parts[0], 10);
		var minute = parts.length > 1 ? parts[1] : '00';
		if (!Number.isFinite(hour)) {
			return raw || '';
		}
		if (mode === '24') {
			return String(hour).padStart(2, '0') + ':' + minute;
		}
		var suffix = hour >= 12 ? 'PM' : 'AM';
		var displayHour = hour % 12 || 12;
		return displayHour + (minute === '00' ? '' : ':' + minute) + ' ' + suffix;
	}

	function applyCalendarTimeMode(mode) {
		mode = mode === '24' ? '24' : '12';
		all('.niwa-calendar-time-mode').forEach(function (button) {
			var active = button.dataset.mode === mode;
			button.classList.toggle('is-active', active);
			button.setAttribute('aria-pressed', active ? 'true' : 'false');
		});
		all('.niwa-calendar-event__time[data-start-time]').forEach(function (time) {
			var start = formatCalendarTime(time.dataset.startTime, mode);
			var end = formatCalendarTime(time.dataset.endTime, mode);
			time.textContent = end ? start + ' – ' + end : start;
		});
		all('.niwa-week-calendar__time-label[data-time]').forEach(function (label) {
			label.textContent = formatCalendarTime(label.dataset.time, mode);
		});
		try {
			window.localStorage.setItem('niwa_scheduler_time_mode', mode);
		} catch (error) {
			// Storage is optional.
		}
	}

	function initCalendarTimeMode() {
		var mode = '12';
		try {
			mode = window.localStorage.getItem('niwa_scheduler_time_mode') || mode;
		} catch (error) {
			// Use the visual-reference default.
		}
		applyCalendarTimeMode(mode);
	}

	function openDetails(button) {
		var modal = document.querySelector('#niwa-contact-details-modal');
		if (!modal) {
			return;
		}
		var value = button.parentNode.querySelector('.niwa-contact-details-value');
		modal.dataset.contactId = button.dataset.contactId || '';
		modal.dataset.triggerId = button.id || '';
		modal.querySelector('textarea').value = value ? value.value : '';
		modal.querySelector('.niwa-details-status').textContent = '';
		modal.hidden = false;
		document.body.classList.add('niwa-modal-open');
		modal.querySelector('textarea').focus();
	}

	function closeDetails() {
		var modal = document.querySelector('#niwa-contact-details-modal');
		if (!modal) {
			return;
		}
		modal.hidden = true;
		document.body.classList.remove('niwa-modal-open');
		var trigger = modal.dataset.triggerId ? document.getElementById(modal.dataset.triggerId) : null;
		if (trigger) {
			trigger.focus();
		}
	}

	function saveDetails(button) {
		var modal = button.closest('#niwa-contact-details-modal');
		var textarea = modal ? modal.querySelector('textarea') : null;
		var status = modal ? modal.querySelector('.niwa-details-status') : null;
		if (!modal || !textarea || !config.ajaxUrl) {
			return;
		}
		button.disabled = true;
		if (status) {
			status.textContent = i18n.saving || 'Saving...';
		}
		var body = new URLSearchParams();
		body.append('action', 'niwa_ai_update_contact_details');
		body.append('nonce', config.nonce || '');
		body.append('contact_id', modal.dataset.contactId || '');
		body.append('details', textarea.value);

		fetch(config.ajaxUrl, {
			method: 'POST',
			credentials: 'same-origin',
			headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
			body: body.toString()
		}).then(function (response) {
			return response.json();
		}).then(function (response) {
			if (!response.success) {
				throw new Error(response.data && response.data.message ? response.data.message : (i18n.saveFailed || 'Save failed.'));
			}
			var trigger = all('.niwa-contact-details-trigger').filter(function (item) { return item.dataset.contactId === modal.dataset.contactId; })[0] || null;
			var hidden = trigger && trigger.parentNode ? trigger.parentNode.querySelector('.niwa-contact-details-value') : null;
			if (hidden) {
				hidden.value = textarea.value;
			}
			if (trigger) {
				trigger.classList.toggle('has-details', textarea.value.trim() !== '');
				trigger.textContent = textarea.value.trim() ? (i18n.editDetails || 'Edit details') : (i18n.addDetails || 'Add details');
			}
			if (status) {
				status.textContent = i18n.saved || 'Details saved.';
				status.classList.remove('is-error');
			}
		}).catch(function (error) {
			if (status) {
				status.textContent = error.message || i18n.saveFailed || 'Save failed.';
				status.classList.add('is-error');
			}
		}).finally(function () {
			button.disabled = false;
		});
	}

	function deleteContact(button) {
		if (!window.confirm(i18n.confirmDelete || 'Are you sure you want to delete this contact?')) {
			return;
		}
		var body = new URLSearchParams();
		body.append('action', 'niwa_ai_delete_contact');
		body.append('nonce', button.dataset.nonce || config.nonce || '');
		body.append('id', button.dataset.id || '');
		button.disabled = true;
		fetch(config.ajaxUrl, {
			method: 'POST',
			credentials: 'same-origin',
			headers: {'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8'},
			body: body.toString()
		}).then(function (response) { return response.json(); }).then(function (response) {
			if (!response.success) {
				throw new Error(response.data && response.data.message ? response.data.message : 'Delete failed.');
			}
			var row = button.closest('tr');
			if (row) {
				row.remove();
			}
		}).catch(function (error) {
			window.alert(error.message || 'Delete failed.');
			button.disabled = false;
		});
	}

	document.addEventListener('click', function (event) {
		var add = event.target.closest('.niwa-scheduler-add');
		var remove = event.target.closest('.niwa-scheduler-remove');
		var addBreak = event.target.closest('.niwa-scheduler-add-break');
		var removeBreak = event.target.closest('.niwa-scheduler-remove-break');
		var copyDay = event.target.closest('.niwa-scheduler-copy-day');
		var copyUsage = event.target.closest('.niwa-scheduler-copy-usage');
		var addLocal = event.target.closest('.niwa-scheduler-add-local');
		var removeLocal = event.target.closest('.niwa-scheduler-remove-local');
		var details = event.target.closest('.niwa-contact-details-trigger');
		var close = event.target.closest('[data-niwa-details-close]');
		var save = event.target.closest('.niwa-details-save');
		var deleteButton = event.target.closest('.niwa-delete-contact');
		var timeMode = event.target.closest('.niwa-calendar-time-mode');

		if (copyUsage) {
			event.preventDefault();
			copyUsageValue(copyUsage);
		} else if (add) {
			event.preventDefault();
			addCollectionRow(add);
		} else if (remove) {
			event.preventDefault();
			if (window.confirm(i18n.confirmRemove || 'Remove this item?')) {
				var row = remove.closest(remove.dataset.row || '.niwa-scheduler-repeatable');
				if (row) {
					var container = row.parentNode;
					if (container.querySelectorAll(remove.dataset.row || '.niwa-scheduler-repeatable').length > 1) {
						row.remove();
						var type = remove.dataset.collection || '';
						reindexCollection('#' + container.id, remove.dataset.row || '', type);
						syncServiceMembers();
					}
				}
			}
		} else if (addBreak) {
			event.preventDefault();
			var day = addBreak.closest('.niwa-scheduler-day');
			var breaks = day ? day.querySelector('.niwa-scheduler-breaks') : null;
			var source = breaks ? breaks.querySelector('.niwa-scheduler-break') : null;
			if (source) {
				var breakClone = source.hidden ? source : source.cloneNode(true);
				clearClone(breakClone);
				breakClone.hidden = false;
				breakClone.classList.remove('is-placeholder');
				if (breakClone !== source) {
					breaks.appendChild(breakClone);
				}
				reindexBreaks(day);
				var breakFocus = breakClone.querySelector('input[type="time"]');
				if (breakFocus) {
					breakFocus.focus();
				}
			}
		} else if (removeBreak) {
			event.preventDefault();
			var breakRow = removeBreak.closest('.niwa-scheduler-break');
			var breaksContainer = breakRow ? breakRow.parentNode : null;
			if (breaksContainer && breaksContainer.querySelectorAll('.niwa-scheduler-break').length > 1) {
				breakRow.remove();
				reindexBreaks(breaksContainer.closest('.niwa-scheduler-day'));
			} else if (breakRow) {
				clearClone(breakRow);
				breakRow.classList.add('is-placeholder');
				breakRow.hidden = true;
			}
		} else if (copyDay) {
			event.preventDefault();
			copyScheduleToNextDay(copyDay);
		} else if (addLocal) {
			event.preventDefault();
			var localScope = addLocal.closest('.niwa-scheduler-member');
			var localList = localScope ? localScope.querySelector(addLocal.dataset.list || '') : null;
			var localSource = localList ? localList.querySelector(addLocal.dataset.row || '') : null;
			if (localSource) {
				var localClone = localSource.cloneNode(true);
				clearClone(localClone);
				localList.appendChild(localClone);
				reindexLocalRows(localScope);
				var localFocus = localClone.querySelector('input');
				if (localFocus) {
					localFocus.focus();
				}
			}
		} else if (removeLocal) {
			event.preventDefault();
			var localRow = removeLocal.closest('.niwa-member-excluded-date, .niwa-member-excluded-range');
			var localContainer = localRow ? localRow.parentNode : null;
			if (localContainer && localContainer.children.length > 1) {
				localRow.remove();
				reindexLocalRows(localContainer.closest('.niwa-scheduler-member'));
			} else if (localRow) {
				clearClone(localRow);
			}
		} else if (details) {
			event.preventDefault();
			openDetails(details);
		} else if (close) {
			event.preventDefault();
			closeDetails();
		} else if (save) {
			event.preventDefault();
			saveDetails(save);
		} else if (deleteButton) {
			event.preventDefault();
			deleteContact(deleteButton);
		} else if (timeMode) {
			event.preventDefault();
			applyCalendarTimeMode(timeMode.dataset.mode || '12');
		}
	});

	document.addEventListener('input', function (event) {
		if (event.target.matches('.niwa-scheduler-member-name')) {
			syncServiceMembers();
		}
	});

	document.addEventListener('change', function (event) {
		if (event.target.matches('.niwa-scheduler-day-enabled')) {
			toggleDay(event.target.closest('.niwa-scheduler-day'));
		}
	});

	document.addEventListener('keydown', function (event) {
		if (event.key === 'Escape' && !document.querySelector('#niwa-contact-details-modal[hidden]')) {
			closeDetails();
		}
	});

	if (document.readyState === 'loading') {
			document.addEventListener('DOMContentLoaded', function () {
				syncServiceMembers();
				applyDayToggles(document);
				initCalendarTimeMode();
			});
		} else {
			syncServiceMembers();
			applyDayToggles(document);
			initCalendarTimeMode();
		}
}());
