let stripe;
let elements;
let cardElement;
let clientSecret = null;
let stripeReady = false;
let paymentIntentId = null;

function initStripeIfNeeded() {
    if (stripeReady) return;

    const publicKey = cutqueue_booking_system_formData.stripePublicKey;
    if (!publicKey) {
        document.getElementById('cutqueue_booking_system_message').innerText = 'Stripe not configured';
        return;
    }

    stripe = Stripe(publicKey);
    stripeReady = true;
}

async function createPaymentIntent() {
    if (clientSecret) return { clientSecret, paymentIntentId };

    try {
        const res = await fetch(cutqueue_booking_system_formData.ajaxUrl, {
            method: 'POST',
            headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
            body: new URLSearchParams({
                action: 'cutqueue_create_intent',
                cutqueue_booking_system_store_id: cutqueue_booking_system_formData.storeId,
                cutqueue_booking_system_service_price: document.getElementById('cutqueue_booking_system_service_price').value,
                cutqueue_booking_system_nonce: cutqueue_booking_system_formData.nonce,
                cutqueue_booking_system_name: document.getElementById('cutqueue_booking_system_name').value || '',
                cutqueue_booking_system_email: document.getElementById('cutqueue_booking_system_email').value || '',
                cutqueue_booking_system_mobile: document.getElementById('cutqueue_booking_system_mobile').value || ''
            })
        });

        const data = await res.json();

        if (!data || !data.success || !data.clientSecret) {
            const serverMsg = data && data.error ? data.error : 'Failed to get clientSecret';
            throw new Error(serverMsg);
        }

        clientSecret = data.clientSecret;
        paymentIntentId = data.paymentIntentId || null;

        return { clientSecret, paymentIntentId };

    } catch (e) {
        document.getElementById('cutqueue_booking_system_message').innerText = 'Failed to prepare payment';
        console.error(e);
    }
}

function mountStripeElement() {
    if (!stripeReady) return;
    if (document.querySelector('#card-number iframe')) return;

    elements = stripe.elements({
        appearance: {
            theme: 'stripe',
            variables: {
                colorPrimary: '#635bff',
                colorBackground: '#f6f8fa',
                colorText: '#32325d',
                colorDanger: '#fa755a',
                borderRadius: '8px',
                spacingUnit: '4px',
                fontFamily: '"Helvetica Neue", Helvetica, sans-serif',
            },
            rules: {
                '.Label': { color: '#636363' },
                '.Input': { fontSize: '16px' }
            }
        }
    });

    const style = {
        base: { fontSize: '16px', color: '#32325d', '::placeholder': { color: '#a0aec0' } },
        invalid: { color: '#fa755a' }
    };

    const cardNumber = elements.create('cardNumber', { style, placeholder: '1234 1234 1234 1234', showIcon: true });
    const cardExpiry = elements.create('cardExpiry', { style, placeholder: 'MM / YY' });
    const cardCvc = elements.create('cardCvc', { style, placeholder: 'CVC' });

    cardNumber.mount('#card-number');
    cardExpiry.mount('#card-expiry');
    cardCvc.mount('#card-cvc');

    cardElement = cardNumber;
}

function resetStripe() {
    clientSecret = null;
    paymentIntentId = null;

    if (cardElement) {
        cardElement.unmount();
        cardElement = null;
    }

    elements = null;

    const num = document.getElementById('card-number');
    const exp = document.getElementById('card-expiry');
    const cvc = document.getElementById('card-cvc');

    if (num) num.innerHTML = '';
    if (exp) exp.innerHTML = '';
    if (cvc) cvc.innerHTML = '';
}

let workerSelect, dateInput, timeSelect, form, message;
let steps, nextBtns, prevBtns, progressBar, bbDate, bbTime;
let disableWorkerSelection, bookings, maxSlotsPerTime;
let bookedDates, bookedTimes;
let currentStep = 0;
let isSubmitting = false;
let serviceSelect, priceInput, summaryName, payLabel;
let totalSteps;

