import $ from 'jquery';
import {Constants} from './constants';
import {Config} from '../../config';
import {Helpers} from "./helpers";
import {SessionDetailsModals} from "../component/modals/SessionDetailsModals";
import {TicketValidation} from "./ticket_validation";
import EventDetails from "../component/event-details/EventDetails";

const moment = require('moment-timezone');

export class Components {
    static getSellSessionList = (eventDetails) => {
        let activeSessions = Helpers.getActiveSessions(eventDetails);

        if (!activeSessions.length) {
            return '';
        }

        let sessionLists = "";

        let sessionCount = activeSessions.length;

        if (eventDetails?.settings?.sell_session?.enabled) {
            activeSessions.forEach(function (session, index) {
                sessionLists += Components.getSellSessionCard(session, eventDetails);
            });

            return `<section class="eb-container">
                <div class="eb-session-section">
                    <h4 class="eb-section-title">Session${sessionCount > 1 ? 's' : ''} (${sessionCount})</h4>
                    <div class="eb-session-container">
                        ${sessionLists}
                    </div>
                </div>
            </section>`
        } else {
            eventDetails?.sessions?.session_lists.forEach(function (session, index) {
                sessionLists += Components.getSessionCard(session, eventDetails);
            });

            return `<section class="eb-session-slider-section">
                <h4 class="eb-section-title">Session${sessionCount > 1 ? 's' : ''} (${sessionCount})</h4>
                <div class="eb-session-slider-container owl-carousel owl-theme">
                    ${sessionLists}
                </div>
            </section>`
        }
    }

    static getSellSessionCard = (sessionData, event) => {
        let occurrence = null;
        if(!Helpers.isEmpty(sessionData.occurrence_uuid)){
            occurrence = event?.event_occurrence.find(occ => occ.uuid == sessionData.occurrence_uuid);
        }

        let duration = Helpers.getDuration(sessionData.session_starts_on?.local, sessionData.session_ends_on?.local);

        return `<div class="eb-ss-item">
            <div class="eb-ss-thumb-wrap">
                <img class="eb-ss-thumb" src="${Helpers.getImageFullUrl(sessionData?.image || Helpers.getDefaultImagePath())}" alt="Session Thumb">
            </div>   
            <div class="eb-ss-content">
                <div class="eb-ss-head">
                    <div class="eb-ss-name-date">
                        ${this.getSessionCardTicketStatus(event, sessionData, occurrence)}

                        <h5 class="eb-ss-name">${sessionData?.name}</h5>
                        <span class="eb-ss-date">
                            ${Helpers.convertToVisitorDateTime(sessionData.session_starts_on?.utc, event.timezone)} - 
                            <span class="eb-dot-gray-left">${Helpers.displayDuration(duration)}</span>
                        </span>
                    </div>

                    ${this.getSessionPurchaseButtonDom(event, sessionData, occurrence)}
               </div>
                <div class="eb-ss-details">
                    <p>
                        ${sessionData.description ? `${Helpers.getTrimedText(sessionData.description)}...` : ''} 
                        <button onclick="Components.loadSessionDetails('${encodeURIComponent(JSON.stringify(sessionData))}')" class="eb-view-details">View details</button>
                    </p>
                </div>
            </div>   
        </div>`;
    }

    static getSessionPurchaseButtonDom(event, sessionData, occurrence){
        let res = '';
        let sessionEnded = false;
        let sessionBookingEnded = false;

        if(Helpers.time().isAfter(Helpers.time(true, sessionData.session_starts_on?.utc))){
            sessionEnded = true;
        }

        if(sessionEnded == false && Helpers.eventBookingIsEnded(event, occurrence)){
            sessionBookingEnded = true;
        }

        if(sessionEnded){
            res = `
                <button class='btn-gray-disable'>
                    Session Ended
                </button>
            `;
        }else if(sessionBookingEnded){
            res = `
                <button class='btn-gray-disable'>
                    Booking Ended
                </button>
            `;
        }else{
            res = `
                <div class="eb-ss-btn-wrap">
                    <button type="button" 
                        class="eb-btn-border" 
                        data-session_id="${sessionData.uuid}"
                        data-occurrence_uuid=""
                        onclick="TicketValidation.viewTicketsForSellSession(this, '${sessionData.uuid}', '${sessionData.occurrence_uuid??''}')"
                    >
                        Purchase Ticket
                    </button>
                </div>
            `;
        }

        return res;
    }

