import {
	useState,
	useCallback,
	useEffect,
	useMemo,
	useRef,
	useReducer,
} from '@wordpress/element';
import { twMerge } from 'tailwind-merge';
import { useSelect, useDispatch } from '@wordpress/data';
import apiFetch from '@wordpress/api-fetch';
import NavigationButtons from '../components/navigation-buttons';
import { classNames, toastBody } from '../helpers';
import { STORE_KEY } from '../store';
import { ColumnItem } from '../components/column-item';
import Input from '../components/input';
import {
	ChevronUpIcon,
	MagnifyingGlassIcon,
	XMarkIcon,
} from '@heroicons/react/24/outline';
import { useForm } from 'react-hook-form';
import { useDebounce } from '../hooks/use-debounce';
import ColumnSkeleton from '../components/column-skeleton';
import {
	clearSessionStorage,
	getFromSessionStorage,
	setToSessionStorage,
} from '../utils/helpers';
import { useNavigateSteps } from '../router';
import Button from '../components/button';
import LoadingSpinner from '../components/loading-spinner';
import { __ } from '@wordpress/i18n';
import toast from 'react-hot-toast';
import Heading from '../components/heading';
export const USER_KEYWORD = 'st-template-search';

const SelectTemplate = () => {
	const { previousStep } = useNavigateSteps();

	const {
		setWebsiteTemplatesAIStep,
		setWebsiteSelectedTemplateAIStep,
		setWebsiteTemplateSearchResultsAIStep,
		setSelectedTemplateIsPremium,
	} = useDispatch( STORE_KEY );

	const {
		stepsData: {
			businessName,
			businessType,
			templateSearchResults,
			templateList: allTemplates,
			templateKeywords: keywords = [],
		},
	} = useSelect( ( select ) => {
		const { getAIStepData, getAllPatternsCategories, getOnboardingAI } =
			select( STORE_KEY );

		const onboardingAI = getOnboardingAI();

		return {
			stepsData: getAIStepData(),
			allPatternsCategories: getAllPatternsCategories(),
			isNewUser: onboardingAI?.isNewUser,
		};
	}, [] );

	const {
		register,
		handleSubmit,
		formState: { errors },
		reset,
		setFocus,
		watch,
		getValues,
	} = useForm( {
		defaultValues: {
			keyword:
				getFromSessionStorage( USER_KEYWORD ) ??
				keywords?.join( ', ' ) ??
				'',
		},
	} );
	const watchedKeyword = watch( 'keyword' );
	const debouncedKeyword = useDebounce( watchedKeyword, 300 );

	const [ isFetching, setIsFetching ] = useState( false );
	const [ backToTop, setBackToTop ] = useState( false );

	const parentContainer = useRef( null );
	const templatesContainer = useRef( null );
	const abortRequest = useRef( [] );

	const [ loadMoreTemplates, setLoadMoreTemplates ] = useReducer(
		( state, updatedState ) => {
			return {
				...state,
				...updatedState,
			};
		},
		{
			page: 1,
			loading: false,
			showLoadMore: false,
		}
	);

	const TEMPLATE_TYPE = {
		RECOMMENDED: 'recommended',
		PARTIAL: 'partial',
		GENERIC: 'generic',
	};

	const refinedSearchResults = useMemo( () => {
		if ( ! templateSearchResults?.length ) {
			return [];
		}

		return templateSearchResults.reduceRight( ( acc, item, index ) => {
			if ( ! item.designs?.length ) {
				return acc;
			}
			const otherDesigns = acc
				.filter( ( designItem ) => item.match !== designItem.match )
				.flatMap( ( otherItem ) => otherItem.designs );

			const updatedDesigns = item.designs.filter(
				( designItem ) =>
					! otherDesigns.find(
						( otherDesign ) => otherDesign.uuid === designItem.uuid
					)
			);

			acc[ index ] = { ...item, designs: updatedDesigns };
			return acc;
		}, templateSearchResults );
	}, [ templateSearchResults ] );

	const getTemplates = useCallback(
		( type ) => {
			const { RECOMMENDED, GENERIC, PARTIAL } = TEMPLATE_TYPE;
			switch ( type ) {
				case RECOMMENDED:
					return refinedSearchResults?.[ 0 ]?.designs || [];
				case PARTIAL:
					return refinedSearchResults?.[ 1 ]?.designs || [];
				case GENERIC:
					return refinedSearchResults?.[ 2 ]?.designs || [];
			}
		},
		[ refinedSearchResults ]
	);

	const getInitialUserKeyword = () => {
		const type = businessType.toLowerCase();
		if ( type !== 'others' ) {
			return type;
		} else if ( keywords?.length > 0 ) {
			return keywords[ 0 ];
		}
		return businessName;
	};

	const maybeHidePremiumTemplates = ( result ) => {
		if ( ! aiBuilderVars?.show_premium_templates ) {
			result = result.map( ( item ) => {
				return {
					...item,
					designs: item?.designs?.filter(
						( template ) => ! template.is_premium
					),
				};
			} );
		}

		return result;
	};

	const fetchTemplates = async ( keyword = getInitialUserKeyword() ) => {
		if ( ! keyword ) {
			return;
		}

		try {
			setIsFetching( true );
			if ( abortRequest.current.length ) {
				abortRequest.current.forEach( ( controller ) => {
					controller.abort();
				} );
				abortRequest.current = [];
			}
			setWebsiteTemplatesAIStep( [] );

			const finalKeywords = [
				...new Set(
					keyword
						.split( ',' )
						.map( ( item ) => item.trim()?.toLowerCase() )
				),
			];

			let results = [];
			const allTemplatesList = [];

			const promises = finalKeywords.map( async ( keywordItem ) => {
				const abortController = new AbortController();
				abortRequest.current.push( abortController );
				const response = await apiFetch( {
					path: 'zipwp/v1/templates',
					method: 'POST',
					data: {
						keyword: keywordItem,
						business_name: businessName,
					},
					signal: abortController.signal,
				} );
				let result = response?.data?.data || [];

				// Filter out premium templates if `show_premium_template` is false.
				result = maybeHidePremiumTemplates( result );

				if ( results.length === 0 ) {
					results = result;
				} else {
					result.forEach( ( item, indx ) => {
						if ( item?.designs?.length > 0 ) {
							results[ indx ].designs = [
								...results[ indx ].designs,
								...item.designs.filter(
									( template ) =>
										! results[ indx ].designs.find(
											( existingTemplate ) =>
												existingTemplate.uuid ===
												template.uuid
										)
								),
							];
						}
					} );
				}

				// Get the the designs in sequence
				result.forEach( ( item ) => {
					if ( Array.isArray( item.designs ) ) {
						allTemplatesList.push(
							...item.designs.filter(
								( template ) =>
									! allTemplatesList.find(
										( existingTemplate ) =>
											existingTemplate.uuid ===
											template.uuid
									)
							)
						);
					}
				} );

				setWebsiteTemplatesAIStep( [ ...allTemplatesList ] );
				setWebsiteTemplateSearchResultsAIStep( [ ...results ] );
				setIsFetching( false );
				setLoadMoreTemplates( { showLoadMore: true } );

				return true;
			} );

			await Promise.all( promises );
		} catch ( error ) {
			if ( error?.name === 'AbortError' ) {
				return;
			}
			setIsFetching( false );
		}
	};

	const fetchAllTemplatesByPage = async ( page = 1 ) => {
		try {
			if ( loadMoreTemplates.loading ) {
				return;
			}
			setLoadMoreTemplates( { loading: true } );

			const response = await apiFetch( {
				path: 'zipwp/v1/all-templates',
				method: 'POST',
				data: {
					business_name: businessName,
					per_page: 9,
					page,
				},
			} );

			if ( ! response.success ) {
				throw new Error(
					response?.data?.data ??
						__( 'Error while fetching templates', 'ai-builder' )
				);
			}

			let result = response?.data?.data?.result || [];
			const lastPage = response?.data?.data?.lastPage || 1;

			// Filter out premium templates if `show_premium_template` is false.
			result = maybeHidePremiumTemplates( result );

			const updatedAllTemplates = [
				...allTemplates,
				...result.map( ( item ) => item.designs ).flat(),
			];
			const updatedSearchResults = [ ...templateSearchResults ];
			result.forEach( ( item ) => {
				if ( ! item?.match ) {
					return;
				}
				const indx = updatedSearchResults.findIndex(
					( searchResult ) => searchResult?.match === item?.match
				);
				if ( indx !== -1 ) {
					const existingDesigns = updatedSearchResults[
						indx
					].designs.map( ( design ) => design.uuid );
					const newDesigns = item.designs.filter(
						( designItem ) =>
							! existingDesigns.includes( designItem.uuid )
					);
					updatedSearchResults[ indx ].designs = [
						...updatedSearchResults[ indx ].designs,
						...newDesigns,
					];
				}
			} );

			setWebsiteTemplatesAIStep( updatedAllTemplates );
			setWebsiteTemplateSearchResultsAIStep( updatedSearchResults );

			if ( page === lastPage ) {
				setLoadMoreTemplates( { showLoadMore: false } );
			}
		} catch ( error ) {
			toast.error(
				toastBody( {
					message: error?.message?.toString(),
				} )
			);
		} finally {
			setLoadMoreTemplates( { loading: false } );
		}
	};

	useEffect( () => {
		setFocus( 'keyword' );

		// Save the manually entered keyword to session storage.
		return () => {
			const keyword = getValues( 'keyword' );
			if (
				! keyword ||
				keywords.some(
					( item ) => item?.toLowerCase() === keyword?.toLowerCase()
				)
			) {
				return clearSessionStorage( USER_KEYWORD );
			}
			setToSessionStorage( USER_KEYWORD, keyword );
		};
	}, [] );

	useEffect( () => {
		fetchTemplates(
			debouncedKeyword ? debouncedKeyword : getInitialUserKeyword()
		);
	}, [ debouncedKeyword ] );

	const handleSubmitKeyword = ( { keyword } ) => {
		onChangeKeyword( keyword );
	};

	const handleClearSearch = () => {
		if ( ! watchedKeyword ) {
			return;
		}
		reset( { keyword: '' } );
		onChangeKeyword( getInitialUserKeyword() );
	};

	const onChangeKeyword = ( value = '' ) => {
		fetchTemplates( value );
		setWebsiteSelectedTemplateAIStep( '' );
		setSelectedTemplateIsPremium( '' );
	};

	const renderTemplates = useMemo( () => {
		if (
			! getTemplates( TEMPLATE_TYPE.RECOMMENDED )?.length &&
			! getTemplates( TEMPLATE_TYPE.PARTIAL )?.length &&
			! getTemplates( TEMPLATE_TYPE.GENERIC )?.length
		) {
			return null;
		}

		return (
			<>
				{ getTemplates( TEMPLATE_TYPE.RECOMMENDED )?.map(
					( template, index ) => (
						<ColumnItem
							key={ template.uuid }
							template={ template }
							position={ index + 1 }
						/>
					)
				) }
				{ getTemplates( TEMPLATE_TYPE.PARTIAL )?.map(
					( template, index ) => (
						<ColumnItem
							key={ template.uuid }
							template={ template }
							position={
								index +
								1 +
								( getTemplates( TEMPLATE_TYPE.RECOMMENDED )
									?.length || 0 )
							}
						/>
					)
				) }
				{ getTemplates( TEMPLATE_TYPE.GENERIC )?.map(
					( template, index ) => (
						<ColumnItem
							key={ template.uuid }
							template={ template }
							position={
								index +
								1 +
								( ( getTemplates( TEMPLATE_TYPE.RECOMMENDED )
									?.length || 0 ) +
									( getTemplates( TEMPLATE_TYPE.PARTIAL )
										?.length || 0 ) )
							}
						/>
					)
				) }
			</>
		);
	}, [ getTemplates ] );

	const handleShowBackToTop = ( event ) => {
		const SCROLL_THRESHOLD = 100;
		const { scrollTop } = event.target;

		if ( scrollTop > SCROLL_THRESHOLD && ! backToTop ) {
			setBackToTop( true );
		}
		if ( scrollTop <= SCROLL_THRESHOLD && backToTop ) {
			setBackToTop( false );
		}
	};

	const handleClickBackToTop = () => {
		parentContainer.current.scrollTo( {
			top: 0,
			behavior: 'smooth',
		} );
	};

	return (
		<div
			ref={ parentContainer }
			className={ twMerge(
				`mx-auto flex flex-col overflow-x-hidden`,
				'w-full'
			) }
			onScroll={ handleShowBackToTop }
		>
			<Heading
				heading={ __( 'Choose the Design', 'ai-builder' ) }
				className="px-5 md:px-10 lg:px-14 xl:px-15 pt-5 md:pt-10 lg:pt-8 xl:pt-8 max-w-fit mx-auto"
			/>
			<form
				className="w-full pt-6 pb-14 max-w-[37.5rem] mx-auto"
				onSubmit={ handleSubmit( handleSubmitKeyword ) }
			>
				<Input
					name="keyword"
					inputClassName="pl-4"
					register={ register }
					placeholder={ __( 'Add a keyword', 'ai-builder' ) }
					height="12"
					error={ errors?.keyword }
					suffixIcon={
						<div className="absolute right-4 flex items-center">
							<button
								type="button"
								className="w-auto h-auto p-0 flex items-center justify-center cursor-pointer bg-transparent border-0 focus:outline-none"
								onClick={ handleClearSearch }
							>
								{ watchedKeyword ? (
									<XMarkIcon className="w-5 h-5 text-zip-app-inactive-icon" />
								) : (
									<MagnifyingGlassIcon className="w-5 h-5 text-zip-app-inactive-icon" />
								) }
							</button>
						</div>
					}
				/>
			</form>

			<div
				ref={ templatesContainer }
				className={ classNames(
					'custom-confirmation-modal-scrollbar', // class for thin scrollbar
					'relative',
					'px-5 md:px-10 lg:px-14 xl:px-15',
					'xl:max-w-full'
				) }
			>
				<div
					ref={ templatesContainer }
					className={ classNames(
						'grid grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 auto-rows-auto items-start justify-center gap-6 mb-10'
					) }
				>
					{ ! isFetching
						? renderTemplates
						: Array.from( { length: 6 } ).map( ( _, index ) => (
								<ColumnSkeleton key={ `skeleton-${ index }` } />
						  ) ) }
				</div>
			</div>

			{ loadMoreTemplates.showLoadMore && (
				<div className="align-center flex justify-center">
					<Button
						className="min-w-[188px] min-h-[50px]"
						variant="primary"
						onClick={ () => {
							if ( loadMoreTemplates.loading ) {
								return;
							}
							fetchAllTemplatesByPage( loadMoreTemplates.page );
							setLoadMoreTemplates( {
								page: loadMoreTemplates.page + 1,
							} );
						} }
						disabled={ loadMoreTemplates.loading }
					>
						{ loadMoreTemplates.loading ? (
							<LoadingSpinner />
						) : (
							__( 'Load More Designs', 'ai-builder' )
						) }
					</Button>
				</div>
			) }

			{ backToTop && (
				<div className="absolute right-20 bottom-28 ml-auto">
					<button
						type="button"
						className="absolute bottom-0 right-0 z-10 w-8 h-8 rounded-full bg-accent-st border-0 border-solid text-white flex items-center justify-center shadow-sm cursor-pointer"
						onClick={ handleClickBackToTop }
					>
						<ChevronUpIcon className="w-5 h-5" />
					</button>
				</div>
			) }

			<div className="sticky bottom-0 bg-container-background py-4.75 px-5 md:px-10 lg:px-14 xl:px-15">
				<NavigationButtons
					onClickPrevious={ previousStep }
					hideContinue
				/>
			</div>
		</div>
	);
};

