<?php

namespace TotalTheme\Integration\WPBakery;

defined( 'ABSPATH' ) || exit;

final class Patterns {

	/**
	 * Template Type Name.
	 */
	public const TEMPLATE_TYPE = 'totaltheme_patterns';

	/**
	 * Init.
	 */
	public static function init() {
		if ( ! self::is_enabled() ) {
			return;
		}
		
		if ( is_admin() || self::is_loading_pattern() ) {
			add_action( 'vc_get_all_templates', [ self::class, 'register_templates' ] );
			add_action( 'vc_templates_render_category', [ self::class, 'render_patterns_tab' ] );
			add_action( 'vc_templates_render_backend_template', [ self::class, 'render_backend_pattern' ], 10, 2 );
			add_action( 'vc_templates_render_frontend_template', [ self::class, 'render_frontend_pattern' ], 10, 2 );
			add_action( 'vc_frontend_editor_enqueue_js_css', [ self::class, 'enqueue_scripts' ] );
			add_action( 'vc_backend_editor_enqueue_js_css', [ self::class, 'enqueue_scripts' ] );
			add_action( 'wp_ajax_totaltheme_get_wpb_patterns', [ self::class, '_get_patterns_ajax_callback' ] );
		}
	}

	/**
	 * Checks if the functionality is enabled.
	 */
	protected static function is_enabled(): bool {
		return wp_validate_boolean( \get_theme_mod( 'section_templates_enable', true ) );
	}

	/**
	 * Checks if currently inserting a pattern via ajax.
	 */
	protected static function is_loading_pattern(): bool {
		return function_exists( 'vc_post_param' )
			&& in_array( vc_post_param( 'action' ), [ 'vc_frontend_load_template', 'vc_backend_load_template' ], true );
	}

	/**
	 * Returns current category name.
	 */
	public static function get_category_name() {
		return esc_html__( 'Patterns', 'total' );
	}

	/**
	 * Returns current category name.
	 */
	public static function get_category_description() {
		return esc_html__( 'Append a pattern to the current layout.', 'total' );
	}

	/**
	 * Register templates.
	 */
	public static function register_templates( $data ) {
		$templates = apply_filters( 'wpex_wpbakery_section_templates', true );
		$templates = (bool) apply_filters( 'totaltheme/integration/wpbakery/patterns/list', $templates );
		if ( ! $templates ) {
			return $data;
		}
		$data[] = [
			'category'             => self::TEMPLATE_TYPE,
			'category_name'        => self::get_category_name(),
			'category_description' => self::get_category_description(),
			'category_weight'      => apply_filters( 'totaltheme/integration/wpbakery/patterns/category_weight', 11 ),
			// Register a dummy template so the tab appears in WPBakery but without having to call all of our patterns
			'templates'            => [
				[
					'unique_id' => 'dummy-template',
					'name'      => 'Dummy Template',
					'type'      => self::TEMPLATE_TYPE,
					'content'   => 'dummy template content',
					'weight'    => 1,
				]
			],
		];
		return $data;
	}

	/**
	 * Ajax callback for getting patterns.
	 */
	public static function _get_patterns_ajax_callback(): void {
		check_ajax_referer( 'totaltheme_get_wpb_patterns_nonce', 'nonce' );
		if ( ! empty( $_GET['post_type'] ) ) {
			// Don't show header/footer/dynamic when not editing dynamic templates.
		}
		wp_send_json_success( [
			'patterns_list' => self::get_patterns_data(),
			'categories'    => self::get_categories(),
		] );
	}

