import { metaKeys } from "./constants";
import { applyFilters } from "@wordpress/hooks";

export const selectors = {
	hasTickets(state, type) {
		return selectors.getTicketCount(state, type) > 0;
	},
	getTicketCount(state, type) {
		return 'tickets' === type ? state?.ticketData?.count : state?.rsvpData?.count;
	},
	getAvailability(state, type) {
		return 'tickets' === type ? state?.availability?.tickets : state?.availability?.rsvp;
	},
	hasAvailability(state, type) {
		return Object.keys(selectors.getAvailability(state, type)).length > 0;
	},
	isWaitlistEnabled(state, type) {
		return 'tickets' === type ? !!state?.waitlistData?.tickets?.enabled: !!state?.waitlistData?.rsvp?.enabled;
	},
	getWaitlistConditional(state, type) {
		return 'tickets' === type ? state?.waitlistData?.tickets?.conditional : state?.waitlistData?.rsvp?.conditional;
	},
	getTicketsHaveNotStartedSales(state, type) {
		return 'tickets' === type ? ( state?.ticketData?.ticketsHaveNotStartedSales || [] ) : ( state?.rsvpData?.ticketsHaveNotStartedSales || [] );
	},
	getTicketsOnSale(state, type) {
		return 'tickets' === type ? ( state?.ticketData?.ticketsOnSale || [] ) : ( state?.rsvpData?.ticketsOnSale || [] );
	},
	getTicketsHaveEndedSales(state, type) {
		return 'tickets' === type ? ( state?.ticketData?.ticketsHaveEndedSales || [] ) : ( state?.rsvpData?.ticketsHaveEndedSales || [] );
	},
	isUsingAssignedSeating(state) {
		return !!state?.isUsingAssignedSeating;
	},
	hasTicketsOnSale(state, type) {
		return selectors.getTicketsOnSale(state, type).length > 0;
	},
	hasWaitlistEnded(state, type) {
		if ( ! selectors.hasTickets(state, type) ) {
			return false;
		}

		const hasEnded = selectors.getTicketsHaveEndedSales(state, type).length === selectors.getTicketCount(state, type);

		/**
		 * Filters whether the waitlist has ended
		 *
		 * @since 6.2.0
		 *
		 * @param {boolean} hasEnded The result of the waitlist having ended.
		 * @param {string}  type     The type of waitlist.
		 *
		 * @return {boolean} Whether the waitlist has ended
		 */
		return applyFilters( 'tec.tickets-plus.waitlist.ended', hasEnded, type );
	},
	isWaitlistActive( state, type ) {
		if ( ! selectors.isWaitlistEnabled(state, type) ) {
			return false;
		}

		if ( ! selectors.hasTickets(state, type) ) {
			return false;
		}

		if ( selectors.hasWaitlistEnded(state, type) ) {
			return false;
		}

		if ( selectors.hasTicketsOnSale(state, type) ) {
			return false;
		}

		const conditional = selectors.getWaitlistConditional(state, type);

		let result = false;

		switch ( conditional ) {
			case metaKeys.conditionals.always:
				result = true;
				break;
			case metaKeys.conditionals.before_sale:
				result = selectors.getTicketsHaveNotStartedSales(state, type).length === selectors.getTicketCount(state, type);
				break;
			case metaKeys.conditionals.on_sold_out:
				result = ! selectors.hasAvailability(state, type);
				break;
		}

		/**
		 * Filters whether the waitlist is active.
		 *
		 * @since 6.2.0
		 *
		 * @param {boolean} result The result of the waitlist being active.
		 * @param {string}  type   The type of waitlist.
		 *
		 * @return {boolean} Whether the waitlist is active.
		 */
		return applyFilters( 'tec.tickets-plus.waitlist.active', result, type );
	}
};