export default SelectTemplate;
<?php
/**
 * Step post type.
 *
 * @package CartFlows
 */

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}
/**
 * Initialization
 *
 * @since 1.0.0
 */
class Cartflows_Step_Post_Type {


	/**
	 * Member Variable
	 *
	 * @var instance
	 */
	private static $instance;

	/**
	 * Member Variable
	 *
	 * @var body_classes
	 */
	private $body_classes = array();

	/**
	 *  Initiator
	 */
	public static function get_instance() {
		if ( ! isset( self::$instance ) ) {
			self::$instance = new self();
		}
		return self::$instance;
	}

	/**
	 *  Constructor
	 */
	public function __construct() {

		add_action( 'init', array( $this, 'step_post_type' ) );
		add_action( 'init', array( $this, 'add_wp_templates_support' ) );
		add_filter( 'post_updated_messages', array( $this, 'post_update_messages' ) );

		add_filter( 'wp_unique_post_slug', array( $this, 'prevent_slug_duplicates' ), 10, 6 );

		add_filter( 'template_include', array( $this, 'load_page_template' ), 99 );
		add_action( 'template_redirect', array( $this, 'query_fix' ), 3 );

		add_action( 'admin_init', array( $this, 'disallowed_admin_all_steps_view' ) );
	}

	/**
	 * Trys to load page.php for a header, footer or part theme layout.
	 *
	 * @since 1.0.0
	 * @param string $template The current template to be loaded.
	 * @return string
	 */
	public function load_page_template( $template ) {

		global $post;

		if ( 'string' == gettype( $template ) && is_object( $post ) && CARTFLOWS_STEP_POST_TYPE === $post->post_type ) {

			/**
			 * Remove Next/Prev Navigation
			 * add_filter('next_post_link', '__return_empty_string');
			 * add_filter('previous_post_link', '__return_empty_string');
			 *
			 * $page = locate_template( array( 'page.php' ) );
			 *
			 * if ( ! empty( $page ) ) {
			 *  return $page;
			 * }
			 */

			/* Remove Next / Previous Rel Link */
			remove_action( 'wp_head', 'adjacent_posts_rel_link_wp_head', 10, 0 );
			add_filter( 'next_post_rel_link', '__return_empty_string' );
			add_filter( 'previous_post_rel_link', '__return_empty_string' );

			$page_template = Cartflows_Helper::get_current_page_template();

			$file = '';

			switch ( $page_template ) {

				case 'cartflows-default':
					$file                 = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
					$this->body_classes[] = $page_template;
					break;
				case 'cartflows-canvas':
					$file                 = CARTFLOWS_FLOW_DIR . 'templates/template-canvas.php';
					$this->body_classes[] = $page_template;
					break;
				default:
					/**
					 * Remove Next/Prev Navigation
					 */
					add_filter( 'next_post_link', '__return_empty_string' );
					add_filter( 'previous_post_link', '__return_empty_string' );

					$page = locate_template( array( 'page.php' ) );

					if ( ! empty( $page ) ) {
						$file = $page;
					}

					break;

				/**
				* Default:
				* $file  = CARTFLOWS_FLOW_DIR . 'templates/template-default.php';
				* $this->body_classes[] = 'cartflows-default';
				* break;
				*/
			}

			$file               = apply_filters( 'cartflows_page_template_file', $file );
			$this->body_classes = apply_filters( 'cartflows_page_template_body_classes', $this->body_classes );


			// Just to be safe, we check if the file exist first.
			if ( file_exists( $file ) ) {

				/* Add Body Class */
				add_filter( 'body_class', array( $this, 'body_class' ) );

				if ( apply_filters( 'cartflows_allow_to_change_page_template', true ) ) {
					$template = $file;
				}
				return $template;
			} else {
				echo wp_kses_post( $file );
			}
		}

		return $template;
	}