	/**
	 * Returns patterns list.
	 */
	protected static function get_patterns( string $category = '' ): array {
		$theme_uri     = untrailingslashit( WPEX_THEME_URI );
		$ph_location   = "{$theme_uri}/inc/integration/wpbakery/patterns/placeholders/";
		$ph_logo       = "{$ph_location}logo.svg";
		$ph_logo_white = "{$ph_location}logo-dark.svg";
		$ph_landscape  = "{$ph_location}landscape.png";
		$ph_portrait   = "{$ph_location}portrait.png";
		$ph_square     = "{$ph_location}square.png";
		$banner_728x90 = "{$ph_location}banner_728x90.png";
		$all_patterns  = [];
		$categories    = self::get_categories();
		if ( $category && isset( $categories[ $category ] ) ) {
			$categories = [
				$category => $categories[ $category ],
			];
		}
		foreach ( $categories as $key => $name ) {
			$file = WPEX_INC_DIR . "integration/wpbakery/patterns/categories/{$key}.php";
			if ( file_exists( $file ) ) {
				$cat_patterns = require $file;
				$count = 0;
				foreach ( $cat_patterns as $id => $pattern ) {
					$count++;
					if ( ! isset( $pattern['name'] ) ) {
						$pattern['name'] = "{$name} {$count}";
					}
					if ( ! isset( $pattern['category'] ) ) {
						$pattern['category'] = $key;
					}
					$all_patterns[ $id ] = $pattern;
				}
			}
		}
		$patterns = apply_filters( 'wpex_wpbakery_section_templates', $all_patterns ); // @deprecated
		return (array) apply_filters( 'totaltheme/integration/wpbakery/patterns/list', $patterns );
	}

	/**
	 * Returns pattern category.
	 */
	protected static function get_pattern_category( string $template_id = '' ): string {
		$category = trim( preg_replace( '/[^a-z]/', '', $template_id ) );
		if ( 'calltoaction' === $category ) {
			$category = 'call-to-action';
		}
		return $category;
	}

	/**
	 * Wrapper for vc_slufify()
	 */
	protected static function slugify( $str = '' ) {
		if ( function_exists( 'vc_slugify' ) ) {
			return vc_slugify( $str );
		}
		$str = strtolower( $str );
		$str = html_entity_decode( $str );
		$str = preg_replace( '/[^\w ]+/', '', $str );
		$str = preg_replace( '/ +/', '-', $str );
		return $str;
	}

	/**
	 * Get patterns data.
	 */
	protected static function get_patterns_data(): array {
		$data      = [];
		$theme_uri = untrailingslashit( WPEX_THEME_URI );
		foreach ( self::get_patterns() as $pattern_id => $pattern_data ) {
			$pattern = [
				'id'         => $pattern_id,
				'unique_id'  => $pattern_id,
				'id_hash'    => md5( $pattern_id ),
				'label'      => $pattern_data['name'],
				'name'       => self::slugify( $pattern_data['name'] ),
				'category'   => $pattern_data['category'] ?? self::get_pattern_category( $pattern_id ),
				'screenshot' => $pattern_data['screenshot'] ?? "{$theme_uri}/inc/integration/wpbakery/patterns/categories/thumbnails/{$pattern_id}.webp",
			];
			$pattern = array_map( 'esc_attr', $pattern );
			$data[]  = $pattern;
		}
		return $data;
	}

	/**
	 * Get patterns JSON.
	 */
	protected static function get_patterns_json(): string {
		return wp_json_encode( $patterns_data );
	}

	/**
	 * Render the patterns tab.
	 */
	public static function render_patterns_tab( $category ) {
		if ( self::TEMPLATE_TYPE === $category['category'] ) {
			$category['output'] = self::get_vc_tab_template();
		}
		return $category;
	}

