/**
 * FormForge Calendar Picker Field
 *
 * Loads available time slots from Google Calendar via Forge API.
 * User selects a date → AJAX fetches free/busy → renders available slots.
 */
(function () {
    'use strict';

    document.addEventListener('DOMContentLoaded', function () {
        var containers = document.querySelectorAll('.formforge-calendar-picker');
        if (!containers.length) return;

        containers.forEach(function (container) {
            var fieldName = container.dataset.fieldName;
            var slotDuration = parseInt(container.dataset.slotDuration, 10) || 30;
            var workStart = parseInt(container.dataset.workStart, 10) || 9;
            var workEnd = parseInt(container.dataset.workEnd, 10) || 17;
            var availableDays = parseAvailableDays(container.dataset.availableDays || '');

            var dateInput = container.querySelector('.formforge-calendar-date');
            var slotsDiv = document.getElementById(fieldName + '_slots');
            var hiddenInput = document.getElementById(fieldName);

            if (!dateInput || !slotsDiv || !hiddenInput) return;

            dateInput.addEventListener('change', function () {
                var date = this.value;
                if (!date) {
                    slotsDiv.style.display = 'none';
                    return;
                }

                slotsDiv.style.display = 'block';
                if (!isDateAllowed(date, availableDays)) {
                    renderSlots([], slotsDiv, hiddenInput, date);
                    return;
                }

                slotsDiv.innerHTML = '<p style="color:#64748b;font-size:14px;">Loading available times...</p>';

                // Fetch available slots via AJAX → Forge API
                var formData = new FormData();
                formData.append('action', 'formforge_calendar_slots');
                formData.append('nonce', document.querySelector('[name="formforge_nonce"]').value);
                formData.append('date', date);
                formData.append('slot_duration', slotDuration);
                formData.append('work_start', workStart);
                formData.append('work_end', workEnd);
                formData.append('form_id', document.querySelector('[name="formforge_form_id"]').value);

                var ajaxUrl = window.formforgeFront ? window.formforgeFront.ajaxUrl : '/wp-admin/admin-ajax.php';

                fetch(ajaxUrl, { method: 'POST', body: formData })
                    .then(function (r) { return r.json(); })
                    .then(function (res) {
                        if (!res.success || !res.data || !res.data.slots) {
                            slotsDiv.innerHTML = '<p style="color:#64748b;font-size:14px;">No available times for this date.</p>';
                            return;
                        }

                        renderSlots(filterSlots(res.data.slots, date, workStart, workEnd, availableDays), slotsDiv, hiddenInput, date);
                    })
                    .catch(function () {
                        // Fallback: generate time slots locally without calendar check
                        var slots = generateLocalSlots(date, workStart, workEnd, slotDuration);
                        renderSlots(filterSlots(slots, date, workStart, workEnd, availableDays), slotsDiv, hiddenInput, date);
                    });
            });
        });
    });

    function parseAvailableDays(value) {
        if (!value) return [];
        return String(value).split(',').map(function (part) {
            return parseInt(part, 10);
        }).filter(function (day) {
            return day >= 1 && day <= 7;
        });
    }

    function isoDayForDate(date) {
        var parsed = new Date(date + 'T00:00:00');
        if (isNaN(parsed.getTime())) return 0;
        var day = parsed.getDay();
        return day === 0 ? 7 : day;
    }

    function isDateAllowed(date, availableDays) {
        if (!availableDays || !availableDays.length) return true;
        return availableDays.indexOf(isoDayForDate(date)) >= 0;
    }

    function clockMinutes(value) {
        var match = String(value || '').match(/^(\d{1,2}):(\d{2})/);
        if (!match) return null;
        var hours = parseInt(match[1], 10);
        var minutes = parseInt(match[2], 10);
        if (hours < 0 || hours > 23 || minutes < 0 || minutes > 59) return null;
        return hours * 60 + minutes;
    }

    function slotLocalLabel(slot) {
        if (typeof slot === 'object' && slot && slot.local_start) {
            return String(slot.local_start);
        }
        if (typeof slot === 'string') {
            return slot;
        }
        if (typeof slot === 'object' && slot && slot.start) {
            var time = new Date(slot.start);
            if (!isNaN(time.getTime())) {
                return time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
            }
        }
        return String(slot || '');
    }

    function filterSlots(slots, date, workStart, workEnd, availableDays) {
        if (!Array.isArray(slots) || !isDateAllowed(date, availableDays)) return [];
        var min = workStart * 60;
        var max = workEnd * 60;
        return slots.filter(function (slot) {
            var minutes = clockMinutes(slotLocalLabel(slot));
            return minutes !== null && minutes >= min && minutes < max;
        });
    }

    function renderSlots(slots, container, hiddenInput, date) {
        // Clear previous content safely.
        while (container.firstChild) container.removeChild(container.firstChild);

        if (!slots.length) {
            var p = document.createElement('p');
            p.style.cssText = 'color:#64748b;font-size:14px;';
            p.textContent = 'No available times for this date.';
            container.appendChild(p);
            return;
        }

        var wrap = document.createElement('div');
        wrap.style.cssText = 'display:flex;flex-wrap:wrap;gap:6px;';

        slots.forEach(function (slot) {
 // v3: full TZ-aware flow. The worker's slot.start is a
            // UTC ISO instant (e.g. "2026-04-30T00:00:00.000Z"). We render
            // the LABEL in the visitor's browser timezone — so a UTC+7
            // visitor sees "07:00" for a 00:00Z slot — and we submit the
            // raw UTC ISO as the hidden value. The PHP submit handler
            // parses that as a real UTC moment (no double TZ shift) and
            // hands it to Google with a `Z` suffix so Google records the
            // same instant; Google then re-displays it in the calendar
            // owner's display TZ. local_start (form's wall-clock) kept as
            // a fallback for legacy worker responses; once the deploy is
            // out, slot.start path always wins.
            var label, value;
            if (typeof slot === 'object' && slot && slot.start) {
                var time = new Date(slot.start);
                if (!isNaN(time.getTime())) {
                    label = time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' });
                    value = time.toISOString(); // canonical UTC ISO with Z
                } else if (slot.local_start) {
                    label = slot.local_start;
                    value = date + 'T' + slot.local_start;
                }
            } else if (typeof slot === 'object' && slot && slot.local_start) {
                label = slot.local_start;
                value = date + 'T' + slot.local_start;
            } else {
                label = String(slot);
                value = date + 'T' + String(slot);
            }

            var btn = document.createElement('button');
            btn.type = 'button';
            btn.className = 'formforge-slot-btn';
            btn.dataset.value = value;
            btn.style.cssText = 'padding:8px 14px;border:1.5px solid #e2e8f0;border-radius:8px;background:#fff;font-size:14px;color:#1e293b;cursor:pointer;transition:all 0.2s;';
            btn.textContent = label;
            wrap.appendChild(btn);
        });
        container.appendChild(wrap);

        // Click handlers
        container.querySelectorAll('.formforge-slot-btn').forEach(function (btn) {
            btn.addEventListener('click', function () {
                // Deselect all
                container.querySelectorAll('.formforge-slot-btn').forEach(function (b) {
                    b.style.borderColor = '#e2e8f0';
                    b.style.background = '#fff';
                    b.style.color = '#1e293b';
                });
                // Select this
                this.style.borderColor = '#3B82F6';
                this.style.background = '#EFF6FF';
                this.style.color = '#3B82F6';
                hiddenInput.value = this.dataset.value;
            });
        });
    }

    function generateLocalSlots(date, workStart, workEnd, slotDuration) {
        var slots = [];
        for (var h = workStart; h < workEnd; h++) {
            for (var m = 0; m < 60; m += slotDuration) {
                if (h === workEnd - 1 && m + slotDuration > 60) break;
                var time = String(h).padStart(2, '0') + ':' + String(m).padStart(2, '0');
                slots.push(time);
            }
        }
        return slots;
    }
})();