document.addEventListener("DOMContentLoaded", function () {
    workerSelect = document.getElementById("cutqueue_booking_system_worker");
    dateInput = document.getElementById("cutqueue_booking_system_date");
    timeSelect = document.getElementById("cutqueue_booking_system_time");
    form = document.getElementById("cutqueue-form");
    message = document.getElementById("cutqueue_booking_system_message");
    steps = document.querySelectorAll(".form-step");
    nextBtns = document.querySelectorAll(".next-step");
    prevBtns = document.querySelectorAll(".prev-step");
    progressBar = document.querySelector(".progress-bar");
    bbDate = document.getElementById('cutqueue_booking_system_date');
    bbTime = document.getElementById('cutqueue_booking_system_time');

    totalSteps = steps.length;

    bookedDates = Array.isArray(cutqueue_booking_system_formData.bookings)
        ? cutqueue_booking_system_formData.bookings.map(b => b.date).filter(Boolean)
        : [];

    bookedTimes = cutqueue_booking_system_formData.bookedTimes || {};

    if (bbDate) {
        flatpickr(bbDate, {
            dateFormat: "Y-m-d",
            minDate: "today",
            onChange: function (selectedDates, dateStr) {
                updateAvailableTimes(dateStr);
                updateTimeOptions();
            }
        });
    }

    const today = new Date();
    const yyyy = today.getFullYear();
    const mm = String(today.getMonth() + 1).padStart(2, "0");
    const dd = String(today.getDate()).padStart(2, "0");
    const todayStr = `${yyyy}-${mm}-${dd}`;
    if (!dateInput.value) dateInput.value = todayStr;
    dateInput.setAttribute("data-placeholder", "Select a date");
    dateInput.classList.add("bb-date-placeholder");
    dateInput.addEventListener("focus", () => dateInput.classList.remove("bb-date-placeholder"));
    dateInput.addEventListener("blur", () => { if (!dateInput.value) dateInput.classList.add("bb-date-placeholder"); });

    nextBtns.forEach(b => b.addEventListener("click", () => {
        const inputs = steps[currentStep].querySelectorAll("input, select, textarea");
        let valid = true;
        inputs.forEach(inp => {
            if (!inp.checkValidity()) { inp.classList.add("is-invalid"); valid = false; } else inp.classList.remove("is-invalid");
        });
        if (!valid) {
            message.innerHTML = `<div class="alert alert-danger">Please fill all required fields correctly before continuing.</div>`;
            return;
        }
        message.innerHTML = "";
        if (currentStep < steps.length - 1) { currentStep++; showStep(currentStep); }
    }));
    prevBtns.forEach(b => b.addEventListener("click", () => { if (currentStep > 0) { currentStep--; showStep(currentStep); } }));
    showStep(currentStep);

    bookings = cutqueue_booking_system_formData.bookings || [];
    let totalWorkers = cutqueue_booking_system_formData.totalWorkers || 0;
    disableWorkerSelection = cutqueue_booking_system_formData.disableWorkerSelection || false;
    const slotsPerBooking = cutqueue_booking_system_formData.slotsPerBooking || 1;
    if (!disableWorkerSelection && totalWorkers === 0) disableWorkerSelection = true;
    maxSlotsPerTime = disableWorkerSelection ? slotsPerBooking : totalWorkers;

    updateTimeOptions();

    if (workerSelect) workerSelect.addEventListener('change', updateTimeOptions);
    if (dateInput) dateInput.addEventListener('change', updateTimeOptions);

    if (cutqueue_booking_system_formData.paymentMode === 'online' || cutqueue_booking_system_formData.paymentMode === 'both') {
        serviceSelect = document.getElementById('cutqueue_booking_system_service');
        priceInput = document.getElementById('cutqueue_booking_system_service_price');
        summaryName = document.getElementById('summary-service-name');
        payLabel = document.getElementById('pay-amount-label');

        if (serviceSelect) {
            serviceSelect.addEventListener('change', updatePaymentSummary);
            updatePaymentSummary();
        }
    }

    form.addEventListener('submit', async (e) => {
        e.preventDefault();
        if (isSubmitting) return;
        isSubmitting = true;

        message.innerText = '';
        const customer_name = document.getElementById('cutqueue_booking_system_name')?.value || '';
        const customer_email = document.getElementById('cutqueue_booking_system_email')?.value || '';
        const customer_phone = document.getElementById('cutqueue_booking_system_mobile')?.value || '';

        const submitButton = form.querySelector("button[type='submit']");
        if (submitButton) submitButton.disabled = true;
        message.innerHTML = '<div class="alert alert-info">Submitting booking...</div>';

        let localPaymentIntentId = paymentIntentId;

        if (cutqueue_booking_system_formData.paymentMode === 'online' || cutqueue_booking_system_formData.paymentMode === 'both') {
            if (!clientSecret) {
                message.innerHTML = '<div class="alert alert-danger">Payment not initialized. Please reopen the payment step.</div>';
                isSubmitting = false;
                if (submitButton) submitButton.disabled = false;
                return;
            }

            const result = await stripe.confirmCardPayment(clientSecret, {
                payment_method: {
                    card: cardElement,
                    billing_details: { name: customer_name, email: customer_email, phone: customer_phone },
                }
            });

            if (result.error) {
                console.error('Stripe confirm error', result.error);
                message.innerHTML = '<div class="alert alert-danger">Your card was declined or payment failed.</div>';
                isSubmitting = false;
                if (submitButton) submitButton.disabled = false;
                return;
            }

            const paymentIntent = result.paymentIntent || result;
            if (!paymentIntent) {
                message.innerHTML = '<div class="alert alert-danger">No payment intent returned.</div>';
                isSubmitting = false;
                if (submitButton) submitButton.disabled = false;
                return;
            }

            if (paymentIntent.status !== 'succeeded') {
                message.innerHTML = `<div class="alert alert-danger">Payment not completed (status: ${paymentIntent.status}).</div>`;
                isSubmitting = false;
                if (submitButton) submitButton.disabled = false;
                return;
            }
            localPaymentIntentId = paymentIntent.id;
        }

        try {
            const baseFormData = new FormData(form);
            baseFormData.append('cutqueue_booking_system_nonce', cutqueue_booking_system_formData.nonce);
            baseFormData.append('action', 'cutqueue_booking_save');
            baseFormData.append('cutqueue_booking_system_store_id', cutqueue_booking_system_formData.storeId || '');
            baseFormData.append('cutqueue_booking_system_payment_mode', cutqueue_booking_system_formData.paymentMode || 'disabled');
            if (localPaymentIntentId) baseFormData.append('paymentIntentId', localPaymentIntentId);

            const resp = await fetch(cutqueue_booking_system_formData.ajaxUrl, { method: 'POST', body: baseFormData });
            const result = await resp.json();

            if (result.success) {
                message.innerHTML = `<div class="alert alert-success">${result.data}</div>`;
                form.reset();
                timeSelect.innerHTML = '<option value="">Select worker & date first</option>';
                currentStep = 0;
                showStep(currentStep);
                resetStripe();
            } else {
                message.innerHTML = `<div class="alert alert-danger">${result.data || 'Booking failed'}</div>`;
            }

        } catch (err) {
            console.error(err);
            message.innerHTML = '<div class="alert alert-danger">Error submitting booking</div>';
        }
        finally {
            if (submitButton) submitButton.disabled = false;
            isSubmitting = false;
        }
    });
});