	/**
	 * Get categories.
	 */
	protected static function get_categories(): array {
		$categories = [
			'hero'           => esc_html__( 'Hero', 'total' ),
			'features'       => esc_html__( 'Features', 'total' ),
			'statistics'     => esc_html__( 'Statistics', 'total' ),
			'team'           => esc_html__( 'Team', 'total' ),
			'call-to-action' => esc_html__( 'Call to Action', 'total' ),
			'faq'            => esc_html__( 'FAQ', 'total' ),
			'subscribe'      => esc_html__( 'Subscribe', 'total' ),
			'pricing'        => esc_html__( 'Pricing', 'total' ),
			'contact'        => esc_html__( 'Contact', 'total' ),
			'header'         => esc_html__( 'Header', 'total' ),
			'header-dark'    => esc_html__( 'Header - Dark', 'total' ),
		//	'blog-post'      => esc_html__( 'Blog Post', 'total' ),
		//	'blog-archive'   => esc_html__( 'Blog Archive', 'total' ),
		//	'cards'          => esc_html__( 'Cards', 'total' ),
			'footer'         => esc_html__( 'Footer', 'total' ),
			'footer-dark'    => esc_html__( 'Footer - Dark', 'total' ),
		];
		$categories = apply_filters_deprecated(
			'wpex_wpbakery_section_templates_categories',
			[ $categories ],
			'Total 6.0',
			'totaltheme/integration/wpbakery/patterns/categories'
		);
		return (array) apply_filters( 'totaltheme/integration/wpbakery/patterns/categories', $categories );
	}

	/**
	 * Renders the items for the patterns tab.
	 */
	protected static function get_vc_tab_template() {
		ob_start();
			require_once WPEX_INC_DIR . 'integration/wpbakery/patterns/category.tpl.php';
		return ob_get_clean();
	}

	/**
	 * Render pattern for the backend editor.
	 */
	public static function render_backend_pattern( $pattern_id, $template_type ) {
		if ( self::TEMPLATE_TYPE === $template_type ) {
			$category = self::get_pattern_category_from_id( $pattern_id );
			if ( $category ) {
				$pattern_content = (string) self::get_patterns( $category )[ $pattern_id ]['content'] ?? '';
			} else {
				$pattern_content = (string) self::get_patterns()[ $pattern_id ]['content'] ?? '';
			}
			if ( $pattern_content ) {
				return trim( $pattern_content );
			}
		}
		return $pattern_id;
	}

	/**
	 * Renders the pattern for the frontend editor.
	 */
	public static function render_frontend_pattern( $pattern_id, $template_type ) {
		if ( self::TEMPLATE_TYPE === $template_type ) {
			$category = self::get_pattern_category_from_id( $pattern_id );
			if ( $category ) {
				$pattern_content = (string) self::get_patterns( $category )[ $pattern_id ]['content'] ?? '';
			} else {
				$pattern_content = (string) self::get_patterns()[ $pattern_id ]['content'] ?? '';
			}
			if ( $pattern_content ) {
				vc_frontend_editor()->setTemplateContent( trim( $pattern_content ) );
				vc_frontend_editor()->enqueueRequired();
				vc_include_template( 'editors/frontend_template.tpl.php', [
					'editor' => vc_frontend_editor(),
				] );
				die(); // important wp_die() causes the page to break - can't use.
			}
			wp_send_json_error( [
				'code' => 'Wrong ID or no Template found #3',
			] );
		}
		return $pattern_id;
	}
	
	/**
	 * Returns the category from a pattern id.
	 */
	private static function get_pattern_category_from_id( string $pattern_id = '' ): string {
		$pos = $pos = strrpos( $pattern_id, '-' );
		if ( $pos !== false ) {
			return substr( $pattern_id, 0, $pos );
		}
		return '';
	}

	/**
	 * Enqueues the Patterns JS.
	 *
	 */
	public static function enqueue_scripts() {
		wp_enqueue_script(
			'totaltheme-wpbakery-patterns',
			totaltheme_get_js_file( 'admin/wpbakery/patterns' ),
			[ 'jquery' ],
			WPEX_THEME_VERSION,
			true
		);
		wp_localize_script( 'totaltheme-wpbakery-patterns', 'totaltheme_wpbakery_patterns_params', [
			'nonce' => wp_create_nonce( 'totaltheme_get_wpb_patterns_nonce' ),
			'i18n'  => [
				'retry'  => esc_html__( 'Retry', 'total' ),
				'failed' => esc_html__( 'Failed to load patterns.', 'total' ),
			],
		] );
	}

	/**
	 * Renders the items for the patterns tab.
	 */
	protected static function render_patterns_tab_item( $template ) {
		// @deprecated - we now use category.tpl.php and JS
	}

}
