import {Constants} from './constants';
import {Config} from '../../config';
import $ from 'jquery';
import {TicketValidation} from './ticket_validation';
import {Components} from './component';
// const moment = require('moment');
// import Moment from "moment";
const moment = require('moment-timezone');

export class Helpers {
    static getEventDisplayName = (eventDetails) => {
        return eventDetails?.display_name ?? null;
    }

    static getEventBannerImage = (eventDetails, index = 0) => {
        const bannerImage = eventDetails?.banner?.[index]?.image ? Config.EB_BASE_URL + '/' + eventDetails?.banner?.[index]?.image : null;
        return bannerImage;
    }

    static getDefaultImagePath() {
        return 'uploads/_default/events/default-thumb-old.jpg';
    }

    static getImageFullUrl = (url) => {
        if (!url) {
            return '';
        }

        return Config.EB_BASE_URL + '/' + url;
    }

    static getEventFallbackImage = () => {
        const fallbackImage = require('../images/404.png')
        return fallbackImage;
    }

    static getFullPath = (path) => {
        const fallbackImage = require('../' + path)
        return fallbackImage;
    }

    static getEventDescription = (eventDetails) => {
        return eventDetails?.description ?? '';
    }

    static getEventMinTicketPrice = (eventDetails) => {
        // To-Do calculate ticket price
        return 'AUD 46';
    }

    static getEventStartForCheckoutSummary = (eventDetails, ticketData) => {

        function formatDateTime(dateStr, timezone) {
            return moment.tz(dateStr, timezone).format('ddd, MMM DD, YYYY h:mm A (z)');
        }

        if (ticketData?.occurrence_uuid && !ticketData?.timeslot_uuid) {
            const eventStartDateTime = formatDateTime(ticketData?.event_start_on, eventDetails?.timezone);
            return eventStartDateTime;

        } else if (ticketData?.timeslot_uuid && ticketData?.occurrence_uuid) {
            const timeslots = eventDetails?.event_occurrence?.find((slot) => slot?.uuid == ticketData?.occurrence_uuid)?.timeslots;
            const startTime = timeslots?.find((slot) => slot?.uuid == ticketData?.timeslot_uuid)?.start_time?.local;
            const eventStartDateTime = formatDateTime(startTime, eventDetails?.timezone);
            return eventStartDateTime;

        } else {
            const eventStartDateTime = formatDateTime(eventDetails?.occurrence?.attributes?.starts_on?.local, eventDetails?.timezone);
            return eventStartDateTime;
        }

    }

    static addTimeWithDate(dateTimeString, amount = "", unit = "minutes") {
        let dateTime = moment.utc(dateTimeString, "YYYY-MM-DD HH:mm");

        if (!amount || !unit) {
            return dateTime;
        }

        return dateTime.add(amount, unit);
    }

    static convertToVisitorDateTime(dateTime, timezone = "Australia/Melbourne", format = 'ddd, MMM DD, YYYY h:mm A', hideAbbr = false, onlyAbbr = false) {
        let datetime = moment.utc(dateTime, "YYYY-MM-DD HH:mm").tz(timezone);

        let tzAbbr = "";
        if (format.indexOf('_notz_') > -1) {
            format = format.replace('_notz_', '');
            tzAbbr = '';
        } else {
            //compare first 3 letters to check if abbr available!
            let t1 = datetime.format('Z'); //'+06:30'
            let t2 = datetime.format('z'); //'+06'|PDT|AEST|IST
            tzAbbr = (t1.substring(0, 3) === t2.substring(0, 3)) ? ' (' + t1 + ' GMT)' : ' (' + t2 + ')';
        }

        if (hideAbbr) {
            tzAbbr = '';
        }

        if (onlyAbbr) {
            return tzAbbr;
        } else {
            return datetime.format(format) + tzAbbr;
        }
    }

    static displayDuration(duration) {
        // Define time units in terms of minutes
        const minutesInAnHour = 60;
        const minutesInADay = 24 * minutesInAnHour;
        let durationInMinutes = 0;

        // Convert hours and minutes to total minutes
        if (duration.hours > 0) {
            durationInMinutes = duration.hours * minutesInAnHour;
        }
        if (duration.minutes > 0) {
            durationInMinutes += duration.minutes;
        }

        // Calculate days
        const days = Math.floor(durationInMinutes / minutesInADay);
        let remainingMinutes = durationInMinutes % minutesInADay;

        // Calculate hours
        const hours = Math.floor(remainingMinutes / minutesInAnHour);
        const minutes = remainingMinutes % minutesInAnHour;

        // Build the output string
        let output = '';
        if (days > 0) {
            output += `${days}d `;
        }
        if (hours > 0) {
            output += `${hours}h `;
        }
        if (minutes > 0) {
            output += `${minutes}m`;
        }

        return output.trim();
    }

    static getDuration(startDatetime, endDatetime) {
        let duration = {};

        if (startDatetime && endDatetime) {
            const time1 = new Date(startDatetime); // Convert start_at to Date object
            const time2 = new Date(endDatetime);   // Convert end_at to Date object

            const dateDiff = Math.floor((time2 - time1) / (1000 * 60)); // Difference in minutes
            const hours = Math.floor(dateDiff / 60); // Calculate hours
            const minutes = dateDiff % 60;          // Calculate remaining minutes

            duration = {hours: hours, minutes: minutes};
        }

        return duration;
    }

    static getTrimedText(text, length, type = 'character') {
        if (type === 'line') {
            const descriptionLines = text.split("\n");
            let firstFewLines = descriptionLines.slice(0, length);
            let joinedLines = firstFewLines.join("\n");
            const linesArray = joinedLines.split("\n");

            let totalChars = 0;
            let validLength = 0;

            for (let i = 0; i < linesArray.length; i++) {
                totalChars += linesArray[i].length;

                if (totalChars > 540) {
                    if (i === 0) {
                        Helpers.getTrimedText(text, 540, 'character'); // Recursive call for character trimming
                        return
                    }
                    validLength = i - 1;
                    break;
                }
            }

            if (validLength && validLength < length) {
                length = validLength;
            }

            firstFewLines = linesArray.slice(0, length);
            text = firstFewLines.join("\n").replace(/\n$/, ""); // Remove trailing newlines
        } else {
            if (text.length > length) {
                text = text.substring(0, length); // Trim by character length
            }
        }

        return text; // Return the trimmed text
    }

    static openModal(selector) {
        $(selector).removeClass('eb-d-none');
        $('body').addClass('eb-modal-open');
    }

    static closeModal(selector) {
        $(selector).addClass('eb-d-none');
        $('body').removeClass('eb-modal-open');
    }

    static truncateString(str, length = 100) {
        if (str.length > length) {
            return str.slice(0, length) + '...';
        }
        return str;
    }

    static getEventVenue(eventDetails) {
        if (!eventDetails || !eventDetails?.configuration) {
            return '';
        }

        let venue = "";

        eventDetails.configuration.attributes.forEach(function (config, index) {
            if (config.name === 'venue') {
                venue = config.value;
            }
        });

        return venue;
    }

    static getYoutubeEmbedUrl(url) {
        const shortUrlRegex = /youtu\.be\/([a-zA-Z0-9_-]+)\??/i;
        const longUrlRegex = /youtube\.com\/((?:embed)|(?:watch))((?:\?v\=)|(?:\/))([a-zA-Z0-9_-]+)/i;

        let youtubeId = null;

        if (longUrlRegex.test(url)) {
            const matches = url.match(longUrlRegex);
            youtubeId = matches[matches.length - 1]; // Get the video ID from long URL
        }

        if (shortUrlRegex.test(url)) {
            const matches = url.match(shortUrlRegex);
            youtubeId = matches[matches.length - 1]; // Get the video ID from short URL
        }

        return youtubeId ?? null;
    }

    static initVideoPlayer(el) {
        if (!el) el = document;
        $('.mrks-iframe-pb', el).off('click').on('click', function () {
            const $this = $(this)
            const img = $this.siblings("img")
            let videoUrl = img.data("youtube-link");
            if (videoUrl !== '') {
                if (videoUrl.indexOf('?') === -1) {
                    videoUrl += '?autoplay=1&mute=1';
                } else {
                    videoUrl += '&autoplay=1&mute=1';
                }
                $this.hide();
                img.fadeOut();
                $this.parents(".mrks-iframe-wrapper").html('<iframe class="mrks-iframe" width="560" height="315"\n' +
                    'src="' + videoUrl + '" frameborder="0" allowfullscreen></iframe>');
            }
            return false;
        });
    }

    static isEmptyObject(obj) {
        return this.isEmpty(obj) || Object.keys(obj).length === 0;
    }

    static isEmpty(value) {
        if (!value) {
            return true;
        } else if (Array.isArray(value) && value.length === 0) {
            return true;
        } else if (typeof value === 'object' && Object.keys(value).length === 0) {
            return true;
        }
        return false;
    }

    static getEventAddress(eventVenueAddress) {
        const venueAddress = [];

        if (eventVenueAddress) {
            if (eventVenueAddress.address_line_1) {
                venueAddress.push(eventVenueAddress.address_line_1);
            }
            if (eventVenueAddress.address_line_2) {
                venueAddress.push(eventVenueAddress.address_line_2);
            }
            if (eventVenueAddress.city) {
                venueAddress.push(eventVenueAddress.city);
            }
            if (eventVenueAddress.state) {
                venueAddress.push(eventVenueAddress.state);
            }
            if (eventVenueAddress.postcode) {
                venueAddress.push(eventVenueAddress.postcode);
            }
            if (eventVenueAddress.country) {
                venueAddress.push(eventVenueAddress.country);
            }
        }

        let vAddress = '';
        if (venueAddress.length > 0) {
            vAddress = venueAddress.join(", ");
        }

        return vAddress;
    }

    static getWidgetButtonStyle(widgetConfig) {
        let widgetButtonStyle = "";
        if (widgetConfig) {
            let hasCusStyle = false;
            widgetButtonStyle = 'style=';

            const themeColor = widgetConfig?.theme_colour;
            if (themeColor) {
                widgetButtonStyle += `background:${themeColor}!important;`;
                hasCusStyle = true;
            }

            const buttonShape = widgetConfig?.button_shape;
            if (buttonShape && buttonShape === Constants.EMBED_BUTTON_SHAPE_CURVE) {
                widgetButtonStyle += 'border-radius:10px!important;';
                hasCusStyle = true;
            }

            if (!hasCusStyle) {
                widgetButtonStyle = "";
            }
        }

        return widgetButtonStyle;
    }

    static getWidgetButtonText(widgetConfig, defaultText = "Book Now") {
        let bookNowButtonText = defaultText;

        if (widgetConfig) {
            if (widgetConfig?.button_text) {
                bookNowButtonText = widgetConfig.button_text;
            }
        }

        return bookNowButtonText;
    }

    static isRecurringEvent(eventDetails) {
        return eventDetails?.event_occurrence?.length > 0;
    }

    static enableFullDay(eventDetails) {
        return eventDetails?.settings?.enable_full_day;
    }

    static isTimeSlotEvent(eventDetails) {
        const typeOfOccurrence = Helpers.getTheTypeOfOccurrence(eventDetails);
        return typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.TIMESLOTS
    }

    static convertNameValueArrayToOneObject = (arr) => {
        let obj = {};
        if (arr && arr !== undefined && arr?.length > 0) {
            for (var i = 0; i < arr?.length; i++) {
                if (arr[i]?.name) {
                    obj[arr[i].name] = arr[i]?.value;
                }
            }
            return obj;
        }
    }

    static calculateTicketFee(details, price) {
        const feesTable = Helpers?.convertNameValueArrayToOneObject(details?.fees?.rate);

        const fee = ((price / 100) * Number(feesTable?.eventbookings_service_fee_percentage || 0) + Number(feesTable?.eventbookings_service_fee_fixed || 0)).toFixed(2);

        // console.log('c456', price,  fee,  Number(price)+Number(fee));

        return Number(price) + Number(fee);
    };