	/**
	 * Body classes.
	 *
	 * @since 1.0.0
	 * @param array $classes Body classes.
	 * @return array
	 */
	public function body_class( $classes = array() ) {

		$classes = array_merge( $classes, $this->body_classes );

		return $classes;
	}

	/**
	 * Create custom post type
	 */
	public function step_post_type() {

		$labels = array(
			'name'          => esc_html_x( 'Steps', 'flow step general name', 'cartflows' ),
			'singular_name' => esc_html_x( 'Step', 'flow step singular name', 'cartflows' ),
			'search_items'  => esc_html__( 'Search Steps', 'cartflows' ),
			'all_items'     => esc_html__( 'All Steps', 'cartflows' ),
			'edit_item'     => esc_html__( 'Edit Step', 'cartflows' ),
			'view_item'     => esc_html__( 'View Step', 'cartflows' ),
			'add_new'       => esc_html__( 'Add New', 'cartflows' ),
			'update_item'   => esc_html__( 'Update Step', 'cartflows' ),
			'add_new_item'  => esc_html__( 'Add New', 'cartflows' ),
			'new_item_name' => esc_html__( 'New Step Name', 'cartflows' ),
		);

		$permalink_settings = Cartflows_Helper::get_permalink_settings();

		$args = array(
			'labels'              => $labels,
			'public'              => true,
			'query_var'           => true,
			'can_export'          => true,
			'exclude_from_search' => true,
			'show_ui'             => true,
			'show_in_menu'        => false,
			'show_in_admin_bar'   => true,
			'show_in_rest'        => true,
			'supports'            => array( 'title', 'editor', 'elementor', 'revisions' ),
			'capability_type'     => 'post',
			'capabilities'        => array(
				'create_posts' => 'do_not_allow', // Prior to Wordpress 4.5, this was false.
			),
			'map_meta_cap'        => true,
		);

		if ( isset( $permalink_settings['permalink_structure'] ) && ! empty( $permalink_settings['permalink_structure'] ) ) {
			$args['rewrite'] = array(
				'slug'       => $permalink_settings['permalink_structure'],
				'with_front' => false,
			);

		} elseif ( isset( $permalink_settings['permalink'] ) && ! empty( $permalink_settings['permalink'] ) ) {

			$args['rewrite'] = array(
				'slug'       => $permalink_settings['permalink'],
				'with_front' => false,
			);
		}

		register_post_type( CARTFLOWS_STEP_POST_TYPE, $args );

		// Step Type.
		$args = array(
			'label'        => __( 'Step Type', 'cartflows' ),
			'public'       => false,
			'rewrite'      => false,
			'hierarchical' => false,
		);

		register_taxonomy( CARTFLOWS_TAXONOMY_STEP_TYPE, CARTFLOWS_STEP_POST_TYPE, $args );

		// Step Flow.
		$args = array(
			'label'        => __( 'Step Flow', 'cartflows' ),
			'public'       => false,
			'rewrite'      => false,
			'hierarchical' => false,
		);

		register_taxonomy( CARTFLOWS_TAXONOMY_STEP_FLOW, CARTFLOWS_STEP_POST_TYPE, $args );

		if ( is_admin() ) {
			/**
			 * Register 'Elementor' & 'Beaver Builder' site types.
			 *
			 * @see  self::add_terms();
			 */
			$taxonomy = CARTFLOWS_TAXONOMY_STEP_TYPE;

			$terms = array(
				array(
					'name' => __( 'Landing', 'cartflows' ),
					'slug' => 'landing',
					'args' => array(
						'slug' => 'landing',
					),
				),
				array(
					'name' => __( 'Optin', 'cartflows' ),
					'slug' => 'optin',
					'args' => array(
						'slug' => 'optin',
					),
				),
				array(
					'name' => __( 'Checkout', 'cartflows' ),
					'slug' => 'checkout',
					'args' => array(
						'slug' => 'checkout',
					),
				),
				array(
					'name' => __( 'Thank You', 'cartflows' ),
					'slug' => 'thankyou',
					'args' => array(
						'slug' => 'thankyou',
					),
				),
				array(
					'name' => __( 'Upsell', 'cartflows' ),
					'slug' => 'upsell',
					'args' => array(
						'slug' => 'upsell',
					),
				),
				array(
					'name' => __( 'Downsell', 'cartflows' ),
					'slug' => 'downsell',
					'args' => array(
						'slug' => 'downsell',
					),
				),
			);

			$this->add_terms( $taxonomy, $terms );

		}
	}