function updatePaymentSummary() {
    const selectedOption = serviceSelect.options[serviceSelect.selectedIndex];
    const serviceName = selectedOption ? selectedOption.textContent : 'Selected Service';
    const price = selectedOption ? selectedOption.getAttribute('data-price') : '';
    if (priceInput) priceInput.value = price || '';
    if (summaryName) summaryName.textContent = serviceName;
    if (payLabel) payLabel.textContent = `€${price || '0.00'}`;
}

async function showStep(i) {
    steps.forEach((s, x) => s.classList.toggle("active", x === i));
    progressBar.style.width = ((i + 1) / totalSteps * 100) + "%";

    if (currentStep === 2 && i !== 2) {
        resetStripe();
    }

    if (i === 2 && (cutqueue_booking_system_formData.paymentMode === 'online' || cutqueue_booking_system_formData.paymentMode === 'both')) {
        initStripeIfNeeded();
        await createPaymentIntent();
        mountStripeElement();
    }
    
    currentStep = i;
}

function updateTimeOptions() {
    const worker = workerSelect.value;
    const date = dateInput.value;
    timeSelect.innerHTML = '<option value="">Select time</option>';
    if (!date) return;

    const [year, month, dayNum] = date.split('-').map(Number);
    const jsDate = new Date(year, month - 1, dayNum);
    const dayName = jsDate.toLocaleDateString('en-US', { weekday: 'long' });

    let start = '', end = '';
    let blocked = false;

    if (disableWorkerSelection || worker === 'any') {
        const oh = cutqueue_booking_system_formData.openingHours || {};
        if (oh[dayName]) { start = oh[dayName].start || ''; end = oh[dayName].end || ''; blocked = false;  }
    } else {
        const ws = cutqueue_booking_system_formData.workersSchedule || {};
        if (ws[worker] && ws[worker][dayName]) { start = ws[worker][dayName].start || ''; end = ws[worker][dayName].end || ''; blocked = ws[worker][dayName].enabled === true; }
    }
    if (blocked || !start || !end) { timeSelect.innerHTML = '<option value="">No available times</option>'; return; }
    const slots = generateSlots(start, end);

    const now = new Date();
    const minBookingTime = new Date(now.getTime() + 60 * 60 * 1000);
    minBookingTime.setMinutes(Math.floor(minBookingTime.getMinutes() / 30) * 30);
    minBookingTime.setSeconds(0);
    minBookingTime.setMilliseconds(0);

    const validSlots = slots.filter(s => {
        const [h, m] = s.split(':').map(Number);
        const slotTime = new Date(jsDate.getFullYear(), jsDate.getMonth(), jsDate.getDate(), h, m);
        return slotTime.getTime() >= minBookingTime.getTime();
    });

    let html = '<option value="">Select time</option>';
    validSlots.forEach(s => {
        let bookedCount;
        if (worker === 'any' || disableWorkerSelection) {
            bookedCount = bookings.filter(b => b.date === date && b.time === s).length;
        } else {
            bookedCount = bookings.filter(b => b.date === date && b.time === s && b.worker === worker).length;
        }
        const disabled = bookedCount >= maxSlotsPerTime ? 'disabled' : '';
        html += `<option value="${s}" ${disabled}>${s}${disabled ? ' (Fully booked)' : ''}</option>`;
    });
    timeSelect.innerHTML = html;
}

function generateSlots(start, end) {
    const out = [];
    if (!start || !end) return out;

    let [cH, cM] = start.split(':').map(Number);
    let [eH, eM] = end.split(':').map(Number);

    let cur = new Date(0, 0, 0, cH, cM);
    let fin = new Date(0, 0, 0, eH, eM);

    // 🔑 overnight shift
    if (fin <= cur) {
        fin.setDate(fin.getDate() + 1);
    }

    while (cur < fin) {
        out.push(cur.toTimeString().slice(0, 5));
        cur.setMinutes(cur.getMinutes() + 30);
    }

    return out;
}

function updateAvailableTimes(dateStr) {
    if (!bbTime) return;
    bbTime.innerHTML = '';

    const startHour = 9;
    const endHour = 17;
    const times = [];
    for (let h = startHour; h <= endHour; h++) {
        times.push(`${String(h).padStart(2, '0')}:00`);
        times.push(`${String(h).padStart(2, '0')}:30`);
    }

    const booked = bookedTimes[dateStr] || [];
    times.forEach(t => {
        const opt = document.createElement('option');
        opt.value = t;
        opt.textContent = t;
        if (booked.includes(t)) opt.disabled = true;
        bbTime.appendChild(opt);
    });
}