    static getSessionCardTicketStatus(event, session, occurrence){
        let showSessionStatus = false;
        let status = '';
        let soldOut = Helpers.isEventSoldOut(event) || Helpers.isOccurrenceTicketSoldOut(event, occurrence) || Helpers.isSessionSoldOut(event, session);
        if(soldOut){
            status = 'Sold Out';
            showSessionStatus = true;
        }else{            
            let remainingTicket = Helpers.getSessionRemainingTicket(event, session);
            let showableAmount = Helpers.showRemainignTicketCount(event).amount;

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


        return `
            <div class="eb-ss-status-wrap ${showSessionStatus?'':'eb-d-none'}">
                <i class="ebi-ticket-icon"></i> <apan>${status}</apan>
            </div>
        `;
    }

    static getSessionCard = (sessionData, eventDetails) => {
        let duration = Helpers.getDuration(sessionData.session_starts_on?.local, sessionData.session_ends_on?.local);

        return `<div class="eb-ss-slider-item" style="display: block">  
            <div class="eb-ss-slider-content">
                <div class="eb-ss-slider-thumb-wrap">
                    <img class="eb-ss--slider-thumb" src="${Helpers.getImageFullUrl(sessionData?.image || Helpers.getDefaultImagePath())}" alt="Session Thumb">
                </div> 
                <div class="eb-ss-slider-head">
                    <div class="eb-ss-slider-name-date">
                        <h4 class="eb-ss-slider-name">${sessionData?.name}</h4>
                        <span class="eb-ss-slider-date">
                            ${Helpers.convertToVisitorDateTime(sessionData.session_starts_on?.utc, eventDetails.timezone)}
                        </span>
                    </div>
               </div>
            </div>  
            <div class="eb-ss-slider-footer">
                <span class="eb-ss-slider-duration">${Helpers.displayDuration(duration)}</span>
                <button onclick="Components.loadSessionDetails('${encodeURIComponent(JSON.stringify(sessionData))}')" class="eb-btn eb-btn-ss-details">View details</button>
            </div> 
        </div>`;
    }

    static getSellSessionListForTicketPopup = (eventDetails) => {
        let activeSessions = Helpers.getActiveSessions(eventDetails);

        if (!activeSessions.length) {
            return '';
        }

        activeSessions = activeSessions.reverse();

        let sessionLists = "";

        if (eventDetails?.settings?.sell_session?.enabled) {
            activeSessions.forEach(function (session, index) {
                sessionLists += Components.getSellSessionCardForTicketPopup(session, eventDetails);
            });

            return `<section class="eb-ticket-modal-session-wrapper">
                <div class="eb-ticket-modal-session-container">
                    ${sessionLists}
                </div>
            </section>`
        }
    }

    static getSellSessionCardForTicketPopup = (sessionData, eventDetails) => {
        let duration = Helpers.getDuration(sessionData.session_starts_on?.local, sessionData.session_ends_on?.local);

        let isMultiDayEvent = Helpers.isMultiDayEvent(eventDetails);

        let dateFormat = Constants.DEFAULT_DATE_FORMAT;
        if (!isMultiDayEvent) {
            dateFormat = "h:mm A";
        }

        let dateTime= Helpers.convertToVisitorDateTime(sessionData.session_starts_on?.utc, eventDetails.timezone, dateFormat);
        let displayDuration = Helpers.displayDuration(duration);
        let sessionUuid = sessionData.uuid;
        let isEnableSessionCapacity = sessionData?.capacity >= 1;
        let sessionCapacity = sessionData?.capacity;
        let sessionTickets = Helpers.getTicketsBySessionUuid(eventDetails, sessionUuid);
        let sessionEnded = false;
        let sessionSoldOut = false;

        let levelSessionId =  sessionData?.uuid && sessionData?.occurrence_uuid ? sessionData.uuid+'_'+sessionData.occurrence_uuid : sessionData?.uuid||'';

        return `
            <input type='hidden' name='is_enable_session_capacity_${levelSessionId}' value='${isEnableSessionCapacity}'>
            <input type='hidden' name='session_capacity_${levelSessionId}' value='${sessionCapacity}'>
            <input type='hidden' name='session_order_tickets_${levelSessionId}' class='session_order_tickets' value='${Helpers.getEventOrderTicketsCount(sessionTickets)}'>
            <div class="eb-ticket-card eb_single_session_card eb-d-none popupSessionList_${sessionData.occurrence_uuid??''}" data-session_id="${sessionUuid}" data-occurrence_uuid="${sessionData.occurrence_uuid}" data-is_sold_out="${sessionSoldOut}">
                <div class="eb_ticket_main_wrap">
                    <div class="eb-ticket-wrap">
                        <div class="eb-ticket-left">
                            <div class="eb-ticket-modal-ss-thumb-wrap">
                                <img class="eb-ticket-modal-ss-thumb" src="${Helpers.getImageFullUrl(sessionData?.image || Helpers.getDefaultImagePath())}" alt="Session Thumb">
                            </div>
                            
                            <div class="eb-ticket-modal-session-data">
                                <h4>${sessionData?.name}</h4>
                                <div class="eb-ticket-ss-date-time">
                                    ${dateTime}
                                </div>
                                
                                 <div class="eb-ticket-ss-duration">
                                    ${displayDuration}
                                </div>
                            </div>
                        </div>
                        
                        <div class="eb-session-right-btn-wrap">
                            <div class="eb-ticket-modal-session-btn-wrap">
                                <button class="eb-icon-btn select_session_btn_${levelSessionId} ${sessionEnded ? 'eb-d-none' : ''}" 
                                    data-session_date="${dateTime}"
                                    data-session_duration="${displayDuration}"
                                    onclick="TicketValidation.loadSessionTickets('${levelSessionId}', this)"
                                >
                                    <i class="ebi-right-arroe"></i>
                                </button>
                                
                                <span class="eb-status-ended eb_session_ended ${sessionEnded ? '' : 'eb-d-none'}">Session Ended</span>
                            </div>
                        </div>
                    </div>
                </div>
                                    
                ${Components.getTicketDescriptionHtml(sessionData?.description)}
            </div>
        `;
    }

    static getTicketPopup(eventDetails, widgetConfig = {}, returnAsPage = false){
        const typeOfOccurrence = Helpers.getTheTypeOfOccurrence(eventDetails);
        let bookNowButtonText = Helpers.getWidgetButtonText(widgetConfig, "Continue");
        let widgetButtonStyle = Helpers.getWidgetButtonStyle(widgetConfig);
        let currency = eventDetails?.currency;
        let hasEventSessionForSell = Helpers.hasEventSessionForSell(eventDetails);
        let activeSessionsCount = Helpers.getActiveSessions(eventDetails)?.length;
        let enableFullDay = Helpers.enableFullDay(eventDetails);
        let isMultiDayEvent = Helpers.isMultiDayEvent(eventDetails);
        let isTimeSlotEvent = Helpers.isTimeSlotEvent(eventDetails);

        let isHideViewTicketsHeader = hasEventSessionForSell && typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT && isMultiDayEvent;

        let startOn = typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.SCHEDULE ? eventDetails?.occurrence?.attributes[0]?.starts_on?.utc : eventDetails?.occurrence?.attributes?.starts_on?.utc
        let shortDate = Helpers.convertToVisitorDateTime(startOn, eventDetails.timezone, 'dddd, MMM DD', true);

        let eventStartTime = Helpers.convertToVisitorDateTime(startOn, eventDetails.timezone, 'h:mm A', true);

        let eventDuration = typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.SCHEDULE ? eventDetails?.occurrence?.attributes[0]?.starts_on?.utc : eventDetails?.occurrence?.attributes?.event_duration;
        let endAt = Helpers.addTimeWithDate(startOn, eventDuration, 'minutes');
        let eventEndTime = Helpers.convertToVisitorDateTime(endAt, eventDetails.timezone, 'h:mm A', true);

        let duration = Helpers.getDuration(startOn, endAt.format(Constants.DEFAULT_DATE_FORMAT));

        let locationContent = "";
        if (eventDetails?.configuration?.type === Constants.EVENT_TYPE.VENUE) {
            let eventVenue = Helpers.getEventVenue(eventDetails);

            if (Helpers.isEmpty(eventVenue)) {
                locationContent = `<i class="ebi-icon-location"></i><span>To Be Announced</span>`;
            } else {
                let eventVenueAddress = eventVenue?.address;
                locationContent = `<i class="ebi-icon-location"></i><span>${eventVenue ? `<span>${eventVenue.name}</span>,` : ''} ${Helpers.getEventAddress(eventVenueAddress)}</span>`;
            }
        } else if (eventDetails?.configuration?.type === Constants.EVENT_TYPE.ONLINE) {
            locationContent = `<svg width="17" height="11" viewBox="0 0 23 15" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <path d="M0.000183105 0V14.524H16.3932V10.186L22.8802 13.932V0.591999L16.3932 4.338V0H0.000183105ZM14.8482 12.979H1.54018V1.545H14.8402L14.8482 12.979ZM21.3402 3.267V11.247L16.3972 8.402V6.122L21.3402 3.267Z" fill="white"></path>
                                </svg> <span>Online events</span> `;
        }

        return `<div id="ticketModal" class="eb-modal-wrapper eb-ticket-modal ${returnAsPage ? '' : 'eb-d-none'}" style="${returnAsPage ? 'position:relative' : ''}">
            <div class="eb-modal-wrap price_calculator_scope">
                <div class="eb-modal-dialog">
                    <div class="eb-modal-content">
                    
                        <div class="eb-modal-header">
                            <div class="eb-modal-ticket-name">
                                <h5>${Helpers.getEventDisplayName(eventDetails)}</h5>
                                <div class="eb-ticket-address">
                                    ${locationContent}
                                </div>
                           </div>
                            <div class="eb-ticket-date-time ${typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.TIMESLOTS || isHideViewTicketsHeader ? 'eb-d-none' : ''}">
                                <div class="eb-ticket-date">
                                    <h5>Date ${enableFullDay ? Helpers.convertToVisitorDateTime(startOn, eventDetails.timezone, '', false, true) : ''}</h5>
                                    <span class="eventHeaderDateTime">
                                        ${typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT ? `
                                            ${shortDate}
                                        ` : `
                                            Multiple Dates
                                        `}
                                    </span>
                                </div>
                                <div class="eb-ticket-time ${enableFullDay ? 'eb-d-none' : ''}">
                                    <h5>
                                        Time ${Helpers.convertToVisitorDateTime(startOn, eventDetails.timezone, '', false, true)}
                                    </h5>
                                    
                                    ${!hasEventSessionForSell ? `
                                        ${typeOfOccurrence === Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT ? `
                                            <span>
                                                ${eventStartTime} ${!Helpers.isMultiDayEvent(eventDetails) ? '- '+eventEndTime : ''}

                                                ${Helpers.isEmpty(Helpers.getActiveSessions(eventDetails)) ? `(${Helpers.displayDuration(duration)})` : ``}
                                            </span>
                                        ` : `
                                            <span class="occurrenceDuration"></span>
                                        `}
                                    ` : `
                                        <span class="eb_active_session_string" data-is_multiple_session="${activeSessionsCount > 1}">
                                            ${activeSessionsCount > 1 ? `
                                                Multiple Sessions
                                            ` : ``}
                                            
                                            ${activeSessionsCount === 1 ? `
                                                Session
                                            ` : ``}
                                        </span>
                                    `}
                                 </div>
                            </div>
                            <button onclick="Components.closeEventTicketPopup()" type="button" class="eb-modal-close"><i class="ebi-icon-close"></i></button>
                        </div>
 
                        <div class="eb-modal-body">
                            <div id="ticketModalBody">
                                ${Components.getTicketFormHtml(eventDetails?.tickets, eventDetails, '', widgetConfig)} 
                            </div>

                            ${Components.getCalenderHtml(eventDetails)}
                        </div>
                        
                        
                        <div class="eb-modal-footer eb_ticket_and_merchandise_element ${isTimeSlotEvent ? 'eb-d-none' : ''}">
                            <div>
                                <div class="eb-ticket-price">
                                    ${Constants.SupportedCurrencySigns[currency]}<span class="display_total_price">0.00</span><span> ${currency}</span>
                                </div>
                                
                                <div class="d-flex justify-content-start selected-ticket-status mb-0 mb-md-0">
                                    <span class="selected-session-wrapper font-12 mr-1 color-dark2" style="display: none;"><span>0</span>x Session<span></span> + </span>
                                    <span class="selected-ticket-wrapper font-12 color-dark2  mr-1 mb-0" style="display: none"><span>4</span>x Ticket<span></span> </span>
                                    <span class="selected-merchandise-wrapper font-12 color-dark2 mr-0" style="display: none;"> + <span>0</span>x Merchandise<span>0</span></span>
                                </div>
                            </div>
                            
                            <button onclick="TicketValidation.submitTicketForm()" type="button" class="eb-btn-black ticketSubmitBtn occSubBtn" ${widgetButtonStyle}>Continue</button>
                        </div>
                        
                        <div class="eb-modal-footer eb_sell_appointment_element ${isTimeSlotEvent ? '' : 'eb-d-none'}">
                            <div>
                               
                            </div>
                            
                            <button onclick="TicketValidation.sellAppointmentBookNow(this)" type="button" class="eb-btn-black ticketSubmitBtn timeslotBookNow" ${widgetButtonStyle}>Book Now</button>
                        </div>
                    </div>
                </div>
            </div>
        </div>`;
    }

    static getTicketListHtml(tickets, eventDetails, selectedOccurrenceUuid = null) {
        let timezone = eventDetails?.timezone;
        let currency = eventDetails?.currency;
        let isRecurringEvent = Helpers.isRecurringEvent(eventDetails);
        let selectedOccurrenceStartsOnInUtc = "";
        let selectedOccurrenceStartsOn = "";
        let hasEventSessionForSell = Helpers.hasEventSessionForSell(eventDetails);
        let isSoldOut = false;
        let isBookingStarted = true;
        let isBookingEnded = false;
        let selectedOccurrence = null;

        if (selectedOccurrenceUuid) {
            selectedOccurrence = Helpers.getOccurrenceDetailsByUuid(eventDetails, selectedOccurrenceUuid);

            if (selectedOccurrence) {
                selectedOccurrenceStartsOnInUtc = selectedOccurrence?.start_on?.utc;
                selectedOccurrenceStartsOn = selectedOccurrence?.start_on?.local;
            }
        }
        
        isSoldOut = Helpers.isEventSoldOut(eventDetails, selectedOccurrence);
        isBookingStarted = Helpers.isBookingStarted(eventDetails, selectedOccurrence);
        isBookingEnded = Helpers.eventBookingIsEnded(eventDetails, selectedOccurrence);

        let ticketHtml = '';
        if(Helpers.isEmpty(tickets?.levels)) return ticketHtml;

        tickets.levels.forEach(function (level, index) {
            if (!level?.status) {
                return false;
            }

            let levelSessionId =  level?.session_uuid && level?.occurrence_uuid ? level.session_uuid+'_'+level.occurrence_uuid : level?.session_uuid||'';
            let hasVariation = Helpers.ticketHasVariations(level);
            let maxTicketLimit = Helpers.getMaxTicketLimit(level);

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

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

            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;

            let eventSettings = eventDetails?.settings?.booking_starts_on?.level === 'event' ? eventDetails?.settings : level?.settings;
            let bookingStartingTimeInUtc = eventSettings?.booking_starts_on?.utc;
            let bookingNotImmediate = eventSettings?.booking_starts_on?.type !== 'immediate';

            if (isRecurringEvent && eventSettings?.booking_starts_on?.type === 'relative_to_occurrence' && selectedOccurrenceStartsOnInUtc) {
                let occurrenceBookingStartType = eventSettings?.booking_starts_on?.occurrence_booking_start_type === 'number_of_hours' ? 'hours' : 'days';
                bookingStartingTimeInUtc = moment(selectedOccurrenceStartsOnInUtc).subtract(eventSettings?.booking_starts_on?.occurrence_booking_start_offset, occurrenceBookingStartType).format('YYYY-MM-DD HH:mm');
            }

            let isTicketBookingNotStarted = bookingStartingTimeInUtc ? bookingNotImmediate && Helpers.calculateTimeDurationInSecFromUtc(bookingStartingTimeInUtc) > 0 : false;
            if (isTicketBookingNotStarted) {
                if (eventSettings?.booking_starts_on?.hide_ticket_until_booking_start) {
                    return null;
                }
            } else bookingStartingTimeInUtc = '';

            level.hasBookingStarted = !isTicketBookingNotStarted;
            level.bookingStartingTimeInUtc = bookingStartingTimeInUtc;
            level.earlyBirdDiscountEndsOnUTc = discountEndsOnUtc;

            let showSoldOutTag = false;
            if(!isSoldOut){
                if(hasEventSessionForSell){
                    showSoldOutTag = level.session_sold_out || level.occurrence_sold_out;
                }

                //Check if ticket is sold out or not
                showSoldOutTag = showSoldOutTag ? showSoldOutTag : Helpers.isTicketSoldOut(level);

            }else{
                showSoldOutTag = true;
            }

            let disabledTicketSelection = Helpers.isTicketSelectionDisabled(eventDetails, selectedOccurrence, level, isBookingStarted, isBookingEnded);

            if(disabledTicketSelection && (level?.settings?.booking_starts_on?.hide_ticket_until_booking_start || eventDetails?.settings?.booking_starts_on?.hide_ticket_until_booking_start)) return '';

            if (hasVariation) {

                let isChildGroupTicket = false;
                let variationTicketHtml = '';
                if (level?.pricing_details) {
                    level?.pricing_details.forEach(function (variationLevel) {

                        if (variationLevel?.quantity_included > 1 && !isChildGroupTicket) {
                            isChildGroupTicket = true;
                        }

                        let pricingDetails = variationLevel;
                        const discPrice = type ? Helpers.discountCalculate(pricingDetails?.price, discountEndsOnLocal, type?.discount_type, type?.discount, timezone) : 0;
                        let priceWithDiscount = +pricingDetails?.price - +discPrice;

                        let fee = Helpers.feesCalculator(discPrice !== 0 ? priceWithDiscount : pricingDetails?.price, level, pricingDetails, eventDetails);

                        let ticketPrice = discPrice ? priceWithDiscount + fee : pricingDetails?.price + fee;

                        variationTicketHtml += `
                        <div class="eb_ticket_main_wrap eb-variation-ticket-wrap">
                            <div class="eb-ticket-wrap">
                                <div class="eb-ticket-left">
                                    <h4>${variationLevel?.variation}</h4>
                                    <div class="eb-ticket-price-wrap">
                                         ${discPrice ? `
                                            <span>${Helpers.getPriceHtml(ticketPrice, currency)}</span>
                                            <strike>${Helpers.getPriceHtml(pricingDetails?.price + fee, currency)}</strike>
                                        ` : `
                                            <span>${Helpers.getPriceHtml(ticketPrice, currency)}</span>
                                        `}
                                    </div>
                                    
                                    <div class="eb-d-flex eb-align-item-center">
                                        ${Components.getTicketIncludesFeeHtml(fee, currency, level, levelSessionId)}
    
                                        ${variationLevel?.minimum_quantity?.quantity ? `
                                            <div class="eb-minimum-quantity-content">
                                                <span class="">
                                                    ${variationLevel?.minimum_quantity?.mandatory ? 'Mandatory - ' : ''}Min QTY: ${variationLevel?.minimum_quantity?.quantity}
                                                </span>
                                            </div>
                                        ` : ``}
                                    </div>
                                    
                                    ${Components.getGroupTicketEachContainsHtml(variationLevel?.quantity_included)}
                                </div>

                                ${Components.getTicketSelectionDom(eventDetails, level, variationLevel, showSoldOutTag, levelSessionId, priceWithDiscount, fee, 'variation_ticket', disabledTicketSelection)}
                            </div>
                            
                            <span class="insert_error_after"></span>
                        </div>`;
                    })
                }

                ticketHtml += `
                    
                    <div class="eb-ticket-card eb_single_ticket_wrapper eb_ticket_session_id_${levelSessionId} ${hasEventSessionForSell ? 'eb-d-none' : ''} ${isChildGroupTicket ? 'eb-group-ticket-variation-wrap' : 'eb-single-ticket-variation-wrap'}">
                        ${Components.getTicketBookingStartEndStatusHtml(bookingStartingTimeInUtc, eventDetails, level, selectedOccurrenceStartsOn)}
                    
                        <input type='hidden' name='${level.uuid}_is_enable_ticket_capacity' value='${level.quantity > 0}' data-session_id='${levelSessionId}'>
                        <input type='hidden' name='${level.uuid}_ticket_capacity' value='${level.quantity}' data-session_id='${levelSessionId}'>
                        <input type='hidden' name='${level.uuid}_total_order_tickets' value='${level.quantity_sold}' data-session_id='${levelSessionId}'>
                                       
                        <div class="eb-ticket-group-title">
                            <h4>${level?.name}</h4>
                        </div>
                        
                        ${variationTicketHtml}
                        
                        ${Components.getTicketDescriptionHtml(level?.description)}
                    </div>
                `;
            } else {

                let pricingDetails = level?.pricing_details[0];
                let isDonation = level.category === Constants.TICKET_CATEGORY.DONATION;
                const discPrice = type ? Helpers.discountCalculate(pricingDetails?.price, discountEndsOnLocal, type?.discount_type, type?.discount, timezone) : 0;
                
                let priceWithDiscount = +pricingDetails?.price - +discPrice;
                
                let fee = Helpers.feesCalculator(discPrice !== 0 ? priceWithDiscount : pricingDetails?.price, level, pricingDetails, eventDetails);

                let ticketPrice = discPrice ? priceWithDiscount + fee : pricingDetails?.price + fee;

                let isGroupTicket = pricingDetails.quantity_included > 1;



                let priceSection = '';
                if(isDonation){
                    let addDisbaleClass = level.min_donation_amount == level.max_donation_amount ? 'opacity05':'';

                    priceSection = `
                        <div class='slider-container ${addDisbaleClass} ${disabledTicketSelection?'eb-disabled-all':''}' id='sliderContainer${level.uuid}${levelSessionId}' data-default='${level.default_donation_amount}' data-min='${level.min_donation_amount}' data-max='${level.max_donation_amount}'>
                            <div class='justify-content-between d-flex slider-label-text'>
                                <span>${Helpers.getPriceHtml(level.min_donation_amount, currency)}</span>
                                <span>${Helpers.getPriceHtml(level.max_donation_amount, currency)}</span>
                            </div>
                            <div class='slider-handle' id='sliderHandle${level.uuid}${levelSessionId}'>
                            <!-- <div class='custom-handle ui-slider-handle'></div> -->
                            </div>
                        </div>
                    `;
                }else{
                    priceSection = `
                        ${discPrice ? `
                            <span>${Helpers.getPriceHtml(ticketPrice, currency)}</span>
                            <strike>${Helpers.getPriceHtml(pricingDetails?.price + fee, currency)}</strike>
                        ` : `
                            <span>${Helpers.getPriceHtml(ticketPrice, currency)}</span>
                        `}
                    `;
                }

                ticketHtml += `
                <div class="eb-ticket-card eb_single_ticket_wrapper eb_ticket_session_id_${levelSessionId} ${hasEventSessionForSell ? 'eb-d-none' : ''} ${isGroupTicket ? 'eb-group-ticket-wrap' : 'eb-single-ticket-wrap'} ${isDonation ? 'eb-ticket-modal-donation-ticket-wrap' : ''}">
                    ${Components.getTicketBookingStartEndStatusHtml(bookingStartingTimeInUtc, eventDetails, level, selectedOccurrenceStartsOn)}
                    <div class="eb_ticket_main_wrap">
                        <div class="eb-ticket-wrap">
                            <div class="eb-ticket-left">
                                <h4>${level?.name}</h4>
                                <div class="eb-ticket-price-wrap">
                                    ${priceSection}
                                </div>
                                
                                <div class="eb-d-flex eb-align-item-center">
                                    ${Components.getTicketIncludesFeeHtml(fee, currency, level, levelSessionId)}

                                    ${level?.settings?.minimum_quantity?.quantity ? `
                                        <div class="eb-minimum-quantity-content">
                                            <span class="">
                                                ${level?.settings?.minimum_quantity?.mandatory ? 'Mandatory - ' : ''}Min QTY: ${level?.settings?.minimum_quantity?.quantity}
                                            </span>
                                        </div>
                                    ` : ``}
                                </div>
    
                                ${Components.getGroupTicketEachContainsHtml(pricingDetails.quantity_included)}
                            </div>
                            
                            ${Components.getTicketSelectionDom(eventDetails, level, null, showSoldOutTag, levelSessionId, priceWithDiscount, fee, isDonation?'donation_ticket':'normal_ticket', disabledTicketSelection)}
                        </div>
                        
                        <span class="insert_error_after"></span>
                        <!--<div class="max-ticket-exceeded-error">There are no tickets available to add.</div>-->
                    </div>
                                        
                    ${Components.getTicketDescriptionHtml(level?.description)}
                </div>`;
            }
        })

        return ticketHtml;
    }

    static getTicketSelectionDom(event, level, variationLevel=null, showSoldOutTag, levelSessionId, priceWithDiscount, fee, type, disabledTicketSelection){
        let res = '';
        let maxTicketLimit = Helpers.getMaxTicketLimit(level);
        let hasEventSessionForSell = Helpers.hasEventSessionForSell(event);
        let currency = event?.currency;
        
        if(type == 'normal_ticket'){
            let pricingDetails = level?.pricing_details[0];
            let ticketInputName = `ticket_info[${level.uuid}][quantity]`;
            if (hasEventSessionForSell) {
                ticketInputName += `[${levelSessionId}]`;
            }

            res = `
                <div class="eb-ticket-right-b-wrap ${disabledTicketSelection?'eb-disabled-all':''}">
                    <div class='sold-out-get-waiting-wrap ${showSoldOutTag?'':'eb-d-none'}'>
                        <span class='eb-soldout-status eb-disabled-all'>Sold Out</span>
                    </div>

                    <div class="eb-ticket-right-btn ${showSoldOutTag?'eb-d-none':''}">
                    
                        <input type="hidden" name="ticket_info[${level.uuid}][total_ticket_per_group]" class="${level.uuid}_total_ticket_per_group" value="${pricingDetails?.quantity_included}">
                    
                        <div class="eb-input-number">
                            <button class="eb-input-number-decrement" type="button" onclick="TicketValidation.inputNumberDecrement(this)">
                                <i class="ebi-minus-solid"></i>
                            </button>

                            <input type="number"
                                name="${ticketInputName}"
                                class="ticket_info_quantity eb_ticket_qty ${level.uuid}"
                                data-id="${level.uuid}"
                                data-max="${maxTicketLimit}"
                                data-min="${level?.settings?.minimum_quantity?.quantity}"
                                data-mus-be-purchase="${level?.settings?.minimum_quantity?.mandatory}"
                                min="0"
                                data-ticket-type="${level.name}"
                                data-session_id="${levelSessionId}"
                                data-occ_uuid="${level?.occurrence_uuid}"
                                data-price="${priceWithDiscount}"
                                data-fee-amount="${fee}"
                                onchange="TicketValidation.onupdateTicketQty(this)"
                                value="0"
                            />
                            
                            <button type="button" class="eb-input-number-increment input-number-increment" onclick="TicketValidation.inputNumberIncrement(this)">
                                <i class="ebi-plus-solid"></i>
                            </button>
                        </div>
                    </div>
                </div>
            `;
        }else if(type == 'variation_ticket'){
            let ticketInputName = `ticket_info[${level.uuid}][subtype][${variationLevel.uuid}][quantity]`;
            if (hasEventSessionForSell) {
                ticketInputName += `[${levelSessionId}]`;
            }

            res = `
                <div class="eb-ticket-right-b-wrap ${disabledTicketSelection?'eb-disabled-all':''}">
                    <div class='sold-out-get-waiting-wrap ${showSoldOutTag?'':'eb-d-none'}'>
                        <span class='eb-soldout-status eb-disabled-all'>Sold Out</span>
                    </div>
                    <div class="eb-ticket-right-btn ${showSoldOutTag?'eb-d-none':''}">
                        <input type="hidden" name="ticket_info[${level.uuid}][subtype][${variationLevel.uuid}][total_ticket_per_group]" class="${variationLevel.uuid}_total_ticket_per_group" value="${variationLevel?.quantity_included}">

                        <div class="eb-input-number">
                            <button type="button" class="eb-input-number-decrement" onclick="TicketValidation.inputNumberDecrement(this)">
                                <i class="ebi-minus-solid"></i>
                            </button>
                            
                            <input type="number" value="0"
                                class="ticket_info_quantity eb_ticket_qty ${level.uuid}"
                                data-max="${maxTicketLimit}"
                                data-min="${variationLevel?.minimum_quantity?.quantity}"
                                data-mus-be-purchase="${variationLevel?.minimum_quantity?.mandatory}"
                                min="0"
                                data-mus-be-purchase="0"
                                data-id="${level.uuid}"
                                data-ticket-type="${level.name}"
                                data-ticket="${variationLevel.uuid}"
                                data-price="${priceWithDiscount}"
                                data-fee-amount="${fee}"
                                data-session_id="${levelSessionId}"
                                data-occ_uuid="${level?.occurrence_uuid}"
                                name="${ticketInputName}"
                                data-is_group_variation="${variationLevel?.quantity_included > 1}"
                                data-sub_ticket_id="${variationLevel.uuid}"
                                onchange="TicketValidation.onupdateTicketQty(this)"
                            />
                            
                            <button type="button" class="eb-input-number-increment input-number-increment" onclick="TicketValidation.inputNumberIncrement(this)">
                                <i class="ebi-plus-solid"></i>
                            </button>
                        </div>
                    </div>
                </div>
            `;
        }else if(type == 'donation_ticket'){
            let pricingDetails = level?.pricing_details[0];
            let ticketInputNameDonationAmount = `ticket_info[${level.uuid}][donation_amount]`;
            let ticketInputName = `ticket_info[${level.uuid}][quantity]`;
            if (hasEventSessionForSell) {
                ticketInputNameDonationAmount += `[${levelSessionId}]`;
                ticketInputName += `[${levelSessionId}]`;
            }

            res = `
                <input type='hidden' class='donation_ticket_qty_${level.uuid}' name='${ticketInputName}' value='0' autocomplete='off'>
                <input type='hidden' name='ticket_info[${level.uuid}][is_group]' value='NO' autocomplete='off'>
                <input type='hidden' name='ticket_info[${level.uuid}][total_ticket_per_group]' value='${pricingDetails?.quantity_included}' autocomplete='off'>

                <div class='select-input-group input-number-group eb-donation-ticket-wrap ${disabledTicketSelection?'eb-disabled-all':''}'>
                    <div class='input-group number-input input-value-remove'>
                        <div class='input-group-append border-left'>
                            <span class='input-group-text border-left'>${currency}</span>
                        </div>
                        <input type='hidden' class='increment eb_ticket_qty ticket_qty_for_donation_${level.uuid} ${level.uuid} ticket_info_quantity'
                            value='0' autocomplete='off'
                            data-max='${maxTicketLimit}' data-id='${level.uuid}' data-ticket-type='${level.name}' data-ticket='${level.uuid}'
                            data-price='0' data-min='${level?.settings?.minimum_quantity?.quantity}'
                            data-mus-be-purchase='${level?.settings?.minimum_quantity?.mandatory}'
                            min='0' max='${maxTicketLimit}' data-fee-amount='0'
                            data-is_donation_ticket='true'
                            data-session_id='${levelSessionId}'
                            data-occ_uuid='${level?.occurrence_uuid}'>
                        
                        <input type='hidden' name='ticket_info[${level.uuid}][is_donation_ticket]' value='true'>
                        
                        <input type='text' class='form-control donation_ticket_qty filter-grayscale donationAmount${level.uuid}${levelSessionId}'
                            placeholder='${level.default_donation_amount}' name='${ticketInputNameDonationAmount}'
                            data-ticket_uuid='${level.uuid}' data-event_id='${event.uuid}'
                            data-session_id='${levelSessionId}'
                            data-occ_uuid='${level?.occurrence_uuid}'
                            data-defaultdonation='${level.default_donation_amount}'
                            data-mindonation='${level.min_donation_amount}' data-maxdonation='${level.max_donation_amount}'
                            data-donationticketkey='${level.uuid}${levelSessionId}'
                            onkeyup='Helpers.onupdateTicketQtyForDonation(this)'
                            onkeypress='Helpers.onupdateTicketQtyForDonation(this)'
                            onchange='Helpers.onupdateTicketQtyForDonation(this, "change")'
                            onblur='Helpers.convertIntoDecimal(this)'>
                        
                        <input type='hidden' name='ticket_info_json_data' value='$ticket_info'>
                        
                        <input type='hidden' name='fee_amount_per_ticket_${level.uuid}' value='${fee}'>
                        
                        <span class='eb-remove-donation-amount-btn' type='button' data-ticket_uuid='${level.uuid}' onclick='Helpers.removeDonationAmount(this,"${level.uuid}${levelSessionId}")'>
                            <i class="ebi-icon-close"></i>
                        </span>

                    </div>
                </div>
            `;
        }

        return res;
    }

    static getTicketFormHtml(tickets, eventDetails, selectedOccurrenceUuid=null, widgetConfig = null) {
        let timezone = eventDetails?.timezone;
        let currency = eventDetails?.currency;
        let isRecurringEvent = Helpers.isRecurringEvent(eventDetails);
        let isTicketPageWidget = Helpers.isTicketPageTypeWidget(widgetConfig);
        let isButtonWidget = Helpers.isButtonTypeWidget(widgetConfig);
        let hasEventSessionForSell = Helpers.hasEventSessionForSell(eventDetails);
        let isTimeSlotEvent = Helpers.isTimeSlotEvent(eventDetails);

        let totalActiveSession = 0
        if (hasEventSessionForSell) {
            // With short data
            let allSessionTickets = [];

            if (!Helpers.isEmpty(eventDetails?.sessions?.session_lists)) {
                if(isRecurringEvent){
                    allSessionTickets = eventDetails?.event_occurrence?.flatMap(occurrence => {
                        let occurrenceSoldOut = Helpers.isOccurrenceTicketSoldOut(eventDetails, occurrence);

                        return (occurrence.sessions ?? []).flatMap(session => {
                            let sessionSoldOut = Helpers.isSessionSoldOut(eventDetails, session);

                            return (session.tickets ?? []).map(ticket => ({
                                ...ticket,
                                session_uuid: session.uuid,
                                occurrence_uuid: occurrence.uuid,
                                session_sold_out: sessionSoldOut,
                                occurrence_sold_out: occurrenceSoldOut,
                            }));
                        })
                    });

                }else{
                    eventDetails?.sessions?.session_lists?.forEach(function (item) {
                        let sessionSoldOut = Helpers.isSessionSoldOut(eventDetails, item);
                        if (item?.tickets?.length) {
                            item?.tickets?.forEach(function (tkt) {
                                tkt.session_uuid = item.uuid;
                                tkt.session_sold_out = sessionSoldOut;
                                allSessionTickets.push(tkt);
                            })
                        }
                    });

                    totalActiveSession = Helpers.getActiveSessions(eventDetails).length;
                }
            }

            tickets = Helpers.makeTicketsListWithFullDataFromShortData(eventDetails, allSessionTickets);
        }

        let ticketHtml = Components.getTicketListHtml(tickets, eventDetails, selectedOccurrenceUuid);

        let merchandiseListHtml = '';
        let merchandiseHtml = '';

        if (!Helpers.isEmptyObject(eventDetails?.merchandise)) {
            eventDetails?.merchandise?.products.forEach(function (product, index) {
                if (!product?.status) {
                    return
                }

                let fee = Helpers.feesCalculator(product?.price, product, product, eventDetails);
                let max = product?.max_per_order || 9999999;
                let min = product?.min_per_order || 0;

                merchandiseListHtml += `<div class="eb-ticket-card eb-ticket-modal-product-container">
                    <div class="eb_ticket_main_wrap">
                        <div class="eb-ticket-wrap">
                            <div class="eb-ticket-left">
                                <div class="eb-ticket-modal-product-thumb-wrap">
                                    <img style="width: 100%" class="eb-ticket-modal-product-ss-thumb" src="${Helpers.getImageFullUrl(product?.image || Helpers.getDefaultImagePath())}" alt="Product Thumb">
                                </div>
                                
                                <div class="eb-ticket-modal-product-data">
                                    <h4>${product?.name}</h4>
                                    <div class="eb-ticket-price-wrap">
                                        <span>${Helpers.getPriceHtml(product?.price + fee, currency)}</span> 
                                    </div>
                                    
                                    <div class="eb-ticket-modal-product-fee">
                                        ${Components.getTicketIncludesFeeHtml(fee, currency)} 
                                    </div>
                                </div>
                            </div>
                            
                            <div class="eb-ticket-modal-product-right-btn-wrap">
                                <div class="eb-ticket-right-btn">                 
                                    <div class="eb-input-number">
                                        <button class="eb-input-number-decrement" type="button" onclick="TicketValidation.inputNumberDecrement(this)">
                                            <i class="ebi-minus-solid"></i>
                                        </button>
    
                                        <input type="number"
                                            name="merchant_product_info[${product.uuid}][quantity]"
                                            class="ticket_info_quantity eb_ticket_qty ${product.uuid}"
                                            data-id="${product.uuid}"
                                            data-max="${max}"
                                            data-min="${min}"
                                            min="${min}"
                                            max="${max}"
                                            data-ticket-type="${product.name}"
                                            data-price="${product?.price}"
                                            data-fee-amount="${fee}"
                                            data-is_product="true"
                                            data-is_merchandise="true"
                                            onchange="TicketValidation.onupdateTicketQty(this)"
                                            value="0"
                                        />
                                        
                                        <button type="button" class="eb-input-number-increment input-number-increment" onclick="TicketValidation.inputNumberIncrement(this)">
                                            <i class="ebi-plus-solid"></i>
                                        </button>
                                    </div>
                                </div>
                            </div>
                        </div>
                        
                        <span class="insert_error_after"></span>
                    </div>
                                        
                    ${Components.getTicketDescriptionHtml(product?.description)}
                </div>`;
            })

            if (merchandiseListHtml) {
                merchandiseHtml += `<div id="ebMerchantProductsSection" class="eb-d-none">
                    <div class="" style="position: relative;padding-bottom: 16px">
                        <span onclick="TicketValidation.showEventTickets(this)" class="" style="position: absolute">
                            <svg width="14" height="14" viewBox="0 0 14 14" fill="none" xmlns="http://www.w3.org/2000/svg">
                                <path d="M6.99992 13.6667L0.333252 7.00004L6.99992 0.333374L8.18742 1.50004L3.52075 6.16671H13.6666V7.83337H3.52075L8.18742 12.5L6.99992 13.6667Z" fill="black"></path>
                            </svg>
                        </span>
                        <div class="" style="text-align: center">Add Products</div>
                    </div>
                    
                    ${merchandiseListHtml}
                </div>`;
            }
        }

        let isEnabledInvitationCodeRestriction = Helpers.isEnabledInvitationCodeRestriction(eventDetails);
        let invitationCodeRestriction = Helpers.getInvitationCodeRestriction(eventDetails);

        let sessionListHtml = "";
        if (hasEventSessionForSell) {
            sessionListHtml = Components.getSellSessionListForTicketPopup(eventDetails);
        }

        return `
            <div class="eb-modal-body-inner">
            
                <div class="" id="eventSessionSection">
                    <div class="eb-widget-occurrence-list-dropdown ${hasEventSessionForSell && isRecurringEvent ? '' : 'eb-d-none'}">
                        ${(isTicketPageWidget || isButtonWidget) && hasEventSessionForSell && isRecurringEvent ? Components.getOccurrenceDropdown(eventDetails, selectedOccurrenceUuid, 'ticket_popup') : ``}
                    </div>
                    ${sessionListHtml}
                </div>
            
                 ${hasEventSessionForSell ? `
                    <div class="eb-ticket-modal-add-btn-wrap eb_ticket_element eb-d-none">
                        <span onclick="TicketValidation.showEventSessionList()" class="eb-ticket-modal-back-arrow-wrap backToSessionListFromTicketList">
                            <i class="ebi-left-arrow"></i>
                        </span>
                        <h4>Add Tickets</h4>
                    </div>
                ` : ``}
            
                 ${isTimeSlotEvent ? `
                    <div class="eb-ticket-modal-add-btn-wrap eb_ticket_element eb-d-none">
                        <span onclick="TicketValidation.showEventAppointmentCalendar(this)" class="eb-ticket-modal-back-arrow-wrap">
                            <i class="ebi-left-arrow"></i>
                        </span>
                        <h4>Select Tickets</h4>
                    </div>
                ` : ``}
            
                <div class="eb_ticket_element ${hasEventSessionForSell || isTimeSlotEvent ? 'eb-d-none' : ''}">
                    <input type="hidden" name="event_has_sessions" value="${hasEventSessionForSell}">
                    <input type="hidden" name="event_session_count" value="${totalActiveSession}">
                    <input type="hidden" name="event_has_products" value="${Helpers.eventHasProducts(eventDetails)}">
                    <input type="hidden" name="is_enable_event_capacity" value="${Helpers.isEnableEventCapacity(eventDetails)}">
                    <input type="hidden" name="event_capacity" value="${Helpers.getEventCapacity(eventDetails, true)}">
                    <input type="hidden" name="event_order_tickets" value="${Helpers.getEventOrderTicketsCount(tickets)}">
                    <input type="hidden" name="is_enable_ticket_purchase_limit_per_attendees" value="${Helpers.getEventMaxTicketPerCustomer(eventDetails) > 0}">
                    <input type="hidden" name="ticket_limit_per_attendees" value="${Helpers.getEventMaxTicketPerCustomer(eventDetails)}">
                    <input type="hidden" class="event_occurrence_uuid" name="event_occurrence_uuid" value="${selectedOccurrenceUuid}"> <!--date come from on change occurrence dropdown-->
                    <input type="hidden" class="is_online_event" name="is_online_event" value="${Helpers.isOnlineEvent(eventDetails)}">
                    <input type="hidden" class="is_online_event_type_event_meet" name="is_online_event_type_event_meet" value="${Helpers.isOnlineEventTypeEventMeet(eventDetails)}">
                    <input type="hidden" class="is_enable_ticket_mandatory" name="is_enable_ticket_mandatory" value="${Helpers.isEnableTicketMandatory(eventDetails)}">
    
                    <div class="eb-widget-occurrence-list-dropdown ${hasEventSessionForSell ? 'eb-d-none' : ''}">
                        ${(isTicketPageWidget || isButtonWidget) && !hasEventSessionForSell ? Components.getOccurrenceDropdown(eventDetails, selectedOccurrenceUuid) : ``}
                    </div>
    
                    <form action="" id="ticketForm">
                        <div class="eb_ticket_form_empty_state ${ticketHtml ? 'eb-d-none' : ''}" style="text-align: center">
                            <span>
                                <svg width="224" height="192" viewBox="0 0 224 192" fill="none" xmlns="http://www.w3.org/2000/svg">
                                    <g clip-path="url(#clip0_35851_435725)">
                                    <path opacity="0.5" d="M96.9033 192C149.923 192 192.903 149.019 192.903 96C192.903 42.9807 149.923 0 96.9033 0C43.884 0 0.90332 42.9807 0.90332 96C0.90332 149.019 43.884 192 96.9033 192Z" fill="#dbdbdb"></path>
                                    <rect x="23" y="53" width="150" height="86" rx="5" fill="white"></rect>
                                    <rect x="37" y="71" width="50" height="50" rx="25" fill="#EAF3FD"></rect>
                                    <path d="M57.694 93.5436C58.2047 94.0542 59.0326 94.0542 59.5433 93.5436C60.054 93.0329 60.054 92.2049 59.5433 91.6942C59.0326 91.1835 58.2047 91.1835 57.694 91.6942C57.1833 92.2049 57.1833 93.0329 57.694 93.5436Z" fill="#4FC9C2"></path>
                                    <path d="M60.9308 96.7799C61.4415 97.2906 62.2695 97.2906 62.7801 96.7799C63.2908 96.2692 63.2908 95.4412 62.7801 94.9305C62.2695 94.4199 61.4415 94.4199 60.9308 94.9305C60.4201 95.4412 60.4201 96.2692 60.9308 96.7799Z" fill="#4FC9C2"></path>
                                    <path d="M64.1671 100.016C64.6778 100.527 65.5058 100.527 66.0165 100.016C66.5272 99.5055 66.5272 98.6775 66.0165 98.1669C65.5058 97.6562 64.6778 97.6562 64.1671 98.1669C63.6564 98.6775 63.6564 99.5055 64.1671 100.016Z" fill="#4FC9C2"></path>
                                    <path d="M126.097 75.6455H99.7742C99.3466 75.6455 99 75.2989 99 74.8713V71.7745C99 71.347 99.3466 71.0003 99.7742 71.0003H126.097C126.524 71.0003 126.871 71.347 126.871 71.7745V74.8713C126.871 75.2989 126.524 75.6455 126.097 75.6455Z" fill="#4FC9C2"></path>
                                    <path d="M158.613 88.3555H100.548C99.6932 88.3555 99 87.9819 99 87.5212V83.3498C99 82.889 99.6932 82.5155 100.548 82.5155H158.613C159.468 82.5155 160.161 82.889 160.161 83.3498V87.5212C160.161 87.9819 159.468 88.3555 158.613 88.3555Z" fill="#4FC9C2"></path>
                                    <path d="M126.097 108.646H99.7742C99.3466 108.646 99 108.299 99 107.871V104.775C99 104.347 99.3466 104 99.7742 104H126.097C126.524 104 126.871 104.347 126.871 104.775V107.871C126.871 108.299 126.524 108.646 126.097 108.646Z" fill="#4FC9C2"></path>
                                    <path d="M158.613 121.355H100.548C99.6932 121.355 99 120.982 99 120.521V116.35C99 115.889 99.6932 115.515 100.548 115.515H158.613C159.468 115.515 160.161 115.889 160.161 116.35V120.521C160.161 120.982 159.468 121.355 158.613 121.355Z" fill="#4FC9C2"></path>
                                    <g filter="url(#filter0_d_35851_435725)">
                                    <path d="M110.839 174.194C107.418 174.194 104.645 171.42 104.645 168V140.129C104.645 136.709 107.418 133.936 110.839 133.936H209.161C212.582 133.936 215.355 136.709 215.355 140.129V168C215.355 171.42 212.582 174.194 209.161 174.194H110.839Z" fill="#4FC9C2"></path>
                                    <path d="M123.29 163.161C128.421 163.161 132.581 159.001 132.581 153.87C132.581 148.739 128.421 144.58 123.29 144.58C118.159 144.58 114 148.739 114 153.87C114 159.001 118.159 163.161 123.29 163.161Z" fill="#FEFEFE"></path>
                                    <path d="M120.422 161H125.335C125.712 160.997 126.072 160.847 126.338 160.581C126.604 160.315 126.755 159.954 126.757 159.578V153.172C126.757 153.064 126.715 152.96 126.638 152.884C126.562 152.808 126.459 152.765 126.351 152.765C126.259 152.747 126.177 152.697 126.117 152.624C126.058 152.552 126.026 152.461 126.026 152.367C126.026 152.273 126.058 152.183 126.117 152.11C126.177 152.038 126.259 151.988 126.351 151.969C126.459 151.969 126.562 151.926 126.638 151.85C126.715 151.774 126.757 151.671 126.757 151.563V149.422C126.757 149.045 126.608 148.683 126.341 148.416C126.074 148.15 125.713 148 125.335 148H123.954C123.846 148 123.743 148.043 123.667 148.119C123.591 148.195 123.548 148.299 123.548 148.406C123.548 148.583 123.478 148.753 123.352 148.879C123.227 149.004 123.057 149.075 122.88 149.075C122.702 149.075 122.532 149.004 122.407 148.879C122.282 148.753 122.211 148.583 122.211 148.406C122.211 148.299 122.169 148.195 122.092 148.119C122.016 148.043 121.913 148 121.805 148H120.422C120.045 148 119.683 148.15 119.416 148.416C119.15 148.683 119 149.045 119 149.422V151.555C119 151.662 119.043 151.766 119.119 151.842C119.195 151.918 119.299 151.961 119.406 151.961C119.498 151.98 119.581 152.029 119.64 152.102C119.699 152.175 119.732 152.265 119.732 152.359C119.732 152.453 119.699 152.544 119.64 152.616C119.581 152.689 119.498 152.739 119.406 152.757C119.299 152.757 119.195 152.8 119.119 152.876C119.043 152.952 119 153.056 119 153.163V159.578C119 159.955 119.15 160.317 119.416 160.584C119.683 160.85 120.045 161 120.422 161ZM119.813 153.509C120.044 153.421 120.243 153.265 120.383 153.062C120.524 152.858 120.599 152.617 120.599 152.369C120.599 152.122 120.524 151.88 120.383 151.677C120.243 151.473 120.044 151.317 119.813 151.23V149.422C119.813 149.26 119.877 149.105 119.991 148.991C120.105 148.877 120.26 148.812 120.422 148.812H121.458C121.549 149.119 121.736 149.388 121.992 149.58C122.249 149.771 122.56 149.875 122.88 149.875C123.2 149.875 123.511 149.771 123.767 149.58C124.023 149.388 124.211 149.119 124.302 148.812H125.331C125.493 148.812 125.648 148.877 125.762 148.991C125.877 149.105 125.941 149.26 125.941 149.422V151.22C125.71 151.307 125.51 151.463 125.37 151.667C125.229 151.87 125.154 152.112 125.154 152.359C125.154 152.606 125.229 152.848 125.37 153.051C125.51 153.255 125.71 153.411 125.941 153.499V159.578C125.941 159.74 125.877 159.895 125.762 160.009C125.648 160.123 125.493 160.188 125.331 160.188H120.422C120.26 160.188 120.105 160.123 119.991 160.009C119.877 159.895 119.813 159.74 119.813 159.578V153.509Z" fill="#23C7C6"></path>
                                    <path d="M121.513 152.762H122.083C122.191 152.762 122.295 152.719 122.371 152.643C122.447 152.567 122.49 152.463 122.49 152.355C122.49 152.248 122.447 152.144 122.371 152.068C122.295 151.992 122.191 151.949 122.083 151.949H121.513C121.405 151.949 121.302 151.992 121.225 152.068C121.149 152.144 121.106 152.248 121.106 152.355C121.106 152.463 121.149 152.567 121.225 152.643C121.302 152.719 121.405 152.762 121.513 152.762Z" fill="#23C7C6"></path>
                                    <path d="M123.666 152.762H124.236C124.344 152.762 124.447 152.719 124.524 152.643C124.6 152.567 124.643 152.463 124.643 152.355C124.643 152.248 124.6 152.144 124.524 152.068C124.447 151.992 124.344 151.949 124.236 151.949H123.666C123.558 151.949 123.454 151.992 123.378 152.068C123.302 152.144 123.259 152.248 123.259 152.355C123.259 152.463 123.302 152.567 123.378 152.643C123.454 152.719 123.558 152.762 123.666 152.762Z" fill="#23C7C6"></path>
                                    <path d="M121.141 159.198C121.547 159.452 122.214 159.578 122.88 159.578C123.546 159.578 124.212 159.452 124.617 159.198C124.762 159.125 124.885 159.014 124.972 158.876C125.06 158.739 125.109 158.581 125.114 158.418C125.114 158.039 125.017 157.667 124.831 157.337C124.646 157.006 124.379 156.729 124.056 156.531C124.287 156.257 124.414 155.91 124.414 155.552C124.414 155.146 124.252 154.756 123.965 154.469C123.678 154.182 123.288 154.021 122.882 154.021C122.476 154.021 122.086 154.182 121.799 154.469C121.512 154.756 121.35 155.146 121.35 155.552C121.349 155.91 121.475 156.257 121.706 156.531C121.385 156.73 121.12 157.008 120.936 157.338C120.753 157.669 120.657 158.04 120.658 158.418C120.662 158.579 120.709 158.737 120.794 158.874C120.879 159.011 120.999 159.123 121.141 159.198ZM122.88 154.831C123.022 154.831 123.161 154.873 123.279 154.952C123.398 155.031 123.49 155.143 123.544 155.275C123.599 155.406 123.613 155.551 123.585 155.69C123.557 155.83 123.489 155.958 123.388 156.058C123.288 156.159 123.16 156.228 123.02 156.255C122.881 156.283 122.736 156.269 122.605 156.214C122.473 156.16 122.361 156.068 122.282 155.95C122.203 155.831 122.161 155.692 122.161 155.55C122.161 155.359 122.237 155.177 122.372 155.042C122.507 154.907 122.689 154.832 122.88 154.831ZM122.134 157.22C122.266 157.139 122.409 157.08 122.559 157.045C122.664 157.068 122.772 157.079 122.88 157.08C122.988 157.079 123.095 157.068 123.201 157.047C123.352 157.081 123.496 157.14 123.627 157.222C123.833 157.346 124.003 157.521 124.121 157.731C124.239 157.94 124.301 158.176 124.302 158.416C124.302 158.416 124.273 158.463 124.198 158.508C123.648 158.851 122.132 158.851 121.58 158.508C121.539 158.487 121.504 158.456 121.478 158.418C121.477 158.179 121.536 157.943 121.651 157.734C121.766 157.524 121.932 157.347 122.134 157.22Z" fill="#23C7C6"></path>
                                    </g>
                                    <path d="M186.5 53.5C186.5 64.5457 177.546 73.5 166.5 73.5C155.454 73.5 146.5 64.5457 146.5 53.5C146.5 42.4543 155.454 33.5 166.5 33.5C177.546 33.5 186.5 42.4543 186.5 53.5Z" fill="white" stroke="#EAF3FD"></path>
                                    <path d="M166.501 42C160.146 42 155 47.1458 155 53.5009C155 59.849 160.146 65 166.501 65C172.849 65 178 59.849 178 53.5009C178 47.1458 172.849 42 166.501 42ZM164.2 59.2504L158.45 53.5009L160.077 51.8724L164.2 55.9953L172.923 47.2735L174.55 48.9002L164.2 59.2504Z" fill="#4FC9C2"></path>
                                    <path d="M169.677 150.646H143.355C142.927 150.646 142.581 150.299 142.581 149.871V146.775C142.581 146.347 142.927 146 143.355 146H169.677C170.105 146 170.452 146.347 170.452 146.775V149.871C170.452 150.299 170.105 150.646 169.677 150.646Z" fill="white"></path>
                                    <path d="M201.419 163.354H144.129C143.274 163.354 142.581 162.981 142.581 162.52V158.349C142.581 157.888 143.274 157.514 144.129 157.514H201.419C202.274 157.514 202.968 157.888 202.968 158.349V162.52C202.968 162.981 202.274 163.354 201.419 163.354Z" fill="white"></path>
                                    <path d="M66.2469 81.8863C65.7553 81.3947 64.9583 81.3947 64.4667 81.8863L47.8863 98.4667C47.3947 98.9583 47.3947 99.7553 47.8863 100.247L49.6792 102.04C50.3459 101.667 51.1145 101.455 51.9293 101.455C54.4784 101.455 56.5449 103.521 56.5449 106.071C56.5449 106.885 56.3327 107.654 55.96 108.321L57.7531 110.114C58.2447 110.605 59.0417 110.605 59.5333 110.114L76.1137 93.5333C76.6053 93.0417 76.6053 92.2447 76.1137 91.7531L74.3207 89.9601C73.6539 90.333 72.8851 90.5453 72.0701 90.5453C69.521 90.5453 67.4545 88.4788 67.4545 85.9297C67.4545 85.1147 67.6668 84.3459 68.0397 83.6791L66.2469 81.8863ZM62.6865 80.1061C64.1613 78.6313 66.5523 78.6313 68.0271 80.1061L69.9933 82.0723C70.8506 82.9295 70.697 84.1329 70.2647 84.8599C70.0791 85.1722 69.9721 85.5365 69.9721 85.9297C69.9721 87.0884 70.9114 88.0277 72.0701 88.0277C72.4633 88.0277 72.8276 87.9207 73.1398 87.7351C73.8669 87.3028 75.0702 87.1492 75.9275 88.0064L77.8939 89.9729C79.3687 91.4477 79.3687 93.8387 77.8939 95.3135L61.3135 111.894C59.8387 113.369 57.4477 113.369 55.9729 111.894L54.0063 109.927C53.1492 109.07 53.3027 107.867 53.7348 107.14C53.9204 106.828 54.0273 106.464 54.0273 106.071C54.0273 104.912 53.088 103.973 51.9293 103.973C51.5362 103.973 51.172 104.079 50.8598 104.265C50.1328 104.697 48.9295 104.851 48.0724 103.993L46.1061 102.027C44.6313 100.552 44.6313 98.1613 46.1061 96.6865L62.6865 80.1061Z" fill="#23C7C6" stroke="#EAF3FD" stroke-width="0.7" stroke-linecap="round" stroke-linejoin="round"></path>
                                    </g>
                                    <defs>
                                    <filter id="filter0_d_35851_435725" x="94.645" y="127.936" width="130.709" height="60.2578" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
                                    <feFlood flood-opacity="0" result="BackgroundImageFix"></feFlood>
                                    <feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha"></feColorMatrix>
                                    <feOffset dy="4"></feOffset>
                                    <feGaussianBlur stdDeviation="5"></feGaussianBlur>
                                    <feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.12 0"></feColorMatrix>
                                    <feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_35851_435725"></feBlend>
                                    <feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_35851_435725" result="shape"></feBlend>
                                    </filter>
                                    <linearGradient id="paint0_linear_35851_435725" x1="96.9033" y1="0" x2="96.9033" y2="192" gradientUnits="userSpaceOnUse">
                                    <stop stop-color="#FAFAFA"></stop>
                                    <stop offset="1" stop-color="#D4D4D4" stop-opacity="0.4"></stop>
                                    </linearGradient>
                                    <clipPath id="clip0_35851_435725">
                                    <rect width="222.194" height="192" fill="white" transform="translate(0.90332)"></rect>
                                    </clipPath>
                                    </defs>
                                    </svg>
                            </span>
                            <p class="eb-popup-empty-state-text" id="emptyStateDynamicTextParagraph">
                                <span id="emptyStateDynamicText">  
                                    ${isEnabledInvitationCodeRestriction ? `
                                        Organiser have made tickets available to only those who has the invitation code. Enter the code to view tickets
                                    ` : `
                                        Tickets are not available for booking yet.
                                    `}          
                                </span>
                                Please <a href="${Config.EB_BASE_URL}/b/organiser/${eventDetails.org.slug}" class="font-weight-normal text-blue" target="_blank"> contact the organiser</a> for more details.
                           </p>
                        </div>
                        
                        ${isEnabledInvitationCodeRestriction ? `
                            <div class="eb-ticket-card eb-invitation-code-main-wrap invitaionCodeWrapper">
                                <div class="eb-invitation-code-wrap">
                                    <label class="eb-checkbox-radio">
                                        <span class="">I have an invitation code</span>
                                        <input type="checkbox" class="hasInvitationCode" onclick="Components.hasInvitationCode()" value="on">
                                        <div class="b-input"></div>
                                    </label>
                            
                                    <div class="eb-invitation-code-input-wrap invitationCodeInputWrapper" style="display: none;">
                                        <div class="eb-coupon-label-wrap">
                                            <label>Enter invitation code</label>
                                        </div>
                                        <div class="eb-input-holder">
                                            <div class="eb-input-group-wrap">
                                                <input type="text" class="eb-form-control invitationCode" placeholder="e.g. E5GHDGF">
                                                <input type="button" class="eb-btn-primary invitationCodeApply" value="Apply" onclick="Components.invitationCodeApply('${eventDetails.uuid}')">
                                            </div>
                                        </div>
                                    </div>
                                </div>
                            </div>
                        ` : ``}
                        
                        <div id="ebTicketSection" class="${ticketHtml ? '' : 'eb-d-none'}">
                            ${ticketHtml}
                        </div>
                        
                        ${merchandiseHtml}
                    </form>
                </div>
            </div>
        `;
    }

    static onChangeOccurrencePicker(_this, from='') {
        let occurrenceUuid = Helpers.getSelectedOccurrenceUuid();

        if (occurrenceUuid) {
            if(from == 'ticket_popup'){
                $('.backToSessionListFromTicketList').attr('onclick', `TicketValidation.showEventSessionList("${occurrenceUuid}")`);
                $('.addAnotherSession').attr('onclick', `TicketValidation.showEventSessionList("${occurrenceUuid}")`);

                $('.eb_single_session_card').addClass('eb-d-none');
                $('.popupSessionList_'+occurrenceUuid).removeClass('eb-d-none');

                $('.occSubBtn').attr('onclick', `TicketValidation.submitTicketForm("${occurrenceUuid}")`);
                $(".eb_ticket_qty").each(function () {
                    if ($(this).attr("data-occ_uuid") !== occurrenceUuid) {
                        $(this).val(0);
                    }
                });

                Helpers.initializeSelect2Picker(); // need for ticket page type widget
                TicketValidation.calculate_total_price(occurrenceUuid); 

            }else if (eventDetails?.event_occurrence?.length) {
                let selectedOccurrenceTickets = Helpers.getTicketsByOccurrenceUuid(eventDetails, occurrenceUuid);
                let occurrenceTicketsHtml = Components.getTicketFormHtml(selectedOccurrenceTickets, eventDetails, occurrenceUuid, widgetConfig)

                $("#ticketModalBody").html(occurrenceTicketsHtml);

                let enableFullDay = Helpers.enableFullDay(eventDetails);
                let timezone = Helpers.getTimezoneToConvertDatetime(eventDetails);
                let occurrence = Helpers.getOccurrenceDetailsByUuid(eventDetails, occurrenceUuid);
                let occStartOn = Helpers.convertTimezone(occurrence.start_on.utc, 'UTC', timezone, 'YYYY-MM-DD HH:mm', 'ddd, MMM DD, YYYY hh:mm A [(]z[)]');
                let occEndOn = Helpers.convertTimezone(occurrence.end_on.utc, 'UTC', timezone, 'YYYY-MM-DD HH:mm', 'ddd, MMM DD, YYYY hh:mm A [(]z[)]');
                
                //Bishal need to work from here for full day
                $('.dateTimeViewSection').html(`
                    <p>Start Date: ${occStartOn}</p>
                    <p>End Date: ${occEndOn}</p>
                `);

                //For count down
                let countDownDom = this.getCountDownDom(eventDetails, occurrence);
                $('.countDownBody').html(countDownDom);
                Helpers.initCountDownBar(eventDetails, occurrence);
                //---->

                //Fot ticket popup section
                let occStartDate = Helpers.convertTimezone(occurrence.start_on.utc, 'UTC', timezone, 'YYYY-MM-DD HH:mm', 'dddd, MMM D');
                $('.eventHeaderDateTime').text(occStartDate);

                let duration = Helpers.getDuration(occurrence.start_on.utc, occurrence.end_on.utc);
                $('.occurrenceDuration').text(Helpers.displayDuration(duration));
                //------->
                
                //For tikcet price section
                let eventTickets = eventDetails?.tickets.levels;    
                let occTickets = occurrence.tickets.map(ticket => {
                    return eventTickets.find(item =>item.uuid==ticket.uuid);
                });
                let eventPrice = Helpers.doGetTicketPriceLabel(eventDetails, {levels: occTickets});
                $('.eventPriceShowingSection').text(eventPrice);
                //------>

                $('.occSubBtn').attr('onclick', `TicketValidation.submitTicketForm("${occurrenceUuid}")`);

                //Event details status bar
                let eventStickerType = Helpers.eventStickerType(eventDetails, occurrence);
                let status = Helpers.getEventStatus(eventDetails, eventStickerType, occurrence);
                if(!Helpers.isEmpty(status)){
                    $('.eventDetailsStatusBox').text(status).removeClass('eb-d-none');
                }
                //------>

                if(eventStickerType == 'event_ended'){
                    $('.eb-book-btn').addClass('eb-disabled-all');
                }else{
                    $('.eb-book-btn').removeClass('eb-disabled-all');
                }

                if(eventStickerType == 'booking_end'){
                    $('.eb-purchase-btn-wrap').addClass('eb-disabled-all');
                }else{
                    $('.eb-purchase-btn-wrap').removeClass('eb-disabled-all');
                }

                Helpers.initializeSelect2Picker(); // need for ticket page type widget
                $('.eb-modal-body').removeAttr('data-select2-id');
                TicketValidation.calculate_total_price();            
            }
        }
    }

    static hasInvitationCode() {
        const isChecked = $('.hasInvitationCode').prop("checked");

        if (isChecked) {
            $('.invitationCodeInputWrapper').show(300);
        } else {
            $('.invitationCodeInputWrapper').hide(300);
        }
    }

    static invitationCodeApply(eventUuid) {
        const code = $('.invitationCode').val();

        if (!code.length) {
            return false;
        }

        $.ajax({
            url: Config.EB_API_URL + `/events/${eventUuid}?invitation_code=${code}`,
            method: 'GET',
            headers: {
                'x-api-key': Config.EB_API_KEY
            },
            dataType: 'json',
            beforeSend: function () {
                // showEbLoading();
            },
            success: function (res) {
                let event = res?.event;

                if (event?.tickets?.levels.length) {

                    // get loaded tickets uuid
                    let loadedTicketUuidArr = [];
                    $(".ticket_info_quantity").each(function (index, ticketInfoQuantity) {
                        let isProduct = $(ticketInfoQuantity).attr("data-is_product") === 'true';

                        if (!isProduct) {
                            let ticketUuid = $(ticketInfoQuantity).attr("data-id");
                            loadedTicketUuidArr.push(ticketUuid);
                        }
                    })

                    let uniqueLoadedTicketUuidArr = [];
                    if (loadedTicketUuidArr.length) {
                        uniqueLoadedTicketUuidArr = [...new Set(loadedTicketUuidArr)];
                    }

                    let eventTickets = event?.tickets;

                    let selectedOccurrenceUuid = Helpers.getSelectedOccurrenceUuid();
                    if (selectedOccurrenceUuid) {
                        eventTickets = Helpers.getTicketsByOccurrenceUuid(event, selectedOccurrenceUuid);
                    }

                    if (eventTickets && uniqueLoadedTicketUuidArr) {
                        eventTickets.levels = eventTickets.levels.map(function (item) {
                            if (!uniqueLoadedTicketUuidArr.includes(item.uuid)) {
                                return item;
                            }
                        })
                    }

                    let restrictedTicketHtml = Components.getTicketListHtml(eventTickets, eventDetails,selectedOccurrenceUuid);

                    if (!restrictedTicketHtml.length) {
                        alert("Your invitation code does not match")
                        return;
                    }

                    $("#ebTicketSection").removeClass("eb-d-none").prepend(restrictedTicketHtml);
                    $(".eb_ticket_form_empty_state").addClass("eb-d-none");

                    if (event?.custom_attributes.length) {
                        let visibleInvitationCodeSection = event?.custom_attributes?.find(item => item.name === 'visible_invitation_code_section').value;

                        if (visibleInvitationCodeSection === false) {
                            $(".invitaionCodeWrapper").hide(300);
                        } else {
                            $(".invitationCodeInputWrapper").hide(300);
                            $(".invitationCode").val('');
                            $(".hasInvitationCode").prop('checked', false);
                        }
                    }
                } else {
                    alert("Your invitation code does not match")
                }
            },
            complete: function () {
                // hide loading
            }
        });
    }

    static getTicketBookingStartEndStatusHtml(bookingStartingTimeInUtc, eventDetails, level, selectedEventDate = null) {
        let dateInUTC = "";
        let showType = "";

        let bookingEndedVariationTicket = Helpers.checkIsBookingEnded(level);
        let bookingEnded = Helpers.checkIsBookingEnded(eventDetails, true);

        if (bookingEndedVariationTicket || bookingEnded) {
            showType = "bookingEnded"
        } else {
            if (!level?.hasBookingStarted) {
                showType = "bookingStartsOn";
                dateInUTC = level?.settings?.booking_starts_on?.utc || level?.bookingStartingTimeInUtc;
            }

            if (eventDetails?.settings?.discount?.level === 'ticket' && level?.earlyBirdDiscountEndsOnUTc && level?.category !== "donation") {
                if (!dateInUTC || level?.earlyBirdDiscountEndsOnUTc && moment((level?.earlyBirdDiscountEndsOnUTc)).isBefore(dateInUTC)) {
                    dateInUTC = level?.earlyBirdDiscountEndsOnUTc;//element?.discountPrice has time calculation it compares with current time
                    showType = "earlyBirdsDiscount";
                }
            }

            let isRecurringEvent = Helpers.isRecurringEvent(eventDetails);

            let bookingsEndsOnUtc = level?.settings?.booking_ends_on?.utc;
            const selectedOccurrence = eventDetails?.event_occurrence?.find(element => element?.start_on?.local === selectedEventDate);
            const selectedEventEndDate = selectedOccurrence?.end_on?.utc;
            if (isRecurringEvent && level?.settings?.booking_ends_on?.type === 'relative_to_occurrence' && selectedEventEndDate) {
                let occurrenceBookingEndsType = level?.settings?.booking_ends_on?.occurrence_booking_end_type === 'number_of_hours' ? 'hours' : 'days';
                bookingsEndsOnUtc = moment(selectedEventEndDate).subtract(level?.settings?.booking_ends_on?.occurrence_booking_end_offset, occurrenceBookingEndsType).format('YYYY-MM-DD HH:mm');
            }

            if (!dateInUTC || bookingsEndsOnUtc && moment((bookingsEndsOnUtc)).isBefore(dateInUTC)) {
                dateInUTC = bookingsEndsOnUtc;
                showType = "bookingEndsOn";
            }
        }

        if (dateInUTC && showType === 'bookingStartsOn') {
            return `
                <div class="eb-booking-start-status">
                    <div class="eb-booking-start-title-date-time">
                        <span class="eb-booking-start-title">Booking starts on: </span>
                        <span class="eb-booking-start-date-time">${Helpers.convertToVisitorDateTime(dateInUTC, eventDetails.timezone)}</span>
                    </div>
                </div>
            `;
        }

        if (showType === 'earlyBirdsDiscount' && dateInUTC) {
            return `
                <div class="eb-early-discount-status">
                    <div class="eb-early-discount-title-date-time">
                        <span class="b-early-discount-title">Early bird discounts ends on: </span>
                        <span class="eb-early-discount-date-time">${Helpers.convertToVisitorDateTime(dateInUTC, eventDetails.timezone)}</span>
                    </div>
                </div>
            `;
        }

        //early birds discount here
        if (showType === 'bookingEnded' || (showType === 'bookingEndsOn' && dateInUTC)) {
            return `
                <div class="eb-booking-end-status">
                    <div class="eb-booking-ends-title-date-time">
                        <span class="eb-booking-ends-title">${showType === 'bookingEnded' ? "Booking ended" : "Booking ends on: "} </span>
                        <span class="veb-booking-ends-date-time">${showType === 'bookingEndsOn' ? Helpers.convertToVisitorDateTime(dateInUTC, eventDetails.timezone) : ''}</span>
                    </div>
                </div>
            `;
        }

        return ``;
    }

    static getGroupTicketEachContainsHtml(quantityIncluded) {
        if (quantityIncluded > 1) {
            return `<div class="eb-gray-label">
                Each set contains ${quantityIncluded} ticket${quantityIncluded > 1 ? 's' : ''}
            </div>`;
        }

        return '';
    }

    static getTicketIncludesFeeHtml(fee, currency, level=null, levelSessionId=null) {
        if(!fee && Helpers.isEmpty(level)){
            return ``;
        }else if ((!fee && level.category==Constants.TICKET_CATEGORY.TICKET) || eventDetails?.settings?.service_charge?.enabled == false) {
            return ``;
        }

        return `<div class="eb-gray-label service_charge_for${level?.uuid}" data-session_id="${levelSessionId}" style="margin-right: .5rem">
            Includes ${Constants.SupportedCurrencySigns[currency]}${fee} fee
        </div>`;
    }

    static getTicketDescriptionHtml(description) {
        if (!description.length) {
            return '';
        }

        return `<div class="eb-ticket-details-wrap">
            <button type="button" class="eb-ticket-details-btn" onclick="Components.toggleTicketDetails(this)"><i class="ebi-icon-down-angle icon"></i> <span class="content">More Details</span></button>
            <div class="eb-ticket-details" style="display: none">
                <p>${description}</p>
            </div>
        </div>`;
    }

    static toggleTicketDetails(_this) {
        $(_this).next(".eb-ticket-details").slideToggle();
        $(_this).toggleClass("active");

        $(_this).find(".content").html($(_this).hasClass("active") ? "Less Details" : "More Details");

        // if ($(_this).hasClass("active")) {
        //     $(_this).find(".icon").addClass("ebi-icon-up-angle").removeClass("ebi-icon-down-angle");
        // } else {
        //     $(_this).find(".icon").addClass("ebi-icon-down-angle").removeClass("ebi-icon-up-angle");
        // }
    }

    static loadSessionDetails(sessionData) {
        sessionData = JSON.parse(decodeURIComponent(sessionData));

        let $modalSelector = $("#sessionDetailsModal");

        $modalSelector.find("#sessionName").html(sessionData.name);
        $modalSelector.find("#sessionImage").attr("src", Helpers.getImageFullUrl(sessionData?.image || Helpers.getDefaultImagePath()));
        $modalSelector.find("#sessionStartDate").html(Helpers.convertToVisitorDateTime(sessionData.session_starts_on?.utc, eventDetails.timezone));
        $modalSelector.find("#sessionDuration").html(Helpers.getDuration(sessionData.session_starts_on?.local, sessionData.session_ends_on?.local));
        $modalSelector.find("#sessionDescription").html(sessionData?.description ? sessionData?.description?.replace("`", "'") : '');

        Helpers.openModal("#sessionDetailsModal");
    }


    static getEventDetailsDateTime(eventDetails, startOn) {
        let isTimeSlotEvent = Helpers.isTimeSlotEvent(eventDetails);
        if (isTimeSlotEvent) {
            return '';
        }

        let eventDuration = eventDetails?.occurrence?.attributes?.event_duration;
        let enableFullDay = Helpers.enableFullDay(eventDetails);

        return `<div class="eb-side-box eb-date-time dateTimeFullDomSection">
            <h4 class="eb-side-title">Date & Time</h4>
            <div class="eb-start-end-time-wrap dateTimeViewSection">
                <p>Start ${enableFullDay ? 'Date' : 'Time'}: ${Helpers.convertToVisitorDateTime(startOn, eventDetails.timezone)}</p>
                <p>End ${enableFullDay ? 'Date' : 'Time'}: ${Helpers.convertToVisitorDateTime(Helpers.addTimeWithDate(startOn, eventDuration, 'minutes'), eventDetails.timezone)}</p>
            </div>  
        </div>`;
    }

    static getCalenderHtml(eventDetails) {
        const typeOfOccurrence = Helpers.getTheTypeOfOccurrence(eventDetails);
        let calenderHtml = "";
        if (typeOfOccurrence != Constants.TYPE_OF_OCCURRENCE.TIMESLOTS) return calenderHtml;

        calenderHtml = `
            <div id="sellAppointmentCalender" class="eb-sell-appointment-main-wrap">
                <div class="eb-sell-ap-calender-wrap">
                    <div class="eb-card-header">
                        <span class="prevMonth">&#10096;</span>
                        <span><strong id="s_m"></strong></span>
                        <span class="nextMonth">&#10097;</span>
                    </div>
                    <div class="eb-card-body">
                        <div class="table-responsive">
                            <table class="table table-sm table-borderless">
                                <thead class="days">
                                    <tr>
                                        ${Object.keys(Constants.DAYS).map(key => (
                                            `<th><span>${Constants.DAYS[key].substring(0, 3)}</span></th>`
                                        )).join('')}
                                    </tr>
                                </thead>
                                <tbody id="dates" class="dates"></tbody>
                            </table>
    
                            <div class="eb-timeslot-modal-footer left-card">
                                <div class="eb-status-lable-wrap">
                                    <div class="status-lable"><span class="available s-circle"></span><span>Available</span></div>
                                    <div class="status-lable"><span class="unavailable s-circle"></span><span>Unavailable</span></div>
                                    <div class="status-lable"><span class="booked s-circle"></span><span>Booked</span></div>
                                </div>
                            </div>
                        </div>
                    </div>
                </div>
    
                <div class="sell-ap-calender-right-wrap" id="event">
                    <div class="eb-card-header">
                        Available timeslots
                    </div>
                    <div class="eb-card-body">
                        <div class="events-today">
    
                        </div>
                    </div>
                </div>
            </div>
        `;

        return calenderHtml;
    }

    static openEventTicketPopup(eventDetails) {
        window.popupOpenStatus?.(true);
        Helpers.openModal("#ticketModal");
        $("#ebBuyTickets").addClass("eb-d-none");
        window.parent.postMessage({ type: 'modal-open' }, '*');
    }

    static closeEventTicketPopup() {
        window.popupOpenStatus?.(false);
        Helpers.closeModal("#ticketModal");
        $("#ebBuyTickets").removeClass("eb-d-none");
        window.parent.postMessage({ type: 'modal-close' }, '*');
    }

    static getEventDateListData(eventDetails) {
        const eventOccurrences = eventDetails?.event_occurrence;
        const res = {
            timeslotList: [],
            eventDateList: [],
            bookedOccurrenceList: [],
            bookedOccurrenceListData: []
        };

        if (!Helpers.isEmpty(eventOccurrences)) {
            let is_got_default_selected = false;
            eventOccurrences.map((eventOccurrence) => {
                let timeslot = {
                    uuid: eventOccurrence.uuid,
                    occurrence: eventOccurrence
                };
                res.timeslotList.push(timeslot);

                const isOccurrenceSoldOut = Helpers.isOccurrenceTicketSoldOut(eventDetails, eventOccurrence);
                if (isOccurrenceSoldOut) {
                    let bookedDate = {
                        uuid: eventOccurrence.uuid,
                        date: Helpers.time(false, eventOccurrence.start_on.local, "YYYY-MM-DD"),
                    };
                    res.bookedOccurrenceListData.push(bookedDate);

                    res.bookedOccurrenceList.push(Helpers.time(false, eventOccurrence.start_on.local, "YYYY-MM-DD"));

                } else {
                    let is_default_selected = false;
                    let is_unavailable = false;
                    let occurrence_eb_start_on = Helpers.time(true, eventOccurrence.start_on.utc, "YYYY-MM-DD");
                    let current_date = Helpers.time(true, null, "YYYY-MM-DD");

                    if (!is_got_default_selected && moment(occurrence_eb_start_on).isSameOrAfter(current_date)) {
                        is_default_selected = true;
                        is_got_default_selected = true;
                    }

                    let is_all_time_slot_unavailable = Components.isAllTimeslotUnavailableOfEventOccurrenceAppointmentDate(eventDetails, eventOccurrence);
                    if (moment(occurrence_eb_start_on).isBefore(current_date) || is_all_time_slot_unavailable) {
                        is_unavailable = true;
                        is_default_selected = false;
                        is_got_default_selected = false;
                    }


                    let event_appointment_date_list = {
                        uuid: eventOccurrence.uuid,
                        occurrence: eventOccurrence,
                        date: Helpers.time(false, eventOccurrence.start_on.local, "YYYY-MM-DD"),
                        is_default_selected: is_default_selected,
                        is_unavailable: is_unavailable,
                    };
                    res.eventDateList.push(event_appointment_date_list);
                }
            });
        }

        return res;
    }

    static isAllTimeslotUnavailableOfEventOccurrenceAppointmentDate(event, eventOccurrence) {
        let is_all_timeslot_unavailable = true;

        let appointment_timeslots_by_occurrence = Components.getAppointmentTimeslotsByOccurrence(event, eventOccurrence);

        let time_slots = appointment_timeslots_by_occurrence.time_slots;

        for (const time_slot of time_slots) {
            if (time_slot.status == Constants.TIMESLOTS_STATUS.TIMESLOTS_AVAILABLE_TEXT) {
                is_all_timeslot_unavailable = false;
                break;
            }
        }

        return is_all_timeslot_unavailable;
    }

    static getAppointmentTimeslotsByOccurrence(event, eventOccurrence) {
        let time_slots = [];
        let eventOrderOccurrences = Helpers.getOrderOccurrenceOfEvent(event);

        if (!Helpers.isEmpty(eventOccurrence) && !Helpers.isEmpty(eventOccurrence.timeslots)) {
            for (let timeslot of eventOccurrence.timeslots) {
                let timeslot_uuid = timeslot.uuid;
                let status = Constants.TIMESLOTS_STATUS.TIMESLOTS_AVAILABLE_TEXT;

                //Past timeslot check
                let appointment_eb_start_on = timeslot.start_time.utc;
                if (moment(appointment_eb_start_on).isBefore(Helpers.time())) {
                    status = Constants.TIMESLOTS_STATUS.TIMESLOTS_UNAVAILABLE_TEXT;
                }


                //Timeslot notice period check
                let has_before_timeslot_notice_period = Helpers.checkBeforeTimeSlotNoticePeriod(event, timeslot);
                if (timeslot.status === Constants.TIMESLOTS_STATUS.TIMESLOTS_UNAVAILABLE || has_before_timeslot_notice_period) {
                    status = Constants.TIMESLOTS_STATUS.TIMESLOTS_UNAVAILABLE_TEXT;
                }

                if(!Helpers.isEmpty(eventOrderOccurrences)){
                    for (let eventOrderOccurrence of eventOrderOccurrences) {
                        let check_after_booked_timeslot_notice_period = Helpers.checkAfterBookedTimeslotNoticePeriod(event, eventOrderOccurrence, timeslot);
                        if (check_after_booked_timeslot_notice_period) {
                            status = Constants.TIMESLOTS_STATUS.TIMESLOTS_UNAVAILABLE_TEXT;
                        }
                    }
                }


                //Need to work on it
                // if($event->event_type == EVENT_TYPE_VIRTUAL){
                //     $userId=$this->authUserId();
                //     $isTimeSlotSoldOnceForCustomer = $this->getComponent('EventMeet')->isTimeSlotSoldedOnceForUser($timeslot, $userId);

                //     if($isTimeSlotSoldOnceForCustomer){
                //         $status = TIMESLOTS_UNAVAILABLE_TEXT;
                //     }
                // }

                let duration = Helpers.getSingleDuration(timeslot?.duration);
                let displayDuration = Helpers.displayDuration(duration);

                let time_slot = {
                    uuid: timeslot_uuid,
                    slot: timeslot.start_time.local,
                    status: status,
                    duration: displayDuration,
                    data: timeslot
                };

                time_slots.push(time_slot);
            }
        }

        // let duration = Helpers.getSingleDuration(event_occurrence['event']['event_duration']/60);
        // let displayDuration = Helpers.displayDuration(duration);

        return {
            time_slots: time_slots,
            // duration:displayDuration
        };
    }

    static getOccurrenceDropdown(eventDetails, selectedOccurrenceUuid = null, from='') {            
        if (Helpers.isTimeSlotEvent(eventDetails) || (Helpers.hasEventSessionForSell(eventDetails) && from !='ticket_popup')) {
            return ``;
        }

        if (!eventDetails?.event_occurrence.length) {
            return '';
        }

        let options = '';
        eventDetails?.event_occurrence.forEach(function (item, index) {
            let selected = "";
            if (selectedOccurrenceUuid) {
                if (selectedOccurrenceUuid === item.uuid) {
                    selected = "selected";
                }
            }else if(index == 0){
                selected = "selected";
            }

            options += `<option data-occurrenceUuid="${item.uuid}" value="" ${selected}>
                ${Helpers.convertToVisitorDateTime(item.start_on.utc, eventDetails.timezone)}
            </option>`;
        })

        return `<div class="eb-side-box eb-occurrence-dropdown">
            <h4 class="eb-side-title">Select event date & time</h4>
            <div class="select2-main-wrap">
                <select class="select2Picker" name="" id="occurrencePicker" onchange="Components.onChangeOccurrencePicker(this, '${from}')">
                  ${options}
                </select>
            </div> 
        </div>`;
    }

    static getCountDownDom(event, occurrence){
        let countDownDomData = Helpers.getCountDownDomData(event, occurrence);
        if(Helpers.isEmpty(countDownDomData) || countDownDomData?.durationInDays >= 100 || Helpers.isEmpty(countDownDomData?.datetime)) return '';

        let hasEventSessionForSell = Helpers.hasEventSessionForSell(event);
        let typeOfOccurrence = Helpers.getTheTypeOfOccurrence(event);
        let timezone = Helpers.getTimezoneToConvertDatetime(event);

        let date = Helpers.convertTimezone(countDownDomData.datetime, 'UTC', timezone, null, 'MMMM DD [at] h:mm A');
        let pTagData = `<div class="countdown-main-title"> <p>${countDownDomData.title + date}</p>`;
        let hTagData = '';

        if(countDownDomData.type == 'booking_end'){
            hTagData = `Time left to book this event  </div>`;
        }else{
            pTagData += `</div>`;
        }

        if(countDownDomData.type == 'offer_end'){
            let discountData = event.early_bird_discount;
            let amount = '';

            if(discountData.discount_type == 'Percentage'){
                amount = discountData.discount+'%';
            }else{
                amount = '$'+discountData.discount;
            }
            hTagData = `<div>Enjoy a discount of ${amount} before the time ends</div>`;
        }

        return `
            <div class="countdown-main-wrap ${hasEventSessionForSell && typeOfOccurrence != Constants.TYPE_OF_OCCURRENCE.DOES_NOT_REPEAT ?'eb-d-none':''}">
                ${pTagData}
                <h3>${hTagData}</h3>
                <div id="countdown" class="${['offer_end','booking_end'].includes(countDownDomData.type)?'eb-end-time-warning':''}"></div>
            </div>
        `;
    }

    static getEventDetailsPageBannerHtml(event){
        let eventBanners = event?.banner;
        let totalBaner = eventBanners.length;
        let bannerDom = '';
        let isCroppedImageClass = '';

        if(totalBaner == 1){
            if (eventBanners?.[0].image.includes("cropped_images")) {
                isCroppedImageClass = 'eb-single-banner-cropped';
            }

            bannerDom = `<img class="event-image" src="${Helpers.getEventBannerImage(event)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>`;
        }else if(totalBaner == 2){
            bannerDom = `
                <div class="eb-event-banner-inner">
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-full-height">
                            <img class="event-image" src="${Helpers.getEventBannerImage(event, 0)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-full-height">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 1)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                </div>
            `;
        }else if(totalBaner == 3){
            bannerDom = `
                <div class="eb-event-banner-inner">
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-full-height">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 0)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-height-50">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 1)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                        <div class="eb-banner-thumb eb-height-50">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 2)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                </div>
            `;
        }else if(totalBaner == 4){
            bannerDom = `
                <div class="eb-event-banner-inner">
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-full-height">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 0)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-height-50">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 1)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                        <div class="eb-height-50 eb-d-flex">
                            <div class="eb-banner-thumb eb-width-50">
                                <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 2)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                            </div>
                            <div class="eb-banner-thumb eb-width-50">
                                <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 3)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                            </div>
                        </div>
                    </div>
                </div>
            `;
        }else if(totalBaner == 5){
            bannerDom = `
                <div class="eb-event-banner-inner">
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-height-58">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 0)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                        <div class="eb-banner-thumb eb-height-42">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 1)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                    </div>
                    <div class="eb-width-50">
                        <div class="eb-banner-thumb eb-height-50">
                            <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 2)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                        </div>
                        <div class="eb-height-50 eb-d-flex">
                            <div class="eb-banner-thumb eb-width-50">
                                <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 3)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                            </div>
                            <div class="eb-banner-thumb eb-width-50">
                                <img class="eb-event-image" src="${Helpers.getEventBannerImage(event, 4)}" onError="this.src='${Helpers.getEventFallbackImage()}'" alt="Event Banner"/>
                            </div>
                        </div>
                    </div>
                </div>
            `;
        }
        
        return `<div class="eb-event-banner-wrap ${isCroppedImageClass}">
                    ${bannerDom}
                </div>`;
    }

}

window.Components = Components;