    static ticketPriceAndDiscountGenerator = (details, tickets) => {
        let discountPercentage = 0;
        // console.log('c45', Helpers?.convertNameValueArrayToOneObject(details?.fees?.rate));
        const isFeeInclusive = tickets?.price_is_fee_inclusive;
        let prices = [];
        let maxPricedTicketVal = 0;
        let maxPricedTicket = null;
        let minPricedTicketVal = 999999999999;
        let minPricedTicket = null;
        let isDonationTicketOnly = false;

        if (tickets?.levels?.length > 0) {
            tickets?.levels?.map(item => {
                if (item?.category != 'donation') {
                    let type = item?.early_bird_discount;
                    if (type?.discount_ends_on?.utc && moment.utc().isAfter(moment.utc(type?.discount_ends_on?.utc))) {
                        type = null; //discount time ended
                    }
                    if (type?.discount_type === 'Fixed') {
                        const disc = item?.pricing_details?.reduce((acc, curr) => {
                            let result = (Number(type?.discount || 0) / Number(curr?.price)) * 100;
                            result = isFeeInclusive ? Helpers.calculateTicketFee(details, result) : result;
                            return result > acc ? result : acc;
                        }, 0);
                        let pricesArray = [];
                        if (item?.status) {
                            pricesArray = item?.pricing_details?.reduce((acc, curr) => {
                                if (maxPricedTicketVal < curr?.price && item?.status) {
                                    maxPricedTicketVal = curr?.price;
                                    maxPricedTicket = item;
                                }
                                if (minPricedTicketVal > curr?.price && item?.status) {
                                    minPricedTicketVal = curr?.price;
                                    minPricedTicket = item;
                                }
                                let result = Number(curr?.price) - Number(type?.discount || 0);
                                result = isFeeInclusive ? Helpers.calculateTicketFee(details, result) : result;
                                return [...acc, result];
                            }, []);
                        }

                        prices = [...prices, ...pricesArray];
                        discountPercentage = disc > discountPercentage ? disc : discountPercentage;
                        // console.log('c4567', prices);
                    } else {
                        let pricesArray = [];
                        if (item?.status) {
                            pricesArray = item?.pricing_details?.reduce((acc, curr) => {
                                if (maxPricedTicketVal < curr?.price && item?.status) {
                                    maxPricedTicketVal = curr?.price;
                                    maxPricedTicket = item;
                                }
                                if (minPricedTicketVal > curr?.price && item?.status) {
                                    minPricedTicketVal = curr?.price;
                                    minPricedTicket = item;
                                }
                                let result = (Number(curr?.price) / 100) * (100 - Number(type?.discount || 0));
                                result = isFeeInclusive ? Helpers.calculateTicketFee(details, result) : result;
                                return [...acc, result];
                            }, []);
                        }

                        prices = [...prices, ...pricesArray];
                        discountPercentage = Number(type?.discount) > discountPercentage ? Number(type?.discount) : discountPercentage;
                    }
                } else {
                    isDonationTicketOnly = true
                }
            });
            if (prices.length > 0) isDonationTicketOnly = false;
        }
        return {ticketPrices: prices, discountPercentage, minPricedTicket, maxPricedTicket, isDonationTicketOnly};
    };

    static applyDiscount(value, discountType, discountAmount) {
        if (discountType === 'Fixed') {
            return Math.max(value - discountAmount, 0);
        } else if (discountType === 'Percentage') {
            const percentageDiscount = (value * discountAmount) / 100;
            return Math.max(value - percentageDiscount, 0);
        }
        return value;
    };

    static ticketPriceLabel(details, tickets, onlyShowMinValue = true, isFromEventDetails) {
        const {
            ticketPrices,
            minPricedTicket,
            maxPricedTicket,
            isDonationTicketOnly
        } = Helpers.ticketPriceAndDiscountGenerator(details, tickets);

        const isFeeInclusive = details?.settings?.service_charge?.enabled;

        if (ticketPrices?.length > 0) {
            let label = '';
            let eventLevelDiscount = null;
            if (details?.settings?.discount?.level == 'event') {
                eventLevelDiscount = details?.early_bird_discount;
                if (eventLevelDiscount?.discount_ends_on?.utc && moment.utc().isAfter(moment.utc(eventLevelDiscount?.discount_ends_on?.utc))) {
                    eventLevelDiscount = null; //discount time ended
                }
            }

            let minPrice = +Math?.min(...ticketPrices);
            let maxPrice = +Math?.max(...ticketPrices);

            if (eventLevelDiscount != null) {
                minPrice = Helpers.applyDiscount(minPrice, eventLevelDiscount?.discount_type, eventLevelDiscount?.discount)
                maxPrice = Helpers.applyDiscount(maxPrice, eventLevelDiscount?.discount_type, eventLevelDiscount?.discount)
            }
            let currencySign = Constants.SupportedCurrencySigns[details?.currency] || '';
            label = `${details?.currency} `;


            if (ticketPrices?.length > 1) {
                minPrice = `${minPrice > 0 ? (isFeeInclusive && minPricedTicket?.settings?.price_included_service_charge !== true ? +Helpers.calculateTicketFee(details, minPrice) : minPrice).toFixed(2) : '0.00'}`;
                maxPrice = (maxPrice > 0 && isFeeInclusive && maxPricedTicket?.settings?.price_included_service_charge !== true ? +Helpers.calculateTicketFee(details, maxPrice) : maxPrice).toFixed(2);
                if (minPrice == '0.00' && maxPrice == '0.00') {
                    label = "Free"
                } else {
                    if (onlyShowMinValue) {
                        label = `${label}${minPrice}`
                    } else {
                        label = `${label}${minPrice} - ${label}${maxPrice}`
                    }
                }
            } else if (ticketPrices?.length === 1) {
                if (ticketPrices[0] > 0) {
                    label += `${(isFeeInclusive && minPricedTicket?.settings?.price_included_service_charge !== true ? +Helpers.calculateTicketFee(details, minPrice) : +minPrice).toFixed(2)}`;
                } else {
                    label = 'Free';
                }
            }

            return label;
        }
        if (isDonationTicketOnly && isFromEventDetails) return 'Donation'

    }

    static doGetTicketPriceLabel(_details, _tickets) {

        let onlyShowMinValue = false;

        if (_details?.settings?.configure_pricing_display_text?.display === 'starting_price') {
            onlyShowMinValue = true;
        }

        let priceRange = _tickets?.levels?.length > 0 ? Helpers.ticketPriceLabel(_details, _tickets, onlyShowMinValue, true) || '' : '';
        // console.log({_details, _tickets, priceRange, onlyShowMinValue});

        return (onlyShowMinValue && priceRange && !['Free', 'Donation'].includes(priceRange) ? 'Starts from ' : '') + priceRange;
    };

    static getPriceHtml(price, currency) {
        return `${Constants.SupportedCurrencySigns[currency] || ''}${parseFloat(price).toFixed(2)} ${currency}`;
    }

    static getTheTypeOfOccurrence = (eventDetails) => {
        return eventDetails?.occurrence?.type;
    }

    static calculateTimeDurationInSecFromUtc(endDateUtc) {
        let startTime = moment.utc();
        const endTime = moment.utc(endDateUtc, 'YYYY/MM/DD HH:mm:ss')
        var duration = moment.duration(moment(endTime, 'YYYY/MM/DD HH:mm:ss').diff(startTime)).asSeconds();
        return duration;
    };

    static calculateTimeDurationInSec(date2, timezone) {//date2 => localtime
        // console.log('z123a786',{date2,timezone});
        let startTime;

        // todays time and end time
        if (timezone) {
            startTime = moment().tz(timezone).format('YYYY/MM/DD HH:mm:ss')
        } else {
            startTime = moment().format('YYYY/MM/DD HH:mm:ss')
        }

        var endTime = moment(date2, 'YYYY/MM/DD HH:mm:ss');
        // var endTime = Moment(MomentTimezone.tz(date2, timezone), 'YYYY/MM/DD HH:mm:ss');

        // calculate total duration
        var duration = moment.duration(moment(endTime, 'YYYY/MM/DD HH:mm:ss').diff(moment(startTime, 'YYYY/MM/DD HH:mm:ss'))).asSeconds();
        // console.log('z123a786',{ date2, timezone, startTime, endTime, duration});

        return duration;
    };

    static discountCalculate(price, discountEndTime, type, discount, timezone) {
        if (discountEndTime !== null) {
            if (Helpers?.calculateTimeDurationInSec(discountEndTime, timezone) > 0) {
                if (type === 'Fixed') {
                    if (Number(price) < Number(discount)) {
                        return Number(price);
                    }
                    const result = Number(discount); //+(Number(price) - Number(discount)).toFixed(2);
                    return result >= 0 ? result : 0;
                } else if (type === 'Percentage') {
                    const result = +(Number(price) / 100) * Number(discount);
                    return result >= 0 ? result : 0;
                } else {
                    return 0;
                }
            } else {
                return 0;
            }
        } else {
            return 0;
        }
    }

    //Will return current time in local/utc timezone. Also can return time in specific format!!!
    static time(utc = true, dateTime = null, format = '') {
        if (!this.isEmpty(dateTime)) {
            if (utc) {
                return this.isEmpty(format) ? moment.utc(dateTime) : moment.utc(dateTime).format(format || "YYYY-MM-DD HH:mm:ss");
            } else {
                return this.isEmpty(format) ? moment(dateTime) : moment(dateTime).format(format || "YYYY-MM-DD HH:mm:ss");
            }
        } else {
            if (utc) {
                return this.isEmpty(format) ? moment.utc() : moment.utc().format(format);
            } else {
                return this.isEmpty(format) ? moment() : moment().format(format);
            }
        }
    }

    static getSingleDuration(duration) {
        if (duration > 0) {
            let hours = Number(duration / 60);
            let minutes = duration % 60;
            minutes = Number(minutes);

            duration = {
                hours: hours,
                minutes: minutes
            };
        }

        return duration;
    }

    static feesCalculator(price, ticket, pricingDetails, eventDetails) {
        const isFeesAvailable = eventDetails?.settings?.service_charge?.enabled || false; //tickets?.price_is_fee_inclusive;
        let fees = eventDetails?.fees;

        const feesTable = Helpers?.convertNameValueArrayToOneObject(fees?.rate);

        const ticketContains = +pricingDetails?.quantity_included || 1;
        if (isFeesAvailable && (price > 0)) {
            if (eventDetails?.settings?.service_charge?.level === 'ticket' && ticket?.settings?.price_included_service_charge) {
                return 0;
            }
            return Number(((price / 100) * Number(feesTable.eventbookings_service_fee_percentage) + Number(feesTable.eventbookings_service_fee_fixed) * +ticketContains).toFixed(2));
        } else {
            return 0;
        }
    };

    static checkIsBookingEnded(data, checkForEvent = false) {
        let settings = data?.settings;

        if (checkForEvent) {
            if (settings?.booking_ends_on?.level === 'ticket') {
                return false;
            }
        }

        return settings?.booking_ends_on?.utc ? moment.utc().diff(moment.utc(settings?.booking_ends_on?.utc, 'YYYY/MM/DD HH:mm:ss')) > 0 : false
    }

    static ticketHasVariations(ticket) {
        return !!(ticket?.pricing_details?.length > 1 || (ticket?.pricing_details?.length === 1 && ticket?.pricing_details?.[0]?.uuid));
    }

    static getMaxTicketLimit(level) {
        let maxTicketLimit = 99999999;

        if (level?.max_quantity_per_customer > 0) {
            maxTicketLimit = level?.max_quantity_per_customer;
        }

        if (level?.quantity > 0) {
            let level_quantity_sold = level?.quantity_sold;

            if (maxTicketLimit) {
                if (level?.quantity < maxTicketLimit) {
                    maxTicketLimit = level?.quantity - level_quantity_sold;
                }
            } else {
                maxTicketLimit = level?.quantity - level_quantity_sold;
            }
        }

        let ticketHasVariations = Helpers.ticketHasVariations(level);
        if (!ticketHasVariations) {
            if (level?.pricing_details[0]?.quantity_included > 1) {
                maxTicketLimit = Math.floor(maxTicketLimit / level?.pricing_details[0]?.quantity_included);
            }
        }

        return maxTicketLimit;
    }

    static hasEventSessionForSell(eventDetails) {
        let activeSessions = Helpers.getActiveSessions(eventDetails);
        return activeSessions.length && eventDetails?.settings?.sell_session_individually?.enabled;
    }