	/**
	 * Add WordPress templates.
	 *
	 * Adds Cartflows templates to steps
	 *
	 * @since 1.0.0
	 * @access public
	 */
	public function add_wp_templates_support() {
		add_filter( 'theme_' . CARTFLOWS_STEP_POST_TYPE . '_templates', array( $this, 'add_page_templates' ), 99, 4 );
	}

	/**
	 * Add page templates.
	 *
	 * @since 1.0.0
	 * @access public
	 *
	 * @param array  $page_templates Array of page templates.
	 *
	 * @param object $wp_theme wp theme.
	 * @param object $post post.
	 *
	 * @return array Page templates.
	 */
	public function add_page_templates( $page_templates, $wp_theme, $post ) {

		$cartflows_templates = array(
			'cartflows-default' => _x( 'CartFlows — Boxed', 'cartflows' ),
			'cartflows-canvas'  => _x( 'Template for Page Builders', 'cartflows' ),
		);

		if ( apply_filters( 'cartflows_show_all_page_templates', false ) ) {
			$cartflows_templates = array_merge( $cartflows_templates, $page_templates );
		}

		return $cartflows_templates;
	}

	/**
	 * Query fixe throwing error on 404 page due our post type changes.
	 * We are setting post_type as empty array to fix the issue.
	 * Ther error was throwing due to redirect_canonical function
	 * This fix is apply for 404 page only
	 */
	public function query_fix() {

		global $wp_query;

		if ( $wp_query->is_404() ) {
			$wp_query->set( 'post_type', array() );
		}
	}

