/**
 * Northfield Theatre — What's On Filtering & Calendar
 *
 * Client-side filtering of events by date, category, venue.
 * Calendar widget for date selection. View toggle (grid/list).
 * Mobile filter overlay. No page reload.
 *
 * @package Northfield_Theatre
 * @since 1.0.0
 */

(function () {
	'use strict';

	/* ======================================================================
	   1. STATE
	   ====================================================================== */

	var state = {
		dateFilter: 'all',
		selectedDate: null,
		categories: [],
		venues: [],
		view: 'grid',
		calendarMonth: new Date().getMonth(),
		calendarYear: new Date().getFullYear(),
	};

	var eventsData = [];
	var instanceDates = [];

	/* ======================================================================
	   2. INITIALISE
	   ====================================================================== */

	function init() {
		// Load embedded data.
		var eventsEl = document.getElementById('whats-on-events-data');
		var datesEl = document.getElementById('whats-on-instance-dates');

		if (eventsEl) {
			try { eventsData = JSON.parse(eventsEl.textContent); } catch (e) { /* ignore */ }
		}
		if (datesEl) {
			try { instanceDates = JSON.parse(datesEl.textContent); } catch (e) { /* ignore */ }
		}

		// Jump calendar to first event month if current month has no events.
		if (instanceDates.length > 0) {
			var firstDate = new Date(instanceDates[0]);
			if (!isNaN(firstDate.getTime())) {
				state.calendarMonth = firstDate.getMonth();
				state.calendarYear = firstDate.getFullYear();
			}
		}

		initDateFilters();
		initCategoryFilters();
		initVenueFilters();
		initViewToggle();
		initMobileFilters();
		initClearFilters();
		renderCalendar();
	}

	/* ======================================================================
	   3. FILTER LOGIC
	   ====================================================================== */

	function applyFilters() {
		var wrappers = document.querySelectorAll('.whats-on__event-wrapper');
		var visibleCount = 0;
		var today = new Date();
		today.setHours(0, 0, 0, 0);

		wrappers.forEach(function (wrapper) {
			var eventId = wrapper.getAttribute('data-event-id');
			var category = wrapper.getAttribute('data-category');
			var venue = wrapper.getAttribute('data-venue');
			var firstDate = wrapper.getAttribute('data-first-date');
			var lastDate = wrapper.getAttribute('data-last-date');

			var visible = true;

			// Date filter.
			if (state.dateFilter !== 'all' && firstDate) {
				var eventFirst = new Date(firstDate);
				var eventLast = lastDate ? new Date(lastDate) : eventFirst;

				if (state.dateFilter === 'today') {
					var todayStr = formatDateISO(today);
					visible = firstDate.substring(0, 10) <= todayStr && lastDate.substring(0, 10) >= todayStr;
				} else if (state.dateFilter === '7days') {
					var weekEnd = new Date(today);
					weekEnd.setDate(weekEnd.getDate() + 7);
					visible = eventFirst <= weekEnd && eventLast >= today;
				} else if (state.dateFilter === '30days') {
					var monthEnd = new Date(today);
					monthEnd.setDate(monthEnd.getDate() + 30);
					visible = eventFirst <= monthEnd && eventLast >= today;
				}
			}

			// Selected calendar date.
			if (visible && state.selectedDate) {
				var selStr = state.selectedDate;
				// Check if any instance for this event falls on the selected date.
				var eventData = eventsData.find(function (e) { return e.id === eventId; });
				if (eventData) {
					visible = eventData.firstDate.substring(0, 10) <= selStr &&
					          eventData.lastDate.substring(0, 10) >= selStr;
				}
			}

			// Category filter.
			if (visible && state.categories.length > 0) {
				visible = state.categories.indexOf(category) !== -1;
			}

			// Venue filter.
			if (visible && state.venues.length > 0) {
				visible = state.venues.indexOf(venue) !== -1;
			}

			if (visible) {
				wrapper.hidden = false;
				visibleCount++;
			} else {
				wrapper.hidden = true;
			}
		});

		// Update count.
		var countEl = document.getElementById('result-count');
		if (countEl) {
			countEl.textContent = visibleCount + (visibleCount === 1 ? ' event' : ' events');
		}

		// Show/hide no results.
		var noResults = document.getElementById('no-results');
		var grid = document.getElementById('events-grid');
		if (noResults && grid) {
			if (visibleCount === 0) {
				noResults.hidden = false;
				grid.style.display = 'none';
			} else {
				noResults.hidden = true;
				grid.style.display = '';
			}
		}
	}

	function formatDateISO(date) {
		var y = date.getFullYear();
		var m = String(date.getMonth() + 1).padStart(2, '0');
		var d = String(date.getDate()).padStart(2, '0');
		return y + '-' + m + '-' + d;
	}

	/* ======================================================================
	   4. DATE FILTER — Radio buttons
	   ====================================================================== */

	function initDateFilters() {
		var radios = document.querySelectorAll('input[name="date_filter"]');
		radios.forEach(function (radio) {
			radio.addEventListener('change', function () {
				state.dateFilter = this.value;
				state.selectedDate = null;
				applyFilters();
			});
		});
	}

	/* ======================================================================
	   5. CATEGORY FILTER — Checkboxes
	   ====================================================================== */

	function initCategoryFilters() {
		var checkboxes = document.querySelectorAll('input[name="category"]');
		checkboxes.forEach(function (cb) {
			cb.addEventListener('change', function () {
				state.categories = [];
				checkboxes.forEach(function (c) {
					if (c.checked) {
						state.categories.push(c.value);
					}
				});
				applyFilters();
			});
		});
	}

	/* ======================================================================
	   6. VENUE FILTER — Checkboxes
	   ====================================================================== */

	function initVenueFilters() {
		var checkboxes = document.querySelectorAll('input[name="venue"]');
		checkboxes.forEach(function (cb) {
			cb.addEventListener('change', function () {
				state.venues = [];
				checkboxes.forEach(function (c) {
					if (c.checked) {
						state.venues.push(c.value);
					}
				});
				applyFilters();
			});
		});
	}

	/* ======================================================================
	   7. VIEW TOGGLE — Grid / List
	   ====================================================================== */

	function initViewToggle() {
		var buttons = document.querySelectorAll('.whats-on__view-btn');
		var grid = document.getElementById('events-grid');

		buttons.forEach(function (btn) {
			btn.addEventListener('click', function () {
				var view = this.getAttribute('data-view');
				state.view = view;

				buttons.forEach(function (b) {
					b.classList.remove('whats-on__view-btn--active');
					b.setAttribute('aria-pressed', 'false');
				});
				this.classList.add('whats-on__view-btn--active');
				this.setAttribute('aria-pressed', 'true');

				if (grid) {
					if (view === 'list') {
						grid.classList.remove('event-grid', 'event-grid--3');
						grid.classList.add('whats-on__grid--list');
					} else {
						grid.classList.add('event-grid', 'event-grid--3');
						grid.classList.remove('whats-on__grid--list');
					}
				}
			});
		});
	}

	/* ======================================================================
	   8. MOBILE FILTERS — Overlay open/close
	   ====================================================================== */

	function initMobileFilters() {
		var toggle = document.getElementById('filter-toggle');
		var sidebar = document.getElementById('whats-on-sidebar');
		var close = document.getElementById('filter-close');
		var apply = document.getElementById('apply-filters');

		if (!toggle || !sidebar) return;

		function openFilters() {
			sidebar.classList.add('is-open');
			toggle.setAttribute('aria-expanded', 'true');
			document.body.classList.add('mobile-nav-open');
			if (close) close.focus();
		}

		function closeFilters() {
			sidebar.classList.remove('is-open');
			toggle.setAttribute('aria-expanded', 'false');
			document.body.classList.remove('mobile-nav-open');
			toggle.focus();
		}

		toggle.addEventListener('click', openFilters);
		if (close) close.addEventListener('click', closeFilters);
		if (apply) apply.addEventListener('click', closeFilters);

		document.addEventListener('keydown', function (e) {
			if (e.key === 'Escape' && sidebar.classList.contains('is-open')) {
				closeFilters();
			}
		});
	}

	/* ======================================================================
	   9. CLEAR FILTERS
	   ====================================================================== */

	function initClearFilters() {
		var btn = document.getElementById('clear-filters');
		if (!btn) return;

		btn.addEventListener('click', function () {
			// Reset state.
			state.dateFilter = 'all';
			state.selectedDate = null;
			state.categories = [];
			state.venues = [];

			// Reset radio buttons.
			var allRadio = document.querySelector('input[name="date_filter"][value="all"]');
			if (allRadio) allRadio.checked = true;

			// Uncheck all checkboxes.
			document.querySelectorAll('input[name="category"], input[name="venue"]').forEach(function (cb) {
				cb.checked = false;
			});

			applyFilters();
		});
	}

	/* ======================================================================
	   10. CALENDAR WIDGET
	   ====================================================================== */

	var MONTH_NAMES = [
		'January', 'February', 'March', 'April', 'May', 'June',
		'July', 'August', 'September', 'October', 'November', 'December'
	];
	var DAY_HEADERS = ['Mo', 'Tu', 'We', 'Th', 'Fr', 'Sa', 'Su'];

	function renderCalendar() {
		var container = document.getElementById('calendar-widget');
		if (!container) return;

		var year = state.calendarYear;
		var month = state.calendarMonth;

		var firstDay = new Date(year, month, 1);
		var lastDay = new Date(year, month + 1, 0);
		var startDow = (firstDay.getDay() + 6) % 7; // Monday = 0
		var daysInMonth = lastDay.getDate();

		var today = new Date();
		var todayStr = formatDateISO(today);

		// Build HTML.
		var html = '';

		// Header with month nav.
		html += '<div class="calendar-widget__header">';
		html += '<button class="calendar-widget__nav-btn" data-dir="-1" aria-label="Previous month">&larr;</button>';
		html += '<span class="calendar-widget__month">' + MONTH_NAMES[month] + ' ' + year + '</span>';
		html += '<button class="calendar-widget__nav-btn" data-dir="1" aria-label="Next month">&rarr;</button>';
		html += '</div>';

		// Day headers.
		html += '<div class="calendar-widget__grid">';
		DAY_HEADERS.forEach(function (d) {
			html += '<span class="calendar-widget__day-header">' + d + '</span>';
		});

		// Empty cells before first day.
		for (var i = 0; i < startDow; i++) {
			html += '<span class="calendar-widget__day"></span>';
		}

		// Days.
		for (var day = 1; day <= daysInMonth; day++) {
			var dateStr = year + '-' + String(month + 1).padStart(2, '0') + '-' + String(day).padStart(2, '0');
			var hasEvents = instanceDates.indexOf(dateStr) !== -1;
			var isToday = dateStr === todayStr;
			var isSelected = dateStr === state.selectedDate;

			var classes = 'calendar-widget__day calendar-widget__day--current-month';
			if (hasEvents) classes += ' calendar-widget__day--has-events';
			if (isToday) classes += ' calendar-widget__day--today';
			if (isSelected) classes += ' calendar-widget__day--selected';

			if (hasEvents) {
				html += '<button class="' + classes + '" data-date="' + dateStr + '">' + day + '</button>';
			} else {
				html += '<span class="' + classes + '">' + day + '</span>';
			}
		}

		html += '</div>';

		container.innerHTML = html;

		// Bind events.
		container.querySelectorAll('.calendar-widget__nav-btn').forEach(function (btn) {
			btn.addEventListener('click', function () {
				var dir = parseInt(this.getAttribute('data-dir'), 10);
				state.calendarMonth += dir;
				if (state.calendarMonth > 11) {
					state.calendarMonth = 0;
					state.calendarYear++;
				} else if (state.calendarMonth < 0) {
					state.calendarMonth = 11;
					state.calendarYear--;
				}
				renderCalendar();
			});
		});

		container.querySelectorAll('.calendar-widget__day--has-events').forEach(function (dayBtn) {
			dayBtn.addEventListener('click', function () {
				var date = this.getAttribute('data-date');
				if (state.selectedDate === date) {
					state.selectedDate = null;
				} else {
					state.selectedDate = date;
					state.dateFilter = 'all';
					var allRadio = document.querySelector('input[name="date_filter"][value="all"]');
					if (allRadio) allRadio.checked = true;
				}
				renderCalendar();
				applyFilters();
			});
		});
	}

	/* ======================================================================
	   11. BOOT
	   ====================================================================== */

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