    static getActiveSessions(eventDetails) {
        let sessions = [];
        const typeOfOccurrence = Helpers.getTheTypeOfOccurrence(eventDetails);
        if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
            sessions = eventDetails?.sessions?.session_lists.filter(item => item.status) || [];
        } else {
            sessions = this.getOccurrenceSessionList(eventDetails);
        }

        let withActiveTicketsSessions = [];
        if (sessions.length) {
            if (eventDetails?.settings?.sell_session?.enabled) {
                sessions.forEach(function (session) {

                    let sessionTickets = Helpers.getTicketsBySessionUuid(eventDetails, session.uuid);
                    if (!sessionTickets?.levels?.length) {
                        return;
                    }

                    let findActiveTicket = sessionTickets?.levels?.find(item => item.status);
                    if (!findActiveTicket) {
                        return;
                    }

                    withActiveTicketsSessions.push(session);
                })
            } else {
                withActiveTicketsSessions = sessions;
            }
        }

        return withActiveTicketsSessions;
    }

    static getOccurrenceSessionList(event) {
        let occurrenceSessions = event?.event_occurrence?.flatMap(occurrence =>
            (occurrence.sessions ?? []).map(session => ({
                ...session,
                occurrence_uuid: occurrence.uuid
            }))
        );
        if (this.isEmpty(occurrenceSessions)) return [];

        const eventSessions = event?.sessions?.session_lists.filter(item => item.status) || [];

        return occurrenceSessions
            .map(occSession => {
                const eventSession = eventSessions.find(evSession => evSession.uuid === occSession.uuid);
                return eventSession ? {
                    ...eventSession,
                    session_starts_on: occSession.session_starts_on,
                    session_ends_on: occSession.session_ends_on,
                    tickets: occSession.tickets,
                    occurrence_uuid: occSession.occurrence_uuid
                } : null;
            })
            .filter(Boolean);
    }

    static isMultiDayEvent(eventDetails) {
        let startAt = moment.utc(eventDetails?.occurrence?.attributes?.starts_on?.utc, "YYYY-MM-DD");

        let eventDuration = eventDetails?.occurrence?.attributes?.event_duration;
        let endAt = Helpers.addTimeWithDate(startAt, eventDuration, 'minutes');
        endAt = moment.utc(endAt, "YYYY-MM-DD");

        return !startAt.isSame(endAt, 'day');
    }

    static getEventCapacity(event, onlyOneOcc = false) {
        let capacity = Constants.CAPACITY_UNLIMITED;
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);

        if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
            capacity = event?.settings?.event_capacity <= 0 ? Constants.CAPACITY_UNLIMITED : event?.settings?.event_capacity;
        } else {
            let totalOcc = onlyOneOcc ? 1 : event?.event_occurrence.map(occ => occ.enabled == true).length;
            capacity = event?.settings?.event_capacity <= 0 ? Constants.CAPACITY_UNLIMITED : event?.settings?.event_capacity * totalOcc;
        }
        return capacity;
    }

    static isEnableEventCapacity(eventDetails) {
        return Helpers.getEventCapacity(eventDetails) > 0;
    }

    static getEventOrderTicketsCount(tickets) {
        let totalOrders = 0;

        tickets?.levels?.forEach(function (item) {
            totalOrders += item.quantity_sold;
        });

        return totalOrders;
    }

    static getEventMaxTicketPerCustomer(eventDetails) {
        return eventDetails?.settings?.max_ticket_per_customer;
    }

    static getEventResourcePdfSrc(resource) {
        const docsGoogleViewerUrl = Constants.DOCS_GOOGLE_VIEWER_URL; // Replace with your actual URL

        if (resource) {
            const pdfPath = Helpers.getImageFullUrl(resource); // Adjust as needed to match your asset URL logic
            // let pdfPath = "https://www.w3.org/WAI/ER/tests/xhtml/testfiles/resources/pdf/dummy.pdf";

            const timestamp = Math.floor(Date.now() / 1000); // Equivalent to PHP's time()
            return `${docsGoogleViewerUrl}?url=${pdfPath}&embedded=true&cache=${timestamp}`;
        }

        return "";
    }

    static isOnlineEvent(eventDetails) {
        return eventDetails?.configuration?.type === "online_event";
    }

    static isOnlineEventTypeEventMeet(eventDetails) {
        const platform = eventDetails?.configuration?.attributes?.find(item => item.name === "platform")?.value;

        if (platform && platform === "event_meet") {
            return true
        }

        return false;
    }

    static isEnableTicketMandatory(eventDetails) {
        if (eventDetails?.settings?.enable_ticket_mandatory) {
            return true;
        }

        return false;
    }

    static eventHasProducts(eventDetails) {
        if (!Helpers.isEmptyObject(eventDetails?.merchandise)) {
            let activeProduct = eventDetails?.merchandise?.products.find(function (item) {
                return item.status;
            })

            if (activeProduct) {
                return true;
            }
        }

        return false;
    }

    static getInvitationCodeRestriction(eventDetails) {
        if (eventDetails?.settings?.restrictions?.length) {
            return eventDetails?.settings?.restrictions?.find(item => item.type === "invitation_code" && item.enabled);
        }

        return false;
    }

    static isEnabledInvitationCodeRestriction(eventDetails) {
        return !!Helpers.getInvitationCodeRestriction(eventDetails);
    }


    static getAgeRestriction(eventDetails) {
        if (eventDetails?.settings?.restrictions?.length) {
            return eventDetails?.settings?.restrictions?.find(item => item.type === "age" && item.enabled);
        }

        return false;
    }

    static isEnabledAgeRestriction(eventDetails) {
        return !!Helpers.getAgeRestriction(eventDetails);
    }

    static isOccurrenceTicketSoldOut(event, occurrence) {
        let status = false;
        if (this.isEmpty(occurrence)) return status;

        let occurrenceCapacity = this.getOccurrenceCapacity(event, occurrence);

        if (occurrenceCapacity != Constants.CAPACITY_UNLIMITED) {
            let totalOccSoldOutTicket = this.getTotalOccurrenceSoldTicket(event, occurrence);

            if (occurrenceCapacity <= totalOccSoldOutTicket) {
                status = true;
            }
        }

        return status;
    }

    static getOccurrenceCapacity(event, occurrence) {
        let haveSellSession = this.hasEventSessionForSell(event);
        let capacity = Constants.CAPACITY_UNLIMITED;
        let occurrenceCapacity = event?.settings?.event_capacity <= 0 ? Constants.CAPACITY_UNLIMITED : event?.settings?.event_capacity;
        let totalSessionCapacity = 0;
        let totalTicketCapacity = 0;
        let allTickets = event?.tickets?.levels || [];

        let uniqueTickets = [];
        if (!this.isEmpty(occurrence.timeslots)) {
            //For timeslot
            const timeSlotTickets = occurrence?.timeslots.flatMap(timeslot => timeslot?.tickets || []);

            const seenUuids = new Set();
            for (const ticket of timeSlotTickets) {
                if (!seenUuids.has(ticket.uuid)) {
                    seenUuids.add(ticket.uuid);
                    uniqueTickets.push(ticket);
                }
            }
        } else {
            if (haveSellSession) {
                uniqueTickets = occurrence?.sessions?.flatMap(session => session.tickets ?? []);
                totalSessionCapacity = this.getTotalSessionCapacity(event, occurrence.uuid);
            } else {
                uniqueTickets = occurrence?.tickets;
            }
        }

        if (!this.isEmpty(uniqueTickets)) {
            for (const ticket of uniqueTickets) {
                const matchedTicket = allTickets.find(item => item.uuid === ticket.uuid);

                if (matchedTicket) {
                    if (matchedTicket.quantity === Constants.CAPACITY_UNLIMITED) {
                        totalTicketCapacity = Constants.CAPACITY_UNLIMITED;
                        break;
                    } else {
                        totalTicketCapacity += matchedTicket.quantity;
                    }
                }
            }
        } else {
            totalTicketCapacity = Constants.CAPACITY_UNLIMITED;
        }

        if (haveSellSession) {
            if (totalTicketCapacity != Constants.CAPACITY_UNLIMITED && totalSessionCapacity != Constants.CAPACITY_UNLIMITED) {
                totalTicketCapacity = totalTicketCapacity < totalSessionCapacity ? totalTicketCapacity : totalSessionCapacity;
            } else if (totalSessionCapacity != Constants.CAPACITY_UNLIMITED) {
                totalTicketCapacity = totalSessionCapacity;
            }
        }

        if (totalTicketCapacity != Constants.CAPACITY_UNLIMITED && occurrenceCapacity != Constants.CAPACITY_UNLIMITED) {
            if (occurrenceCapacity < totalTicketCapacity) {
                capacity = occurrenceCapacity;
            } else {
                capacity = totalTicketCapacity;
            }
        } else if (totalTicketCapacity == Constants.CAPACITY_UNLIMITED && occurrenceCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = occurrenceCapacity;
        } else if (totalTicketCapacity != Constants.CAPACITY_UNLIMITED && occurrenceCapacity == Constants.CAPACITY_UNLIMITED) {
            capacity = totalTicketCapacity;
        } else {
            capacity = Constants.CAPACITY_UNLIMITED;
        }

        return capacity;
    }

    static getTotalOccurrenceSoldTicket(event, occurrence) {
        let totalSoldTicket = 0;

        if (!this.isEmpty(occurrence?.timeslots)) {
            //For timeslot
            const timeSlotTickets = occurrence?.timeslots.flatMap(timeslot => timeslot?.tickets || []);

            for (const timeSlotTicket of timeSlotTickets) {
                totalSoldTicket += timeSlotTicket.quantity_sold;
            }
        } else {
            //For occurrence
            let occTickets = [];
            let haveSellSession = this.hasEventSessionForSell(event);
            if (haveSellSession) {
                occTickets = occurrence?.sessions?.flatMap(session => session.tickets ?? []);
            } else {
                occTickets = occurrence?.tickets;
            }

            for (const occTicket of occTickets) {
                totalSoldTicket += occTicket.quantity_sold;
            }
        }

        return totalSoldTicket;
    }

    static getSelectedOccurrenceUuid() {
        return $("#occurrencePicker").find(":selected").attr('data-occurrenceUuid');
    }

    static getOccurrenceDetailsByUuid(eventDetails, occurrenceUuid) {
        return eventDetails?.event_occurrence?.find(item => item.uuid === occurrenceUuid)
    }

    static getSessionDetailsByUuid(eventDetails, sessionUuid) {
        return eventDetails?.sessions?.session_lists?.find(item => item.uuid === sessionUuid)
    }

    static getTimeslotDetailsByUuid(occurrenceDetails, timeslotUuid) {
        return occurrenceDetails?.timeslots?.find(item => item.uuid === timeslotUuid)
    }

    static makeTicketsListWithFullDataFromShortData(eventDetails, ticketsListWithShortData) {
        let ticketsList = [];

        if (ticketsListWithShortData?.length) {

            ticketsListWithShortData.forEach(function (ticket) {
                let ticketUuid = ticket.uuid;

                if (eventDetails?.tickets?.levels?.length) {
                    let findTicket = eventDetails?.tickets?.levels?.find(item => item.uuid === ticketUuid);

                    if (findTicket) {

                        let formattedPricingDetails = findTicket?.pricing_details.map(function (item, index) {
                            return {
                                ...item,
                                quantity_sold: ticket?.pricing_details[index]?.quantity_sold
                            }
                        })

                        ticketsList.push(
                            {
                                ...findTicket,
                                quantity_sold: ticket.quantity_sold,
                                total_purchased_by_user: ticket.total_purchased_by_user,
                                pricing_details: formattedPricingDetails,
                                session_uuid: ticket?.session_uuid,
                                occurrence_uuid: ticket?.occurrence_uuid ?? null,
                                session_sold_out: ticket?.session_sold_out,
                                occurrence_sold_out: ticket?.occurrence_sold_out ?? false,
                            }
                        )
                    }
                }
            })
        }

        if (ticketsList.length) {
            return {levels: ticketsList};
        }

        return [];
    }

    static getTicketsByOccurrenceUuid(eventDetails, occurrenceUuid) {
        let selectedOccurrence = Helpers.getOccurrenceDetailsByUuid(eventDetails, occurrenceUuid);
        return Helpers.makeTicketsListWithFullDataFromShortData(eventDetails, selectedOccurrence?.tickets);
    }

    static getTicketsBySessionUuid(eventDetails, sessionUuid) {
        let selectedSession = Helpers.getSessionDetailsByUuid(eventDetails, sessionUuid);
        return Helpers.makeTicketsListWithFullDataFromShortData(eventDetails, selectedSession?.tickets);
    }

    static getTicketsBySTimeslotUuid(eventDetails, occurrenceUuid, timeslotUuid) {
        let selectedOccurrence = Helpers.getOccurrenceDetailsByUuid(eventDetails, occurrenceUuid);
        let selectedTimeslot = Helpers.getTimeslotDetailsByUuid(selectedOccurrence, timeslotUuid);
        return Helpers.makeTicketsListWithFullDataFromShortData(eventDetails, selectedTimeslot?.tickets);
    }

    static isTicketPageTypeWidget(widgetConfig) {
        return widgetConfig?.type === Constants.WIDGET_TYPE.TICKET_PAGE;
    }

    static isButtonTypeWidget(widgetConfig) {
        return widgetConfig?.type === Constants.WIDGET_TYPE.BUTTON;
    }

    static initializeSelect2Picker() {
        $('.select2Picker').select2();
    }

    static triggerChangeOccurrencePicker() {
        $('#occurrencePicker').trigger('change');
    }

    static htmlspecialchars(str) {
        if (typeof str !== "string") return str; // Ensure it's a string

        return str
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;"); // Escape single quotes
    }

    static checkBeforeTimeSlotNoticePeriod(event, appointment) {
        let timeslot_settings = event?.occurrence?.attributes?.timeslot_settings;
        let notice_period_before_timeslot_time = timeslot_settings?.notice_period?.allow_booking_after_attendee_time;

        if (!this.isEmpty(timeslot_settings) && timeslot_settings.enable_notice_period && !this.isEmpty(notice_period_before_timeslot_time)) {
            let timeslot_start_on = moment(appointment.start_time.utc);
            let date = timeslot_start_on.clone().subtract(notice_period_before_timeslot_time, 'minutes');

            if (moment(date).isBefore(moment().utc())) {
                return true;
            }
        }

        return false;
    }

    static checkAfterBookedTimeslotNoticePeriod(event, eventOrderOccurrence, timeslot) {
        let timeslot_settings = event?.occurrence?.attributes?.timeslot_settings;
        let notice_period_after_booked_timeslot = timeslot_settings?.notice_period?.allow_booking_after_end_of_booked_timeslot;
        let status = false;

        if (!this.isEmpty(timeslot_settings) && timeslot_settings.enable_notice_period && !this.isEmpty(notice_period_after_booked_timeslot)) {
            let timeslot_start_on = moment(timeslot.start_time.utc);

            let event_order_occurrence_start_on = moment(eventOrderOccurrence.start_time.utc);
            let event_order_occurrence_end_on = event_order_occurrence_start_on.clone().add(eventOrderOccurrence.duration, 'minutes');

            let event_order_occurrence_end_on_with_notice = event_order_occurrence_end_on.clone().add(notice_period_after_booked_timeslot, 'minutes');

            if (timeslot_start_on.isBefore(moment(event_order_occurrence_end_on_with_notice)) && timeslot_start_on.isAfter(moment(event_order_occurrence_start_on))) {
                status = true;
            }
        }

        return status;
    }

    //It will return the timeslot which have a order
    static getOrderOccurrenceOfEvent(event) {
        let orderedOccurrecnces = [];
        let occurrences = event?.event_occurrence;
        if (this.isEmpty(occurrences)) return orderedOccurrecnces;

        const timeslots = occurrences.flatMap(occurrence => occurrence?.timeslots || []);

        for (const timeslot of timeslots) {
            let tickets = timeslot?.tickets;
            if (this.isEmpty(tickets)) continue;

            let haveOrder = false;
            for (const ticket of tickets) {
                if (ticket.quantity_sold > 0) {
                    haveOrder = true;
                    break;
                }
            }

            if (haveOrder) {
                orderedOccurrecnces.push(timeslot);
            }
        }

        return orderedOccurrecnces;
    }


    static isTicketSoldOut(level) {
        let status = false;

        let ticketCapacity = level.quantity;
        if (ticketCapacity != Constants.CAPACITY_UNLIMITED) {
            let totalSoldTicket = level.quantity_sold;

            if (ticketCapacity <= totalSoldTicket) {
                status = true;
            }
        }

        return status;
    }

    static isEventSoldOut(event, occurrence = null) {
        let status = false;


        if (!this.isEmpty(occurrence)) {
            status = Helpers.isOccurrenceTicketSoldOut(event, occurrence);
        } else {
            let capacity = this.getCapacity(event);
            if (capacity != Constants.CAPACITY_UNLIMITED) {
                let totalSoldTicket = this.getTotalSoldTicketForEvent(event);

                if (capacity <= totalSoldTicket) {
                    status = true;
                }
            }

        }

        return status;
    }

    static getCapacity(event) {
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);
        let haveSellSession = this.hasEventSessionForSell(event);

        let capacity = 0;
        let ticketCapacity = 0;
        let totalSessionCapacity = 0;
        let eventCapacity = this.getEventCapacity(event);

        if (haveSellSession) {
            totalSessionCapacity = this.getTotalSessionCapacity(event);

            if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
                //Getting all the tickets of all the session
                let tickets = event?.sessions?.session_lists.flatMap(session => session?.tickets || []);
                let ticketUuids = tickets.map(ticket => ticket.uuid);
                //------->
                ticketCapacity = this.getEventTicketsCapacity(event, ticketUuids);

            } else {
                let haveUnlimitedTicket = false;
                const occurrences = event?.event_occurrence;
                for (const occurrence of occurrences) {
                    let occSessions = occurrence?.sessions;
                    if (this.isEmpty(occSessions)) continue;

                    for (const occSession of occSessions) {
                        let mainSession = event?.sessions?.session_lists?.find(session => session.uuid == occSession.uuid);
                        if (this.isEmpty(mainSession) || mainSession.status != 1) continue;

                        let ticketUuids = mainSession.tickets.map(ticket => ticket.uuid);
                        let sessionticketCapacity = this.getEventTicketsCapacity(event, ticketUuids);

                        if (ticketCapacity == Constants.CAPACITY_UNLIMITED) {
                            haveUnlimitedTicket = true;
                            break;
                        } else {
                            ticketCapacity += sessionticketCapacity;
                        }
                    }

                    if (haveUnlimitedTicket) break;
                }
            }

            if (eventCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED && totalSessionCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = totalSessionCapacity < ticketCapacity ? totalSessionCapacity : ticketCapacity;
                capacity = capacity < eventCapacity ? capacity : eventCapacity;
            } else if (totalSessionCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = totalSessionCapacity < ticketCapacity ? totalSessionCapacity : ticketCapacity;
            } else if (eventCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = eventCapacity < ticketCapacity ? eventCapacity : ticketCapacity;
            } else if (eventCapacity != Constants.CAPACITY_UNLIMITED && totalSessionCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = eventCapacity < totalSessionCapacity ? eventCapacity : totalSessionCapacity;
            } else if (eventCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = eventCapacity;
            } else if (totalSessionCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = totalSessionCapacity;
            } else if (ticketCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = ticketCapacity;
            } else {
                capacity = Constants.CAPACITY_UNLIMITED;
            }


        } else {
            ticketCapacity = this.getEventTicketsCapacity(event);

            if (eventCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = eventCapacity < ticketCapacity ? eventCapacity : ticketCapacity;
            } else if (eventCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = eventCapacity;
            } else if (ticketCapacity != Constants.CAPACITY_UNLIMITED) {
                capacity = ticketCapacity;
            } else {
                capacity = Constants.CAPACITY_UNLIMITED;
            }
        }

        return capacity;
    }

    static getEventTicketsCapacity(event, ticketUuids = []) {
        let totalTicketCapacity = Constants.CAPACITY_UNLIMITED;
        let tickets = event?.tickets?.levels;

        if (this.isEmpty(tickets)) return totalTicketCapacity;

        //For customly assigned tickets
        if (!this.isEmpty(ticketUuids)) {
            const ticketMap = new Map(tickets.map(ticket => [ticket.uuid, ticket]));
            tickets = ticketUuids.map(uuid => ticketMap.get(uuid) || null);
        }
        //------>
        totalTicketCapacity = 0;
        for (const ticket of tickets) {
            if (ticket.quantity === Constants.CAPACITY_UNLIMITED) {
                totalTicketCapacity = Constants.CAPACITY_UNLIMITED;
                break;
            } else {
                totalTicketCapacity += ticket.quantity;
            }
        }

        return totalTicketCapacity;
    }

    //This method will return total event or occurrence session capacity
    static getTotalSessionCapacity(event, occurrenceUUID = null) {
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);
        let totalSessionCapacity = 0;
        let sessions = event?.sessions?.session_lists;
        if (this.isEmpty(sessions) || event?.sessions?.enabled == false) return Constants.CAPACITY_UNLIMITED;

        if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
            for (const session of sessions) {
                if (session.capacity == 0) {
                    totalSessionCapacity = Constants.CAPACITY_UNLIMITED;
                    break;
                } else {
                    totalSessionCapacity += session.capacity;
                }
            }
        } else {
            let haveUnlimited = false
            const occurrences = event?.event_occurrence;
            for (const occurrence of occurrences) {
                if (!this.isEmpty(occurrenceUUID) && occurrenceUUID != occurrence.uuid) continue;
                let occSessions = occurrence?.sessions;
                if (this.isEmpty(occSessions)) continue;

                for (const occSession of occSessions) {
                    let mainSession = sessions?.find(session => session.uuid == occSession.uuid);
                    if (this.isEmpty(mainSession) || mainSession.status != 1) continue;

                    if (mainSession.capacity == 0) {
                        totalSessionCapacity = Constants.CAPACITY_UNLIMITED;
                        haveUnlimited = true;
                        break;
                    } else {
                        totalSessionCapacity += mainSession.capacity;
                    }
                }

                if (haveUnlimited) break;
            }
        }

        return totalSessionCapacity;
    }

    static isSessionSoldOut(event, session) {
        let status = false;
        let capacity = 0;
        let sessionCapacity = session?.capacity == 0 ? Constants.CAPACITY_UNLIMITED : session?.capacity;
        if (this.isEmpty(sessionCapacity)) {
            let mainSession = event?.sessions?.session_lists.find(item => item.uuid == session.uuid);
            sessionCapacity = mainSession?.capacity == 0 ? Constants.CAPACITY_UNLIMITED : mainSession?.capacity;
        }

        let sessionTickets = session?.tickets || [];
        let ticketUuids = sessionTickets.map(ticket => ticket.uuid);
        let ticketCapacity = this.getEventTicketsCapacity(event, ticketUuids);


        if (sessionCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = sessionCapacity < ticketCapacity ? sessionCapacity : ticketCapacity;
        } else if (sessionCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = sessionCapacity;
        } else if (ticketCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = ticketCapacity;
        } else {
            capacity = Constants.CAPACITY_UNLIMITED;
        }

        if (capacity != Constants.CAPACITY_UNLIMITED) {
            let totalSoldTicket = 0;
            sessionTickets?.forEach(function (item) {
                totalSoldTicket += item.quantity_sold;
            });

            if (capacity <= totalSoldTicket) {
                status = true;
            }
        }

        return status;
    }

    //This method will return sold ticket count (active&disabled)  for the event (EVERY TYPE)
    static getTotalSoldTicketForEvent(event) {
        let totalSoldTicket = 0;
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);
        let haveSellSession = this.hasEventSessionForSell(event);

        if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
            if (haveSellSession) {
                let tickets = event?.sessions?.session_lists?.flatMap(session => session.tickets ?? []);

                totalSoldTicket = tickets.reduce((acc, cur) => acc + (Number(cur?.quantity_sold) || 0), 0);

            } else {
                totalSoldTicket = event.tickets.levels.reduce((pre, cur) => pre + (Number(cur?.quantity_sold) || 0), 0);
            }
        } else {
            let occurrences = event?.event_occurrence;
            if (!this.isEmpty(occurrences)) {
                if (haveSellSession) {
                    occurrences.forEach(occurrence => {
                        let tickets = occurrence?.sessions?.flatMap(session => session.tickets ?? []);
                        totalSoldTicket += tickets.reduce((pre, cur) => pre + (Number(cur?.quantity_sold) || 0), 0);
                    });

                } else {
                    occurrences.forEach(occurrence => {
                        totalSoldTicket += this.getTotalOccurrenceSoldTicket(event, occurrence);
                    });
                }
            }
        }

        return totalSoldTicket;
    }

    // Attendee form formeo data list
    static getAttendeeFormList(tickets, lineItems) {
        console.log({tickets}, {lineItems});
        let globalIndex = 1;
        let result = [];

        lineItems.forEach(item => {
            if (item.type === "ticket") {
                let totalTickets = Number(item.quantity_included) * Number(item.quantity);
                let ticketName = "";

                tickets.forEach(ticket => {
                    if (ticket.uuid === item.product) {
                        ticketName = ticket.name;
                    } else {
                        ticket.pricing_details.forEach(detail => {
                            if (detail.uuid === item.product) {
                                ticketName = `${ticket.name} (${detail.variation})`;
                            }
                        });
                    }
                });

                for (let i = 0; i < totalTickets; i++) {
                    result.push({
                        index: globalIndex++,
                        formeo_ticket_slug: item.formeo_ticket_slug,
                        quantity: item.quantity,
                        ticket_name: ticketName,
                    });
                }
            }
        });

        return result;
    }

    // Get order form link
    static getOrderFormLink(eventDetails) {
        const attributes = eventDetails?.configuration?.attributes;
        let result = {};

        attributes?.forEach((attr) => {
            if (attr?.name == 'order_form') {
                result = {
                    enable: attr?.value?.enabled,
                    link: attr?.value?.form_link,
                }
            }
        });

        return result;
    }

    static getOrderTicketDetails = (data, tickets, merchandise = {}, orderTicketData) => {
        let result = [];

        data.forEach(item => {
            if (item.type === "ticket") {
                let ticketName = "";
                let ticketPrice = 0;

                tickets.forEach(ticket => {
                    if (ticket.uuid === item.product) {
                        ticketName = ticket.name;

                        if (ticket.category == Constants.TICKET_CATEGORY.TICKET) {
                            let {
                                type,
                                discountEndsOnLocal
                            } = this.getDiscountData(eventDetails, ticket, orderTicketData);
                            let pricingDetails = ticket?.pricing_details[0];
                            const discPrice = type ? this.discountCalculate(pricingDetails?.price, discountEndsOnLocal, type?.discount_type, type?.discount, eventDetails?.timezone) : 0;
                            let priceWithDiscount = +pricingDetails?.price - +discPrice;
                            let fee = Helpers.feesCalculator(discPrice !== 0 ? priceWithDiscount : pricingDetails?.price, ticket, pricingDetails, eventDetails);
                            ticketPrice = discPrice ? priceWithDiscount + fee : pricingDetails?.price + fee;
                        } else {
                            ticketPrice = item.price;
                        }

                    } else {
                        ticket.pricing_details.forEach(detail => {
                            if (detail.uuid === item.product) {
                                ticketName = `${ticket.name} (${detail.variation})`;

                                let {
                                    type,
                                    discountEndsOnLocal
                                } = this.getDiscountData(eventDetails, ticket, orderTicketData);
                                const discPrice = type ? Helpers.discountCalculate(detail?.price, discountEndsOnLocal, type?.discount_type, type?.discount, eventDetails?.timezone) : 0;
                                let priceWithDiscount = +detail?.price - +discPrice;
                                let fee = Helpers.feesCalculator(discPrice !== 0 ? priceWithDiscount : detail?.price, ticket, detail, eventDetails);
                                ticketPrice = discPrice ? priceWithDiscount + fee : detail?.price + fee;
                            }
                        });
                    }
                });

                result.push({
                    ticketName: ticketName,
                    product: item.product,
                    quantity: item.quantity,
                    price: ticketPrice,
                    quantityIncluded: item.quantity_included ?? 1
                });
            } else if (item.type === "merchandise") {
                let ticketName = "";
                let ticketPrice = 0;

                merchandise.forEach(product => {
                    if (product.uuid === item.product) {
                        ticketName = product.name;

                        let fee = Helpers.feesCalculator(product?.price, product, product, eventDetails);
                        ticketPrice = product?.price + fee;
                    }
                });

                result.push({
                    ticketName: ticketName,
                    product: item.product,
                    quantity: item.quantity,
                    price: ticketPrice,
                    quantityIncluded: item.quantity_included ?? 1
                });
            }
        });

        return result;
    }

    static getDiscountData(event, level, orderTicketData) {
        let isRecurringEvent = Helpers.isRecurringEvent(eventDetails);

        let discountType = "";
        let discountStartsOn = null; //utc time
        let discountEndsOnLocal = null;
        let discountEndsOnUtc = null;

        let selectedOccurrenceStartsOnInUtc = null;
        let selectedOccurrenceStartsOn = null;
        if (!this.isEmpty(orderTicketData.occurrence_uuid)) {
            let orderedOccurrence = Helpers.getOccurrenceDetailsByUuid(eventDetails, orderTicketData.occurrence_uuid);

            if (orderedOccurrence) {
                selectedOccurrenceStartsOnInUtc = orderedOccurrence?.start_on?.utc;
                selectedOccurrenceStartsOn = orderedOccurrence?.start_on?.local;
            }
        }

        if (event?.settings?.discount?.enabled && event?.settings?.discount?.level === 'ticket') {
            discountType = level;
        } else if (event?.settings?.discount?.enabled && event?.settings?.discount?.level === 'event') {
            discountType = event;
        }

        if (discountType != null) {
            discountStartsOn = discountType?.early_bird_discount?.discount_starts_on?.utc;
            discountEndsOnLocal = discountType?.early_bird_discount?.discount_ends_on?.local;
            discountEndsOnUtc = discountType?.early_bird_discount?.discount_ends_on?.utc;
            if (isRecurringEvent && discountType?.early_bird_discount?.type === 'relative_to_occurrence' && selectedOccurrenceStartsOnInUtc) {
                let discountStartsOnOccurrenceType = discountType?.early_bird_discount?.discount_starts_on?.occurrence_booking_end_type === 'number_of_hours' ? 'hours' : 'days';
                let discountStartsOffset = discountType?.early_bird_discount?.discount_starts_on?.occurrence_booking_end_offset;
                if (discountStartsOffset > 0) {
                    discountStartsOn = moment(selectedOccurrenceStartsOnInUtc).subtract(discountStartsOffset, discountStartsOnOccurrenceType).format('YYYY-MM-DD HH:mm');
                } else {
                    discountStartsOn = moment.utc().format('YYYY-MM-DD HH:mm');
                }

                let discountEndsOnOccurrenceType = discountType?.early_bird_discount?.discount_ends_on?.occurrence_booking_end_type === 'number_of_hours' ? 'hours' : 'days';
                discountEndsOnLocal = moment(selectedOccurrenceStartsOn).subtract(discountType?.early_bird_discount?.discount_ends_on?.occurrence_booking_end_offset, discountEndsOnOccurrenceType).format('YYYY-MM-DD HH:mm');
                discountEndsOnUtc = moment(selectedOccurrenceStartsOnInUtc).subtract(discountType?.early_bird_discount?.discount_ends_on?.occurrence_booking_end_offset, discountEndsOnOccurrenceType).format('YYYY-MM-DD HH:mm');
            }
        }
        let type = discountType != null && Helpers.calculateTimeDurationInSecFromUtc(discountStartsOn) <= 0 ? discountType?.early_bird_discount : null;

        return {
            type,
            discountType,
            discountStartsOn, //utc time
            discountEndsOnLocal,
            discountEndsOnUtc,
        };
    }

    // Get total tickets price
    static orderTicketTotalPriceFromFormattedList(data) {
        let total = 0;
        data.forEach(item => {
            total += Number(item.quantity) * Number(item.price);
        });

        return total;
    }

    static eventStickerType(event, occurrence = null) {
        let type = '';
        if (this.isEmpty(occurrence)) {
            let bookingStartData = event.settings.booking_starts_on;
            if (bookingStartData.level == 'event' && this.time().isBefore(this.time(true, bookingStartData.utc))) {
                type = 'booking_not_started';
            } else if (this.eventIsEnded(event)) {
                type = 'event_ended';
            } else if (this.isEventSoldOut(event)) {
                type = 'sold_out';
            } else if (this.eventBookingIsEnded(event)) {
                type = 'booking_end';
            } else if (this.showRemainignTicketCount(event).status) {
                type = 'ticket_remaining';
            }

        } else {
            //For occurrence
            let bookingStartData = event.settings.booking_starts_on;
            if (bookingStartData.level == 'event') {
                let ebBookingStartOn = null;
                if (bookingStartData.type == Constants.BOOKING_STARTS_ON.immediate) {
                    ebBookingStartOn = bookingStartData.utc;
                } else {
                    ebBookingStartOn = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', bookingStartData.occurrence_booking_start_type, bookingStartData.occurrence_booking_start_offset);
                }

                if (this.time().isBefore(this.time(true, ebBookingStartOn))) {
                    return 'booking_not_started';
                }
            }

            if (this.time().isAfter(this.time(true, occurrence.start_on.utc))) {
                return 'event_ended';
            }

            if (this.isEventSoldOut(event, occurrence)) {
                return 'sold_out';
            }

            if (this.eventBookingIsEnded(event, occurrence)) {
                return 'booking_end';
            }

            if (this.showRemainignTicketCount(event).status) {
                type = 'ticket_remaining';
            }
        }

        return type;
    }

    static eventIsEnded(event) {
        let status = false;

        let statusData = event.extended_status.find(item => item.name == 'ended');
        status = statusData.value;

        return status;
    }

    static eventBookingIsEnded(event, occurrence = null, level = null) {
        let status = false;
        let bookingEndData = event.settings.booking_ends_on;
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);
        let haveSellSession = this.hasEventSessionForSell(event);
        let tickets = event.tickets.levels;

        if (this.isEmpty(occurrence)) {
            if (typeOfOccurrence == Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT) {
                if (bookingEndData.level == 'event') {
                    if (this.time(true, bookingEndData.utc, null).isBefore(this.time())) {
                        status = true;
                    }
                } else {
                    //For all tikcets
                    if (haveSellSession) {
                        tickets = event?.sessions?.session_lists.flatMap(session =>
                            (session.tickets ?? []).map(item => tickets.find(tc => tc.uuid == item.uuid))
                        )
                            .filter(Boolean)
                            .filter((ticket, index, self) =>
                                self.findIndex(t => t.uuid === ticket.uuid) === index // Ensure uniqueness
                            );
                    }
                    status = true;
                    for (const ticket of tickets) {
                        if (!ticket.status || (!this.isEmpty(level) && level.uuid != ticket.uuid)) continue;

                        let booEndData = ticket?.settings?.booking_ends_on;
                        if (!this.isEmpty(booEndData) && this.time(true, booEndData.utc, null).isAfter(this.time())) {
                            status = false;
                            break;
                        }
                    }
                }
            } else {
                let occurrences = event.event_occurrence;
                status = true;
                for (const occurrence of occurrences) {
                    if (occurrence.enabled == false) continue;
                    status = this.occurrenceBookingIsEnded(event, occurrence);
                    if (status == false) break;
                }
            }
        } else {
            status = this.occurrenceBookingIsEnded(event, occurrence, level);
        }

        return status;
    }

    static occurrenceBookingIsEnded(event, occurrence, level = null) {
        let status = true;
        let bookingEndData = event.settings.booking_ends_on;
        let haveSellSession = this.hasEventSessionForSell(event);
        let tickets = event.tickets.levels;

        if (bookingEndData.level == 'event') {
            if (bookingEndData.type != Constants.BOOKING_ENDS_ON.relative_to_occurrence) {
                if (this.time().isBefore(this.time(true, bookingEndData.utc, null))) {
                    status = false;
                }
            } else {
                let eb_occurrence_end = this.time(true, occurrence.end_on.utc);
                let eb_booking_end = this.getOccurrenceIndividualSettingsDateTime(eb_occurrence_end, 'UTC', bookingEndData.occurrence_booking_end_type, bookingEndData.occurrence_booking_end_offset);

                if (this.time().isBefore(this.time(true, eb_booking_end, null))) {
                    status = false;
                }
            }

        } else {
            //For all tikcets
            if (haveSellSession) {
                tickets = occurrence?.sessions.flatMap(session =>
                    (session.tickets ?? []).map(item => tickets.find(tc => tc.uuid == item.uuid))
                )
                    .filter(Boolean)
                    .filter((ticket, index, self) =>
                        self.findIndex(t => t.uuid === ticket.uuid) === index // Ensure uniqueness
                    );
            } else {
                tickets = occurrence?.tickets.map(item => tickets.find(tc => tc.uuid == item.uuid)).filter(Boolean);
            }

            let eb_occurrence_end = this.time(true, occurrence.end_on.utc);
            status = true;

            for (const ticket of tickets) {
                if (!ticket.status || (!this.isEmpty(level) && level.uuid != ticket.uuid)) continue;

                let booEndData = ticket?.settings?.booking_ends_on;

                if (booEndData.type != Constants.BOOKING_ENDS_ON.relative_to_occurrence) {
                    if (this.time().isBefore(this.time(true, booEndData.utc, null))) {
                        status = false;
                        break;
                    }
                } else {
                    let eb_booking_end = this.getOccurrenceIndividualSettingsDateTime(eb_occurrence_end, 'UTC', booEndData.occurrence_booking_end_type, booEndData.occurrence_booking_end_offset);

                    if (this.time().isBefore(this.time(true, eb_booking_end, null))) {
                        status = false;
                        break;
                    }
                }
            }
        }
        return status;
    }

    static isBookingStarted(event, occurrence = null, level = null) {
        let status = true;
        let eventTickets = event.tickets.levels;
        let eventBookingStartData = event.settings.booking_starts_on;


        if (this.isEmpty(occurrence)) {
            if (eventBookingStartData.level == 'event') {
                if (this.time().isBefore(this.time(true, eventBookingStartData.utc))) {
                    status = false;
                }
            } else {
                status = false;
                for (const ticket of eventTickets) {
                    if (!ticket.status || (!this.isEmpty(level) && level.uuid != ticket.uuid)) continue;

                    let ticketBookingStartData = ticket.settings.booking_starts_on;
                    if (this.time().isAfter(this.time(true, ticketBookingStartData.utc))) {
                        status = true;
                        break;
                    }
                }
            }

        } else {
            if (eventBookingStartData.level == 'event') {
                let ebBookingStartOn = null;
                if (eventBookingStartData.type == Constants.BOOKING_STARTS_ON.relative_to_occurrence) {
                    ebBookingStartOn = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', eventBookingStartData.occurrence_booking_start_type, eventBookingStartData.occurrence_booking_start_offset);
                } else {
                    ebBookingStartOn = eventBookingStartData.utc;
                }

                if (this.time().isBefore(this.time(true, ebBookingStartOn))) {
                    status = false;
                }
            } else {
                let occTicket = occurrence.tickets.map(ot => eventTickets.find(et => et.uuid == ot.uuid));

                status = false;
                for (const ticket of occTicket) {
                    if (!ticket.status || (!this.isEmpty(level) && level.uuid != ticket.uuid)) continue;

                    let ticketBookingStartData = ticket.settings.booking_starts_on;
                    let ebBookingStartOn = null;
                    if (ticketBookingStartData.type == Constants.BOOKING_STARTS_ON.relative_to_occurrence) {
                        ebBookingStartOn = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', ticketBookingStartData.occurrence_booking_start_type, ticketBookingStartData.occurrence_booking_start_offset);
                    } else {
                        ebBookingStartOn = ticketBookingStartData.utc;
                    }

                    if (this.time().isAfter(this.time(true, ebBookingStartOn))) {
                        status = true;
                        break;
                    }
                }
            }
        }

        return status;
    }

    static isTicketSelectionDisabled(event, occurrence = null, level, isBookingStarted, isBookingEnded) {
        let status = false;
        if (!isBookingStarted || isBookingEnded) {
            status = true;
        } else {
            let isTicketBookingStarted = this.isBookingStarted(event, occurrence, level);

            if (!isTicketBookingStarted) {
                status = true;
            } else {
                status = this.eventBookingIsEnded(event, occurrence, level);
            }
        }

        return status;
    }

    static showRemainignTicketCount(event) {
        let res = {
            status: false,
            amount: 20
        };
        let tikcetRemainignData = event.settings.configure_ticket_remaining;

        if (tikcetRemainignData.hide_on_the_event_details == false) {
            res.status = true;
            res.amount = tikcetRemainignData.remaining_tickets;
        }

        return res;
    }

    static getEventStatus(event, eventStickerType, occurrence = null) {
        let status = '';
        switch (eventStickerType) {
            case 'sold_out':
                status = 'Sold Out';
                break;
            case 'event_ended':
                status = 'Event Ended';
                break;
            case 'booking_end':
                status = 'Booking Ended';
                break;
            case 'ticket_remaining':
                let remainingTicket = 0;
                if (this.isEmpty(occurrence)) {
                    remainingTicket = this.getEventRemainingTicket(event);
                } else {
                    remainingTicket = this.getOccurrenceRemainingTicket(event, occurrence);
                }

                let showableAmount = this.showRemainignTicketCount(event).amount;

                if (remainingTicket != Constants.CAPACITY_UNLIMITED && remainingTicket <= showableAmount) {
                    status = `Only ${remainingTicket} ticket${remainingTicket > 1 ? 's' : ''} left`;
                }
                break;
            default:
                break;
        }

        return status;
    }

    static getEventRemainingTicket(event) {
        let totalRemainingTikcet = Constants.CAPACITY_UNLIMITED;
        let capacity = this.getCapacity(event);
        if (capacity != Constants.CAPACITY_UNLIMITED) {
            let totalSoldTicket = this.getTotalSoldTicketForEvent(event);
            totalRemainingTikcet = capacity - totalSoldTicket;
        }

        return totalRemainingTikcet;
    }

    static getOccurrenceRemainingTicket(event, occurrence) {
        let totalRemainingTikcet = Constants.CAPACITY_UNLIMITED;
        let occurrenceCapacity = this.getOccurrenceCapacity(event, occurrence);

        if (occurrenceCapacity != Constants.CAPACITY_UNLIMITED) {
            let totalOccSoldOutTicket = this.getTotalOccurrenceSoldTicket(event, occurrence);
            totalRemainingTikcet = occurrenceCapacity - totalOccSoldOutTicket;
        }

        return totalRemainingTikcet;
    }

    static getSessionRemainingTicket(event, session) {
        let totalRemainingTicket = Constants.CAPACITY_UNLIMITED;
        let eventRemainingTikcet = Constants.CAPACITY_UNLIMITED;
        let sessionRemainingTikcet = Constants.CAPACITY_UNLIMITED;
        let capacity = 0;
        let sessionCapacity = session?.capacity == 0 ? Constants.CAPACITY_UNLIMITED : session?.capacity;
        if (this.isEmpty(sessionCapacity)) {
            let mainSession = event?.sessions?.session_lists.find(item => item.uuid == session.uuid);
            sessionCapacity = mainSession?.capacity == 0 ? Constants.CAPACITY_UNLIMITED : mainSession?.capacity;
        }

        let sessionTickets = session?.tickets || [];
        let ticketUuids = sessionTickets.map(ticket => ticket.uuid);
        let ticketCapacity = this.getEventTicketsCapacity(event, ticketUuids);


        if (sessionCapacity != Constants.CAPACITY_UNLIMITED && ticketCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = sessionCapacity < ticketCapacity ? sessionCapacity : ticketCapacity;
        } else if (sessionCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = sessionCapacity;
        } else if (ticketCapacity != Constants.CAPACITY_UNLIMITED) {
            capacity = ticketCapacity;
        } else {
            capacity = Constants.CAPACITY_UNLIMITED;
        }

        if (capacity != Constants.CAPACITY_UNLIMITED) {
            let totalSoldTicket = 0;
            sessionTickets?.forEach(function (item) {
                totalSoldTicket += item.quantity_sold;
            });

            sessionRemainingTikcet = capacity - totalSoldTicket;
        }


        if (!Helpers.isEmpty(session.occurrence_uuid)) {
            let occurrence = event?.event_occurrence.find(occ => occ.uuid == session.occurrence_uuid);
            let occurrenceCapacity = this.getOccurrenceCapacity(event, occurrence);

            if (occurrenceCapacity != Constants.CAPACITY_UNLIMITED) {
                let totalOccSoldOutTicket = this.getTotalOccurrenceSoldTicket(event, occurrence);

                eventRemainingTikcet = occurrenceCapacity - totalOccSoldOutTicket;
            }

        } else {
            let totalEventCapacity = this.getCapacity(event);
            if (totalEventCapacity != Constants.CAPACITY_UNLIMITED) {
                let totalEventTiSold = this.getTotalSoldTicketForEvent(event);
                eventRemainingTikcet = totalEventCapacity - totalEventTiSold;
            }
        }

        if (sessionRemainingTikcet != Constants.CAPACITY_UNLIMITED && eventRemainingTikcet != Constants.CAPACITY_UNLIMITED) {
            totalRemainingTicket = eventRemainingTikcet < sessionRemainingTikcet ? eventRemainingTikcet : sessionRemainingTikcet;
        } else if (sessionRemainingTikcet != Constants.CAPACITY_UNLIMITED) {
            totalRemainingTicket = sessionRemainingTikcet
        } else if (eventRemainingTikcet != Constants.CAPACITY_UNLIMITED) {
            totalRemainingTicket = eventRemainingTikcet
        }

        return totalRemainingTicket;
    }

    static getOccurrenceIndividualSettingsDateTime(dateTime, timezoneType = 'UTC', offsetType, offset) {
        if (!dateTime || !offset || !offsetType) return '';

        if (!moment.isMoment(dateTime)) {
            if (timezoneType == 'UTC') {
                dateTime = moment.utc(dateTime);
            } else {
                dateTime = moment(dateTime);
            }
        }

        let offsetInHours = offset;
        if (offsetType == Constants.BOOKING_ENDS_ON.number_of_days) {
            offsetInHours = offset * 24;
        }

        // Subtract the offset in hours from the dateTime
        const resultDateTime = dateTime.subtract(offsetInHours, 'hours');

        return resultDateTime;
    }

    static getCountDownDomData(event, occurrence = null) {
        let res = {
            type: '',
            title: '',
            datetime: '',
            durationInDays: 0
        };

        if (this.eventIsEnded(event)) {
            return res;
        }

        //Booking will start
        let ebBookingStartDateTime = null;
        if (this.isEmpty(occurrence) || event.settings.booking_starts_on.type == Constants.BOOKING_STARTS_ON.immediate) {
            ebBookingStartDateTime = event.settings.booking_starts_on.utc;
        } else {
            ebBookingStartDateTime = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', event.settings.booking_starts_on.occurrence_booking_start_type, event.settings.booking_starts_on.occurrence_booking_start_offset);
        }


        if (!this.isEmpty(ebBookingStartDateTime)
            && event.settings.booking_starts_on.level == 'event'
            && this.time(true, ebBookingStartDateTime).isAfter(this.time(true))
            && widgetConfig?.display_booking_start_countdown !== false
        ) {
            res.type = 'booking_start';
            res.datetime = ebBookingStartDateTime;
            res.title = 'Booking will start on ';
            res.durationInDays = this.time(true, ebBookingStartDateTime).diff(this.time(true), 'days');

            return res;
        }
        //--------->

        let stickerType = this.eventStickerType(event, occurrence);

        //Offer started not end
        if (event.settings.discount.enabled
            && event.settings.discount.level == 'event'
            && !['event_ended', 'booking_end', 'sold_out'].includes(stickerType)
            && widgetConfig?.display_discount_end_countdown !== false
        ) {
            let discountIsStarted = true;
            let ebDiscountEndtDateTime = null;
            if (this.isEmpty(occurrence) || event.early_bird_discount.type == Constants.DISCOUNT_STARTS_AND_ENDS_ON.specific_time) {
                ebDiscountEndtDateTime = event.early_bird_discount.discount_ends_on.utc;

                if (event.early_bird_discount.is_enable_customise_discount_start) {
                    discountIsStarted = this.time(true, event.early_bird_discount.discount_starts_on.utc).isBefore(this.time());
                }
            } else {
                ebDiscountEndtDateTime = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', event.early_bird_discount.discount_ends_on.occurrence_discount_end_type, event.early_bird_discount.discount_ends_on.occurrence_discount_end_offset);

                if (event.early_bird_discount.is_enable_customise_discount_start) {
                    let ebDiscountStartDateTime = this.getOccurrenceIndividualSettingsDateTime(occurrence.start_on.utc, 'UTC', event.early_bird_discount.discount_starts_on.occurrence_discount_start_type, event.early_bird_discount.discount_starts_on.occurrence_discount_start_offset);

                    discountIsStarted = this.time(true, ebDiscountStartDateTime).isBefore(this.time());
                }
            }

            if (!this.isEmpty(ebDiscountEndtDateTime)
                && this.time(true, ebDiscountEndtDateTime).isAfter(this.time())
                && discountIsStarted
            ) {
                res.type = 'offer_end';
                res.datetime = ebDiscountEndtDateTime;
                res.title = 'Early birds discount will end on ';
                res.durationInDays = this.time(true, ebDiscountEndtDateTime).diff(this.time(true), 'days');

                return res;
            }
        }
        //--------->


        //Booking end
        let ebBookingEndDateTime = null;
        if (this.isEmpty(occurrence) || event.settings.booking_ends_on.type == Constants.BOOKING_ENDS_ON.continue_until_event_ends) {
            ebBookingEndDateTime = event.settings.booking_ends_on.utc;
        } else {
            ebBookingEndDateTime = this.getOccurrenceIndividualSettingsDateTime(occurrence.end_on.utc, 'UTC', event.settings.booking_ends_on.occurrence_booking_end_type, event.settings.booking_ends_on.occurrence_booking_end_offset);
        }

        if (stickerType != 'sold_out'
            && !this.isEmpty(ebBookingEndDateTime)
            && this.time(true, ebBookingEndDateTime).isAfter(this.time())
            && event.settings.booking_ends_on.level == 'event'
        ) {
            res.type = 'booking_end';
            res.datetime = ebBookingEndDateTime;
            res.title = 'Booking will end on ';
            res.durationInDays = this.time(true, ebBookingEndDateTime).diff(this.time(true), 'days');

            return res;
        }
        //--------->


        let event_start_at = null;
        let event_end_at = null;
        let haveSellSession = this.hasEventSessionForSell(event);
        if (this.isEmpty(occurrence)) {
            event_start_at = event.occurrence.attributes.starts_on.utc;
            event_end_at = this.time(true, event.occurrence.attributes.starts_on.utc).add(event.occurrence.attributes.event_duration, 'minutes');
        } else {
            event_start_at = occurrence.start_on.utc;
            event_start_at = occurrence.end_on.utc;
        }

        //Event start
        if (!this.isEmpty(event_start_at)
            && this.time(true, event_start_at).isAfter(this.time())
            && widgetConfig?.display_event_start_countdown !== false
        ) {

            res.type = 'event_start';
            res.datetime = event_start_at;
            res.title = 'The event will be started on ';
            res.durationInDays = this.time(true, event_start_at).diff(this.time(true), 'days');

            return res;
        }
        //--------->

        //Event end
        if ((!this.isEmpty(occurrence) || !haveSellSession)
            && !this.isEmpty(event_end_at)
            && this.time(true, event_end_at).isAfter(this.time())
            && widgetConfig?.display_event_end_countdown !== false
        ) {
            res.type = 'event_end';
            res.datetime = event_end_at;
            res.title = 'The event will end on ';
            res.durationInDays = this.time(true, event_end_at).diff(this.time(true), 'days');

            return res;
        }
        //--------->
    }

    static convertTimezone(datetime, fromTimezone, toTimezone, inputFormat = null, outputFormat = null) {
        // Parse the input datetime in the source timezone
        let momentObj = null;
        if (fromTimezone == 'UTC') {
            momentObj = inputFormat
                ? moment.utc(datetime, inputFormat) // Use custom format if provided
                : moment.utc(datetime); // Default to ISO format        
        } else {
            momentObj = inputFormat
                ? moment.tz(datetime, inputFormat, fromTimezone) // Use custom format if provided
                : moment.tz(datetime, fromTimezone); // Default to ISO format
        }

        // Convert to the target timezone
        const convertedDatetime = momentObj.clone().tz(toTimezone);

        return outputFormat ? convertedDatetime.format(outputFormat) : convertedDatetime;
    }

    static getTimezoneToConvertDatetime(event) {
        return event.enable_datetime_conversion ? this.getBrowserTimezone() : event.timezone
    }

    static getBrowserTimezone() {
        return Intl.DateTimeFormat().resolvedOptions().timeZone;
    }

    static initCountDownBar(event, occurrence = null) {
        let countDownDomData = this.getCountDownDomData(event, occurrence);
        if (this.isEmpty(countDownDomData?.datetime)) return;

        let dateTime = moment.isMoment(countDownDomData.datetime) ? countDownDomData.datetime : this.time(true, countDownDomData.datetime);
        let localDatetime = this.convertTimezone(dateTime, 'UTC', this.getBrowserTimezone(), null, 'MM/DD/YYYY HH:mm');
        const counter_datetime = new Date(localDatetime);

        $('#countdown').mbComingsoon({
            expiryDate: counter_datetime,
            speed: 800
        });
    }

    static eventAddToCalendar(event, visitorTime) {

        let googleCalendarUrl = '';
        let yahooCalendarUrl = '';
        let addToCalendarLink = '';

        if (event) {
            googleCalendarUrl = Config.EB_BASE_URL + '/b/event/add-to-calendar/' + event.slug + '?calendar=google&visitor-time=' + visitorTime;
            yahooCalendarUrl = Config.EB_BASE_URL + '/b/event/add-to-calendar/' + event.slug + '?calendar=yahoo&visitor-time=' + visitorTime;
            addToCalendarLink = Config.EB_BASE_URL + '/b/event/add-to-calendar/' + event.slug + '?visitor-time=' + visitorTime;
        }

        return {
            google_calendar_url: googleCalendarUrl,
            yahoo_calendar_url: yahooCalendarUrl,
            add_to_calendar_link: addToCalendarLink
        };
    }

    //Donation slider
    static initializeSlider(handleId, initialValue, min, max, stepValue) {
        $("#" + handleId).slider({
            range: "min",
            value: initialValue,
            step: stepValue,
            min: min,
            max: max,
            create: function () {
                $("#" + handleId + " .custom-handle").text(initialValue.toFixed(2));
            },
            slide: function (event, ui) {
                Helpers.updateSlider(handleId, ui.value);
            },
            start: function (event, ui) {
                Helpers.updateSlider(handleId, ui.value);
            },
            stop: function (event, ui) {
                Helpers.updateSlider(handleId, ui.value);
            }
        });
    }

    static updateSlider(handleId, value) {
        let ticketKey = handleId.slice("sliderHandle".length);
        let amount = value.toFixed(2);
        $("#" + handleId + " .custom-handle").text(amount);
        $(".donationAmount" + ticketKey).val(amount).trigger('change');
    }

    static initSliderContainer() {
        // Loop through each slider container and initialize the slider
        $(".slider-container").each(function () {
            let handleId = $(this).find('.slider-handle').attr("id");
            let defaultAmount = parseFloat($(this).data('default'));
            let min = parseFloat($(this).data('min'));
            let max = parseFloat($(this).data('max'));
            Helpers.initializeSlider(handleId, defaultAmount, min, max, 0.50);
        });
    }

    //------->

    static onupdateTicketQtyForDonation(e, args) {
        let amount = $(e).val();
        amount = amount.replaceAll(',', '');
        if (amount < 0) {
            amount = 0;
        }

        const parentDivSelector = $(e).parents('.eb-ticket-wrap');

        const ticketId = $(e).data('ticket_uuid');
        const $input = $(e).parents('.input-number-group').find('.ticket_info_quantity');
        const currency = eventDetails?.currency;
        const currencySymbol = Constants.SupportedCurrencySigns[currency];

        const defaultDonation = parseFloat($(e).data('defaultdonation'));
        const minDonation = parseFloat($(e).data('mindonation'));
        const maxDonation = parseFloat($(e).data('maxdonation'));
        const donationticketkey = $(e).data('donationticketkey');
        const sessionId = $(e).data('session_id');

        const handalerId = "#sliderHandle" + donationticketkey;
        let sliderDonationAmount = parseFloat(defaultDonation).toFixed(2);


        if (amount > 0) {
            if (args == 'change') {
                if (amount < minDonation || amount > maxDonation) {
                    $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('data-price', 0);
                    $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('value', 0);
                    $(parentDivSelector).find(`.donation_ticket_qty_${ticketId}`).val(0);

                    //Set slider data
                    $(handalerId).slider('value', sliderDonationAmount);
                    $(handalerId + " .custom-handle").text(sliderDonationAmount);

                    $(e).val('');

                    $(`.ticket_qty_for_donation_${ticketId}`).attr('data-fee-amount', 0);
                    $(`.service_charge_for${ticketId}`).html('Fee ' + currencySymbol + '0.00');
                    change_ticket_qty($input);

                    customToast("error", `The donation amount should be between ${minDonation} and ${maxDonation}.`);
                    return;
                }
            }
            $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('data-price', amount);
            $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('value', 1);
            $(parentDivSelector).find(`.donation_ticket_qty_${ticketId}`).val(1);

            sliderDonationAmount = parseFloat(amount).toFixed(2);

        } else {
            $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('data-price', 0);
            $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('value', 0);
            $(parentDivSelector).find(`.donation_ticket_qty_${ticketId}`).val(0);

            if (args == 'change') {
                $(e).val('');
                alert(`The donation amount should be between ${minDonation} and ${maxDonation}.`);
            }
        }

        //Set slider data
        $(handalerId).slider('value', sliderDonationAmount);
        $(handalerId + " .custom-handle").text(sliderDonationAmount);

        if (amount > 0 && eventDetails?.settings?.service_charge?.enabled) {
            //Need to work from here bishal
            let fee = this.feesCalculator(amount, null, null, eventDetails);

            if (typeof sessionId == 'number') {
                $(`.ticket_qty_for_donation_${ticketId}[data-session_id=${sessionId}]`).attr('data-fee-amount', fee);
                $(`.service_charge_for${ticketId}[data-session_id=${sessionId}]`).html('Includes ' + `${currencySymbol}${fee}` + ' fee');
            } else {
                $(`.ticket_qty_for_donation_${ticketId}`).attr('data-fee-amount', fee);
                $(`.service_charge_for${ticketId}`).html('Includes ' + `${currencySymbol}${fee}` + ' fee');
            }

            TicketValidation.change_ticket_qty($input);


        } else {
            $('.eb-loader').hide();

            $(`.ticket_qty_for_donation_${ticketId}`).attr('data-fee-amount', 0);
            $(`.service_charge_for${ticketId}`).html('Fee ' + currencySymbol + '0.00');

            TicketValidation.change_ticket_qty($input);
        }
    }

    static convertIntoDecimal(e) {
        var ticketPrice = e.value;
        ticketPrice = ticketPrice.replace(/,/g, "");

        if (isNaN(Number(ticketPrice)) || Number(ticketPrice) == 0) {
            $(e).val('');
            return;
        }

        let formatter = new Intl.NumberFormat('en-US', {
            style: 'decimal',
            minimumFractionDigits: 2
        });
        let formattedNumber = formatter.format(ticketPrice);
        $(e).val(formattedNumber);
    }

    static removeDonationAmount(e, donationTicketKey) {
        const parentDivSelector = $(e).parents('.eb-ticket-wrap');
        const ticketId = $(e).data('ticket_uuid');
        const $input = $(e).parents('.input-number-group').find('.ticket_info_quantity');
        const currency = eventDetails?.currency;
        const currencySymbol = Constants.SupportedCurrencySigns[currency];

        const handalerId = "#sliderHandle" + donationTicketKey;
        const defaultDonation = parseFloat($('.donationAmount' + donationTicketKey).data('defaultdonation')).toFixed(2);

        $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('data-price', 0);
        $(parentDivSelector).find(`.ticket_qty_for_donation_${ticketId}`).attr('value', 0);
        $(parentDivSelector).find(`.donation_ticket_qty_${ticketId}`).val(0);

        //Set slider data
        $(handalerId).slider('value', defaultDonation);
        $(handalerId + " .custom-handle").text(defaultDonation);

        $('.donationAmount' + donationTicketKey).val('');

        $(`.ticket_qty_for_donation_${ticketId}`).attr('data-fee-amount', 0);
        $(`.service_charge_for${ticketId}`).html('Fee ' + currencySymbol + '0.00');
        TicketValidation.change_ticket_qty($input);
    }

    static isSessionBookingEnded_x(event, sessionData, occurrence) {
        console.log(sessionData);

        let bookingEnded = false;
        let eventBookingSettings = event.settings.booking_ends_on;

        if (eventBookingSettings.level == 'event') {
            if (eventBookingSettings.type == Constants.BOOKING_ENDS_ON.specific_time || eventBookingSettings.type == Constants.BOOKING_ENDS_ON.continue_until_event_ends) {
                bookingEnded = this.time().isAfter(this.time(true, eventBookingSettings.utc));
            } else {
                bookingEnded = this.eventBookingIsEnded(event, occurrence);
            }
        } else {
            bookingEnded = this.isSessionAllTicketBookingEnded(event, sessionData);
        }


        return bookingEnded;
    }

    static isSessionAllTicketBookingEnded_x(event, sessionData) {
        let allSessionBookingEnded = true;
        let eventTickets = event.tickets.levels;
        let sessionTickets = sessionData.tickets.map(item => eventTickets.find(et => et.uuid == item.uuid));

        for (const sessTicket of sessionTickets) {
            if (this.isEmpty(sessTicket) || sessTicket.status != true) continue;

            let ticketBookingSettingsData = sessTicket?.settings?.booking_ends_on;
            if (this.time().isBefore(this.time(true, ticketBookingSettingsData.utc))) {
                allSessionBookingEnded = true;
                break;
            }
        }

        return allSessionBookingEnded;
    }

    //Timeslot initialization
    static initTimeslotContainer(event) {
        let c_date = new Date();
        let month = c_date.getMonth();
        let year = c_date.getFullYear();
        let timeslotList = null;
        let eventDateListData = null;
        let bookedEventDateListData = null;
        let bookedEventDateList = null;
        let typeOfOccurrence = this.getTheTypeOfOccurrence(event);

        if (typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.TIMESLOTS) {
            const eventDateListAndBookedData = Components.getEventDateListData(event);
            timeslotList = eventDateListAndBookedData?.timeslotList;
            eventDateListData = eventDateListAndBookedData?.eventDateList;
            bookedEventDateListData = eventDateListAndBookedData?.bookedOccurrenceListData;
            bookedEventDateList = eventDateListAndBookedData?.bookedOccurrenceList;

            if (!Helpers.isEmpty(eventDateListData)) {
                const defaultSelectedDate = this.getDefaultSelectedDate(eventDateListData);
                month = new Date(defaultSelectedDate).getMonth();
                year = new Date(defaultSelectedDate).getFullYear();
            }

            this.renderSellAppointmentCalendar(month, year, eventDateListData, bookedEventDateList, bookedEventDateListData);

            this.showAppointmentTimeslots(event, timeslotList, eventDateListData);

            this.autoSelectFirstAvailableTimeSlot();
        }

        return {
            month,
            year,
            timeslotList,
            eventDateListData,
            bookedEventDateListData,
            bookedEventDateList
        };
    }

    //For timeslot event render
    static renderSellAppointmentCalendar(m, y, eventDateListData, bookedEventDateList, bookedEventDateListData) {
        let c_date = new Date();

        //For get into waiting list button
        let bookedEventDateListDataArr = [];
        bookedEventDateListData.map(function (value, key) {
            const date = value.date;
            bookedEventDateListDataArr[date] = {...value};
            return date;
        })
        //-------->

        //Month's first weekday
        let firstDay = new Date(y, m, 1).getDay();
        //Days in Month
        let d_m = new Date(y, m + 1, 0).getDate();
        //Days in Previous Month
        let d_pm = new Date(y, m, 0).getDate();

        let table = document.getElementById('dates');
        table.innerHTML = '';
        let s_m = document.getElementById('s_m');
        s_m.innerHTML = Constants.MONTHS[m] + ' ' + y;
        let date = 1;
        //remaining dates of last month
        let r_pm = (d_pm - firstDay) + 1;
        for (let i = 0; i < 6; i++) {
            let row = document.createElement('tr');
            for (let j = 0; j < 7; j++) {
                let copparedDate = y + "-" + ("0" + (m + 1)).slice(-2) + "-" + ("0" + (date)).slice(-2);

                let eventDateInfoArr = [];
                const eventDateList = eventDateListData.map(function (value, key) {
                    const date = value.date;
                    eventDateInfoArr[date] = {...value};

                    return date;
                })

                if (i === 0 && j < firstDay) {
                    let cell = document.createElement('td');
                    let span = document.createElement('span');
                    let cellText = document.createTextNode(r_pm);
                    span.classList.add('ntMonth');
                    span.classList.add('prevMonth');
                    cell.appendChild(span).appendChild(cellText);
                    row.appendChild(cell);
                    r_pm++;
                } else if (date > d_m && j < 7) {
                    if (j !== 0) {
                        let i = 0;
                        for (let k = j; k < 7; k++) {
                            i++
                            let cell = document.createElement('td');
                            let span = document.createElement('span');
                            let cellText = document.createTextNode(i);
                            span.classList.add('ntMonth');
                            span.classList.add('nextMonth');
                            cell.appendChild(span).appendChild(cellText);
                            row.appendChild(cell);

                            let first_appointment_date_time = new Date(eventDateList[0]).getTime();
                            const cDate = y + "-" + ("0" + (m + 1)).slice(-2) + "-" + ("0" + (date > 31 ? 31 : date)).slice(-2)

                            let current_date_time = new Date(cDate).getTime();

                            if (current_date_time < first_appointment_date_time) {
                                $(row).find('span').addClass('previous_date');
                            }
                        }
                    }
                    break;
                } else {
                    let cell = document.createElement('td');
                    let span = document.createElement('span');
                    let cellText = document.createTextNode(date);

                    if (eventDateList.includes(copparedDate)) {
                        const eventDateInfo = eventDateInfoArr[copparedDate];
                        const occurrenceDateUUID = eventDateInfo['uuid'];
                        const isDefaultSelected = eventDateInfo['is_default_selected'];
                        const isUnavailable = eventDateInfo['is_unavailable'];

                        span.setAttribute('data-occurrence_uuid', occurrenceDateUUID);

                        if (isUnavailable) {
                            span.classList.add('bg-light');
                        } else {
                            span.classList.add('show_event');
                            span.classList.add('has_event');
                        }

                        if (isDefaultSelected) {
                            span.classList.add('active');
                            span.classList.add('default_selected_appointment');
                            // appointmentOccurrenceUUID = occurrenceDateUUID;
                            span.setAttribute('id', "default_selected_appointment");
                        }

                        if (date === c_date.getDate() && y === c_date.getFullYear() && m === c_date.getMonth()) {
                            span.classList.add('today');
                        }
                    } else if (bookedEventDateList.includes(copparedDate)) {
                        span.classList.add('booked_event');
                        span.setAttribute('title', 'Booked');

                        //For waiting list
                        const eventDateInfo = bookedEventDateListDataArr[copparedDate];
                        const occurrenceDateUUID = eventDateInfo['uuid'];
                        span.setAttribute('data-occurrence_uuid', occurrenceDateUUID);
                        span.classList.add('show_event');
                        //--------->

                        if (date === c_date.getDate() && y === c_date.getFullYear() && m === c_date.getMonth()) {
                            span.classList.add('today');
                        }
                    }

                    cell.appendChild(span).appendChild(cellText);
                    row.appendChild(cell);
                    date++;
                }

                let first_appointment_date_time = new Date(eventDateList[0]).getTime();
                let current_date_time = new Date(copparedDate).getTime();

                if (current_date_time < first_appointment_date_time) {
                    let hasShowEventClass = $(row).find('span').hasClass("show_event");

                    if (!hasShowEventClass) {
                        $(row).find('span').addClass('previous_date');
                    }
                }
            }

            table.appendChild(row);
        }
    }

    static getDefaultSelectedDate(eventDateListData) {
        let defaultSelectedDate = eventDateListData[eventDateListData.length - 1].date;

        eventDateListData.forEach(function (item, key) {
            if (item.is_default_selected) {
                defaultSelectedDate = item.date;
            }
        });

        return defaultSelectedDate;
    }

    static showAppointmentTimeslots(event, timeslotList, eventDateListData, showDefault = true, selectedOccurrenceUUID = null) {
        let eventOccurrence = null;
        if (showDefault) {
            eventOccurrence = this.getDefaultSelectedOccurrence(eventDateListData);
        } else {
            eventOccurrence = timeslotList?.filter(item => item.uuid == selectedOccurrenceUUID);
            eventOccurrence = eventOccurrence[0].occurrence;
        }

        let timeslotsData = Components.getAppointmentTimeslotsByOccurrence(event, eventOccurrence);
        let timeslots = timeslotsData?.time_slots;

        this.renderEventTimeslots(event, timeslots);

        this.maskAsCheckedSelectedDate(event, eventOccurrence);
    }

    static autoSelectFirstAvailableTimeSlot() {
        let availableTimeslots = $("#sellAppointmentCalender").find(".selectable.time-slotes");

        if (availableTimeslots.length) {
            let firstAvailableTimeslots = availableTimeslots.first();

            if (firstAvailableTimeslots) {
                firstAvailableTimeslots[0].click();
            }
        }
    }

    static getDefaultSelectedOccurrence(eventDateListData) {
        let defaultSelectedOccurrence = eventDateListData[eventDateListData.length - 1].occurrence;

        for (const item of eventDateListData) {
            if (item.is_default_selected) {
                defaultSelectedOccurrence = item.occurrence;
                break;
            }
        }

        return defaultSelectedOccurrence;
    }

    static renderEventTimeslots(event, timeslots) {
        if (!this.isEmpty(timeslots)) {
            if (this.eventIsEnded(event) || this.occAllTimeslotUnavailable(timeslots)) return;
            let eventsLi = '';

            timeslots.forEach(timeslot => {
                $('.events-today').html(eventsLi += `<div data-timeslot_data='${timeslot?.data}' data-timeslot_duration="${timeslot?.duration}" data-appointment_uuid="${timeslot?.uuid}" class="alert ${timeslot?.status === 'available' ? 'selectable ' : 'alert-secondary'} time-slotes eb_time_slots">
                    ${this.time(false, timeslot?.slot, 'h:mm A')}
                    <div class="status-lable"><span class=""></span>${timeslot?.duration}</div>
                </div>`);
            });
        } else {
            $('.events-today').html('<h5 class="eb-time-slot-events-empty-state">No events found</h5>');
        }
    }

    static maskAsCheckedSelectedDate(event, eventOccurrence) {
        let timeslotUnavailable = this.occAllTimeslotUnavailable(eventOccurrence?.timeslots);

        if (this.eventIsEnded(event) || timeslotUnavailable) {
            $('.timeslotBookNow').addClass('eb-disabled-all');
        } else {
            let startOn = eventOccurrence.start_on.local;
            $('.timeslotBookNow').html(`Book for ${Helpers.time(false, startOn, 'D MMMM YYYY')}`);
        }
    }

    static occAllTimeslotUnavailable(timeslots) {
        if (this.isEmpty(timeslots)) return true;

        let status = false;
        for (const timeslot of timeslots) {
            if (timeslot.status != 'unavailable') {
                status = false;
                break;
            }
            status = true;
        }

        return status;
    }

    //-------->


}

window.Helpers = Helpers;