	/**
	 * Prevent slug duplicated
	 *
	 * @param string $slug post slug.
	 * @param int    $post_ID post id.
	 * @param string $post_status post status.
	 * @param string $post_type post type.
	 * @param int    $post_parent post parent id.
	 * @param string $original_slug original slug.
	 * @return string
	 */
	public function prevent_slug_duplicates( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {

		$check_post_types = array(
			'post',
			'page',
			CARTFLOWS_STEP_POST_TYPE,
		);

		if ( ! in_array( $post_type, $check_post_types, true ) ) {
			return $slug;
		}

		if ( CARTFLOWS_STEP_POST_TYPE == $post_type ) {
			// Saving a post, check for duplicates in POST or PAGE post types.
			$post_match = get_page_by_path( $slug, 'OBJECT', 'post' );
			$page_match = get_page_by_path( $slug, 'OBJECT', 'page' );

			if ( $post_match || $page_match ) {
				$slug .= '-2';
			}
		} else {

			// Saving a POST or PAGE, check for duplicates in CARTFLOWS_STEP_POST_TYPE post type.
			$custom_post_type_match = get_page_by_path( $slug, 'OBJECT', CARTFLOWS_STEP_POST_TYPE );

			if ( $custom_post_type_match ) {
				$slug .= '-2';
			}
		}

		return $slug;
	}

	/**
	 * Add Update messages for any custom post type
	 *
	 * @param array $messages Array of default messages.
	 */
	public function post_update_messages( $messages ) {

		$custom_post_type = get_post_type( get_the_ID() );

		if ( CARTFLOWS_STEP_POST_TYPE == $custom_post_type ) {

			$obj                           = get_post_type_object( $custom_post_type );
			$singular_name                 = $obj->labels->singular_name;
			$messages[ $custom_post_type ] = array(
				0  => '', // Unused. Messages start at index 1.
				/* translators: %s: singular custom post type name */
				1  => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				2  => sprintf( __( 'Custom %s updated.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				3  => sprintf( __( 'Custom %s deleted.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				4  => sprintf( __( '%s updated.', 'cartflows' ), $singular_name ),
				/* translators: %1$s: singular custom post type name ,%2$s: date and time of the revision */
				5  => isset( $_GET['revision'] ) ? sprintf( __( '%1$s restored to revision from %2$s', 'cartflows' ), $singular_name, wp_post_revision_title( (int) $_GET['revision'], false ) ) : false, //phpcs:ignore WordPress.Security.NonceVerification.Recommended
				/* translators: %s: singular custom post type name */
				6  => sprintf( __( '%s published.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				7  => sprintf( __( '%s saved.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				8  => sprintf( __( '%s submitted.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				9  => sprintf( __( '%s scheduled for.', 'cartflows' ), $singular_name ),
				/* translators: %s: singular custom post type name */
				10 => sprintf( __( '%s draft updated.', 'cartflows' ), $singular_name ),
			);
		}

		return $messages;
	}

	/**
	 * Add Terms for Taxonomy.
	 *
	 * => Example.
	 *
	 *  $taxonomy = '{taxonomy}';
	 *  $terms    = array(
	 *                  array(
	 *                      'name'  => 'Landing',
	 *                      'slug'  => 'landing',
	 *                  ),
	 *                  array(
	 *                      'name'  => 'Checkout',
	 *                      'slug'  => 'checkout',
	 *                  ),
	 *              );
	 *
	 *  self::add_terms( $taxonomy, $terms );
	 *
	 * @since 1.0.0
	 * @param string $taxonomy Taxonomy Name.
	 * @param array  $terms    Terms list.
	 * @return void
	 */
	public function add_terms( $taxonomy = '', $terms = array() ) {

		foreach ( $terms as $key => $term ) {

			$term_exist = term_exists( $term['slug'], $taxonomy );

			if ( empty( $term_exist ) ) {

				/**
				 * Add additional args if passed from request.
				 *
				 * @see https://codex.wordpress.org/Function_Reference/wp_insert_term
				 */
				if ( array_key_exists( 'args', $term ) ) {
					wp_insert_term( $term['name'], $taxonomy, $term['args'] );
				} else {

					$term['args'] = array( $term['slug'] );

					wp_insert_term( $term['name'], $taxonomy, $term['args'] );
				}
			}
		}
	}

	/**
	 * Redirect admin pages.
	 *
	 * @return void
	 */
	public function disallowed_admin_all_steps_view() {

		global $pagenow;

		// Check current admin page. If step post type view redirect it to flow.
		if ( 'edit.php' === $pagenow && isset( $_GET['post_type'] ) && CARTFLOWS_STEP_POST_TYPE === $_GET['post_type'] ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended

			if ( isset( $_GET['debug'] ) && 'true' === sanitize_text_field( $_GET['debug'] ) ) { //phpcs:ignore WordPress.Security.NonceVerification.Recommended
				return;
			}

			wp_safe_redirect( admin_url( 'edit.php?post_type=' . CARTFLOWS_FLOW_POST_TYPE ) );
			exit;
		}
	}
}

/**
 *  Kicking this off by calling 'get_instance()' method
 */
Cartflows_Step_Post_Type::get_instance();
.uagb-block-b4c4a866.uagb-forms__outer-wrap{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}.uagb-block-b4c4a866 .uagb-forms-main-form textarea{text-align: left;}.uagb-block-b4c4a866 .uagb-forms-input{text-align: left;}.uagb-block-b4c4a866 .uagb-forms-input-label{display: none;text-align: left;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-field-set{margin-bottom: 20px;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-input-label{font-size: 15px;margin-bottom: 10px;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-input:focus{outline:  none !important;background-color:  !important;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-input:focus::placeholder{color:  !important;}.uagb-block-b4c4a866 .uagb-slider.round{border-radius: 20px !important;}.uagb-block-b4c4a866 .uagb-form-phone-country{background: url(data:image/svg+xml;base64,PHN2ZyB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgd2lkdGg9JzE4cHgnIGhlaWdodD0nMThweCcgeG1sOnNwYWNlPSJwcmVzZXJ2ZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCA1MTIgNTEyIj48cGF0aCBkPSJtMzk2LjYgMTYwIDE5LjQgMjAuN0wyNTYgMzUyIDk2IDE4MC43bDE5LjMtMjAuN0wyNTYgMzEwLjV6IiBmaWxsPSIjMWQyMzI3IiBjbGFzcz0iZmlsbC0wMDAwMDAiPjwvcGF0aD48L3N2Zz4=) no-repeat;-moz-appearance: none !important;-webkit-appearance:  none !important;background-position:  top 50% right 10px;appearance: none !important;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-main-submit-button-wrap{text-align: left;}.uagb-block-b4c4a866 .uagb-forms-checkbox-wrap input[type=checkbox] + label:before{background-color: #ffffff;width: 15px;height: 15px;}.uagb-block-b4c4a866 .uagb-forms-radio-wrap input[type=radio] + label:before{background-color: #ffffff;width: 15px;height: 15px;}.uagb-block-b4c4a866 .uagb-slider{background-color: #ffffff;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-switch{height: calc(1px + 1px + 26px);width: calc(1px + 1px + 56px);}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-slider:before{height: 20px;width: 20px;top: 3px;bottom: 3px;left: 3px;background-color: #1e1e1e;border-radius: 3px 3px 3px 3px;}.uagb-block-b4c4a866 .uagb-switch input:checked + .uagb-slider{background-color: #017cba;}.uagb-block-b4c4a866 .uagb-switch input:checked + .uagb-slider:before{transform: translateX(30px);background-color: #ffffff;}.uagb-block-b4c4a866 .uagb-switch input:focus + .uagb-slider{box-shadow: 0 0 1px#017cba;}.uagb-block-b4c4a866 .uagb-forms-accept-wrap input[type=checkbox] + label:before{background-color: #ffffff;width: 15px;height: 15px;}.uagb-block-b4c4a866 .uagb-forms-main-form  .uagb-forms-input{border-top: 0;border-left: 0;border-right: 0;outline: 0;border-radius: 0;background: transparent;border-bottom: 1px solid #BDBDBD;padding-top: 0px;padding-bottom: 10px;padding-left: 0px;padding-right: 10px;border-top-width: 1px;border-left-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-top-left-radius: 3px;border-top-right-radius: 3px;border-bottom-left-radius: 3px;border-bottom-right-radius: 3px;border-color: #BDBDBD;border-style: solid;}.uagb-block-b4c4a866 .uagb-forms-main-form  .uagb-forms-accept-wrap input[type=checkbox] + label:before{border-bottom: 1px solid #BDBDBD;}.uagb-block-b4c4a866 .uagb-forms-main-form  .uagb-forms-checkbox-wrap input[type=checkbox] + label:before{border-bottom: 1px solid #BDBDBD;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-slider{border-bottom: 1px solid #BDBDBD;}.uagb-block-b4c4a866 .uagb-forms-main-form  .uagb-forms-radio-wrap input[type=radio] + label:before{border-bottom: 1px solid #BDBDBD;}.uagb-block-b4c4a866.uagb-forms__outer-wrap .uagb-forms-main-form  .uagb-forms-input{border-top-width: 0;border-right-width: 0;border-left-width: 0;border-bottom-width: 1px;}.uagb-block-b4c4a866 .uagb-forms-checkbox-wrap input[type=checkbox]:checked + label:before{color: #ffffff;background-color: #017cba;font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-radio-wrap input[type=radio]:checked + label:before{background-color: #ffffff;box-shadow: inset 0 0 0 4px #017cba;font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-accept-wrap input[type=checkbox]:checked + label:before{color: #ffffff;background-color: #017cba;font-size: calc(15px / 1.2);}@media only screen and (max-width: 976px) {.uagb-block-b4c4a866.uagb-forms__outer-wrap{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-input-label{font-size: 15px;}.uagb-block-b4c4a866 .uagb-slider.round{border-radius: 20px !important;}.uagb-block-b4c4a866 .uagb-form-phone-country{background-position: top 50% right 12px;padding-right: 30px;}.uagb-block-b4c4a866 .uagb-switch input:checked + .uagb-slider:before{transform: translateX(30px);}.uagb-block-b4c4a866 .uagb-forms-checkbox-wrap input[type=checkbox]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-radio-wrap input[type=radio]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-accept-wrap input[type=checkbox]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-switch{height: calc(1px + 1px + 26px);width: calc(1px + 1px + 56px);}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-slider:before{height: calc(20px + 0px);width: calc(20px + 0px);top: 3px;bottom: 3px;left: 3px;border-radius: 3px 3px 3px 3px;}}@media only screen and (max-width: 767px) {.uagb-block-b4c4a866.uagb-forms__outer-wrap{padding-top: 0px;padding-right: 0px;padding-bottom: 0px;padding-left: 0px;}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-forms-input-label{font-size: 15px;}.uagb-block-b4c4a866 .uagb-slider.round{border-radius: 20px !important;}.uagb-block-b4c4a866 .uagb-form-phone-country{background-position: top 50% right 6px;padding-right: 30px;}.uagb-block-b4c4a866 .uagb-switch input:checked + .uagb-slider:before{transform: translateX(30px);}.uagb-block-b4c4a866 .uagb-forms-checkbox-wrap input[type=checkbox]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-radio-wrap input[type=radio]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-accept-wrap input[type=checkbox]:checked + label:before{font-size: calc(15px / 1.2);}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-switch{height: calc(1px + 1px + 26px);width: calc(1px + 1px + 56px);}.uagb-block-b4c4a866 .uagb-forms-main-form .uagb-slider:before{height: calc(20px + 0px);width: calc(20px + 0px);top: 3px;bottom: 3px;left: 3px;border-radius: 3px 3px 3px 3px;}}