<?php

/**
 * The admin-specific functionality of the plugin.
 *
 * @link       https://wpconfiguratorbuilder.com/
 * @since      1.0.0
 *
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/admin
 */

if ( ! defined('ABSPATH') ) {
	die();
}

/**
 * The admin-specific functionality of the plugin.
 *
 * Defines the plugin name, version, and two examples hooks for how to
 * enqueue the admin-specific stylesheet and JavaScript.
 *
 * @package    wcb-configurator-builder
 * @subpackage wcb-configurator-builder/admin
 * @author     WPCB <support@wpconfiguratorbuilder.com>
 */
class WPCB_Admin {

	/**
	 * The ID of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $plugin_name    The ID of this plugin.
	 */
	private $plugin_name;

	/**
	 * The version of this plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      string    $version    The current version of this plugin.
	 */
	private $version;

	/**
	 * The list of this plugin available post types.
	 *
	 * @since    1.0.0
	 * @access   private
	 * @var      array    $post_types   The list of WCB plugin post types
	 */
	private $post_types;

	/**
	 * Initialize the class and set its properties.
	 *
	 * @since    1.0.0
	 * @param      string $plugin_name       The name of this plugin.
	 * @param      string $version    The version of this plugin.
	 */
	public function __construct( $plugin_name, $version ) {
		$this->plugin_name = $plugin_name;
		$this->version     = $version;
		$this->post_types  = array( 'wpcb_configuration', 'wpcb_input', 'wpcb_choice', 'wpcb_visual', 'wpcb_formula', 'wpcb_template' );

		add_action( 'in_admin_header', array( $this, 'admin_header_bar' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );

		add_filter( 'use_block_editor_for_post_type', array( $this, 'auto_enable_block_editor' ), 999, 2 );
		add_filter( 'wp_generate_attachment_metadata', array( $this, 'fix_svg_metadata' ), 10, 2 );

		add_filter( 'post_row_actions', array( $this, 'add_duplicate_post_link' ), 10, 2);
		add_action( 'admin_action_wpcb_duplicate_post', array( $this, 'admin_duplicate_post_action' ) );
		add_action( 'admin_notices', array( $this, 'show_duplicate_post_notice' ) );
		add_action( 'admin_notices', array( $this, 'show_plugin_admin_notices' ) );
		add_action( 'admin_init', array( $this, 'edit_admin_footer' ) );
		add_action( 'admin_init', array( $this, 'run_demo_importer' ) );
		add_action( 'admin_menu', array( $this, 'register_pages' ), 999 );

		add_action( 'admin_menu', array( $this, 'hide_menu_for_roles' ), 999 );
		add_action( 'admin_bar_menu', array( $this, 'remove_admin_bar_for_roles' ), 999 );
		add_action( 'current_screen', array( $this, 'block_all_wcb_screens_for_roles' ) );

		add_action( 'wp_ajax_wpcb_update_analytics', array( $this, 'ajax_update_configuration_analytics' ) );
		add_action( 'wp_ajax_nopriv_wpcb_update_analytics', array( $this, 'ajax_update_configuration_analytics' ) );
		
		add_action( 'wp_ajax_wpcb_update_statistics', array( $this, 'ajax_update_configuration_stats' ) );
		add_action( 'wp_ajax_nopriv_wpcb_update_statistics', array( $this, 'ajax_update_configuration_stats' ) );

		add_filter( 'upload_mimes', array( $this, 'allow_glb_mime_types' ), 10, 2 );
		add_filter( 'wp_check_filetype_and_ext', array( $this, 'add_glb_mime_check' ), 10, 5 );
	}

	/**
	 * Register the stylesheets for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function enqueue_scripts() {
		global $typenow;
		$types = $this->post_types;

		wp_enqueue_style( 'wp-color-picker' );
		wp_enqueue_style( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'css/wpcb-admin.css', array(), $this->version, 'all' );
		
		if ( ! $typenow ) {
			return;
		}
		if ( ! in_array( $typenow, $types ) ) {
			return;
		}

		wp_enqueue_script( $this->plugin_name, plugin_dir_url( __FILE__ ) . 'js/wpcb-admin.js', array('wp-color-picker', 'jquery'), $this->version, true );
	}

	/**
	 * Make sure block editor is active always
	 *
	 * @since    1.0.0
	 */
	public function auto_enable_block_editor($use_block_editor, $post_type) {
		if ($post_type === 'wpcb_configuration') {
			return true;
		}
		return $use_block_editor;
	}

	/**
	 * Make sure block editor is active always
	 *
	 * @since    1.0.0
	 */
	public function ajax_update_configuration_analytics() {
		if ( function_exists( 'wpcb_analytics_update_configuration_stats' ) ) {
			wpcb_analytics_update_configuration_stats();
		}
		echo '1';
		die();
	}

	/**
	 * Make sure block editor is active always
	 *
	 * @since    1.0.0
	 */
	public function ajax_update_configuration_stats() {
		if ( function_exists( 'wpcb_collect_configuration_item_stats' ) ) {
			$id = isset( $_POST['post_id'] ) ? sanitize_text_field( wp_unslash( $_POST['post_id'] ) ) : '';
			$selections = isset( $_POST['selections'] ) ? array_filter( wp_unslash( $_POST['selections'] ) ) : '';

			wpcb_collect_configuration_item_stats( $id, $selections );
		}
		echo '1';
		die();
	}

	/**
	 * Fix SVG attachment dimensions meta
	 *
	 * @since    1.0.0
	 */
	public function fix_svg_metadata( $data, $id ) {
		$attachment = get_post( $id );
		if ($attachment->post_mime_type !== 'image/svg+xml') {
			return $data;
		}

		$file_path = get_attached_file( $id );
		if ( ! file_exists( $file_path ) ) {
			return $data;
		}

		$svg = simplexml_load_file( $file_path );
		if ( $svg && isset( $svg['width'] ) && isset( $svg['height'] ) ) {
			$width = (int) $svg['width'];
			$height = (int) $svg['height'];

			if ( $width > 0 && $height > 0 ) {
				$data['width'] = $width;
				$data['height'] = $height;
			}
		}

		return $data;
	}

	/**
	 * Register the header bar for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function admin_header_bar() {
		global $typenow;
		$types = $this->post_types;
		if ( ! $typenow ) {
			return;
		}
		if ( ! in_array( $typenow, $types ) ) {
			return;
		}
		if ( get_current_screen()->is_block_editor ) {
			return;
		}
		if ( isset( $_GET['page'] ) && 'setup' === $_GET['page'] ) {
			return;
		}

		include 'partials/admin-header.php';
	}

	/**
	 * Short description.
	 *
	 * @since    1.0.0
	 */
	public function register_pages() {
		add_submenu_page(
			'edit.php?post_type=wpcb_configuration',
			__( 'Welcome', 'wcb-configurator-builder' ),
			__( 'Welcome', 'wcb-configurator-builder' ),
			'edit_posts',
			'welcome',
			array( $this, 'welcome_page_contents' )
		);

		add_submenu_page(
			'edit.php?post_type=wpcb_configuration',
			__( 'Setup', 'wcb-configurator-builder' ),
			__( 'Setup', 'wcb-configurator-builder' ),
			'edit_posts',
			'setup',
			array( $this, 'setup_page_contents' )
		);
	}

	/**
	 * Welcome page contents
	 *
	 * @since    1.0.0
	 */
	public function welcome_page_contents() {
		// Show page contents.
		include 'partials/welcome-page.php';
	}

	/**
	 * Setup wizard page contents
	 *
	 * @since    1.0.0
	 */
	public function setup_page_contents() {
		// Show page contents.
		include 'partials/setup-page.php';
	}

	/**
	 * Dplication post action link
	 *
	 * @since    1.0.0
	 */
	public function add_duplicate_post_link($actions, $post) {
		if ( ! current_user_can('edit_posts') ) {
			return $actions;
		}

		global $typenow;
		$types = $this->post_types;
		if ( ! $typenow ) {
			return $actions;
		}
		if ( ! in_array( $typenow, $types ) ) {
			return $actions;
		}

		$url = wp_nonce_url(
			admin_url('admin.php?action=wpcb_duplicate_post&post=' . $post->ID),
			basename(__FILE__),
			'duplicate_nonce'
		);

		$actions['duplicate'] = '<a href="' . esc_url($url) . '" title="' .  esc_attr__( 'Duplicate this item', 'wcb-configurator-builder' ) . '">' . esc_attr__( 'Duplicate', 'wcb-configurator-builder' ) . '</a>';

		return $actions;
	}

	/**
	 * Dplication post action
	 *
	 * @since    1.0.0
	 */
	public function admin_duplicate_post_action() {
		if ( ! isset( $_GET['post'] ) || ! isset( $_GET['duplicate_nonce'] ) || ! wp_verify_nonce( $_GET['duplicate_nonce'], basename(__FILE__) ) ) {
			wp_die( esc_attr__('Security check failed', 'wcb-configurator-builder') );
		}

		$post_id = absint($_GET['post']);
		$post = get_post($post_id);

		if ($post) {
			// Add extra slash to unicode characters so they get rendered correctly in duplicate posts.
			$post_content = str_replace( '\\u', "\\\\u", $post->post_content );

			$new_post = array(
				'post_title'     => $post->post_title . ' (' . __( 'Copy', 'wcb-configurator-builder' ) . ')',
				'post_content'   => $post_content,
				'post_excerpt'   => $post->post_excerpt,
				'post_status'    => 'draft',
				'post_type'      => $post->post_type,
				'post_author'    => get_current_user_id(),
			);

			$new_post_id = wp_insert_post($new_post);

			// Copy custom fields
			$meta = get_post_meta($post_id);
			$analytics_keys = array( '_wpcb_entry_count', '_wpcb_entry_rate', '_wpcb_view_count', '_wpcb_quote_count', 
				'_wpcb_cart_count', '_wpcb_email_count', '_wpcb_pdf_count', '_wpcb_save_count', '_wpcb_wishlist_count',
				'_wpcb_capture_count', 'wpcb_saves_links', 'wpcb_pdfs_links','wpcb_stats' );

			foreach ($meta as $key => $values) {
				if ( in_array( $key, $analytics_keys ) ) {
					continue;
				}

				foreach ($values as $value) {
					add_post_meta($new_post_id, $key, maybe_unserialize($value));
				}
			}

			$redirect_url = admin_url('edit.php?post_type=' . $post->post_type . '&duplicate_success=1');
			wp_safe_redirect( $redirect_url );
			exit;
		} else {
			wp_die( esc_attr__( 'Post creation failed', 'wcb-configurator-builder' ) );
		}
	}

	/**
	 * Register the footer text for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function edit_admin_footer() {
		global $typenow;

		$types = $this->post_types;
		$post_type = false;
		if ( isset( $_GET['post'] ) ) {
			$post_id = sanitize_key( $_GET['post'] );
			$post_type = get_post_type( $post_id );
		}

		if ( ( $typenow && in_array( $typenow, $types ) ) || in_array( $post_type, $types ) ) {
			add_filter( 'admin_footer_text', array( $this, 'edit_admin_footer_text' ) , 11 );
			add_filter( 'update_footer', array( $this, 'edit_admin_footer_version' ) , 11 );
		}
	}

	/**
	 * Handle demo configuration import action.
	 *
	 * @since    1.3.0
	 */
	public function run_demo_importer() {
		global $typenow;
		if ( ! $typenow || 'wpcb_configuration' !== $typenow ) {
			return;
		}
		if ( ! isset( $_GET['method'] ) || $_GET['method'] !== 'import_demo' ) {
			return;
		}

		$import_type = 'image';
		if ( 'model' === wpcb_get_option( 'wpcb_configuration_visual_type' )  ) {
			if ( ! file_exists( WPCB_BASE . '/admin/demos/sofa.json' ) ) {
				return;
			}
			$import_type = 'model';
			$json = file_get_contents( WPCB_BASE . '/admin/demos/sofa.json' );
		} else {
			if ( ! file_exists( WPCB_BASE . '/admin/demos/watch.json' ) ) {
				return;
			}
			$json = file_get_contents( WPCB_BASE . '/admin/demos/watch.json' );
		}

		$json_array = json_decode( $json, true );
		$choice_imports = [];
		if ( isset( $json_array['choices'] ) && is_array( $json_array['choices'] ) ) {
			foreach ( $json_array['choices'] as $choice ) {
				$post_id = wp_insert_post( array(
					'post_title'  => $choice['post_title'],
					'post_type'   => 'wpcb_choice',
					'post_status' => 'publish',
				));

				update_post_meta( $post_id, '_label', $choice['title'] );
				update_post_meta( $post_id, '_type', $choice['type'] );
				update_post_meta( $post_id, '_template', $choice['template'] );
				update_post_meta( $post_id, '_show_thumbnail', 'yes' );

				update_post_meta( $post_id, '_class', '' );
				update_post_meta( $post_id, '_required', 'no' );

				update_post_meta( $post_id, '_items_per_row', '7' );
				update_post_meta( $post_id, '_items_per_row_tablet', '5' );
				update_post_meta( $post_id, '_items_per_row_mobile', '3' );

				if ( isset( $choice['use_thumbnail'] ) ) {
					update_post_meta( $post_id, '_use_thumbnail', $choice['use_thumbnail'] );
				}
				if ( isset( $choice['model_group'] ) ) {
					update_post_meta( $post_id, '_model_group', $choice['model_group'] );
				}
				if ( isset( $choice['model_material'] ) ) {
					update_post_meta( $post_id, '_model_material', $choice['model_material'] );
				}

				$options = array();
				$has_price = false;
				$option_keys = array(
					'label' => 'label',
					'thumbnail' => 'thumbnail',
					'color' => 'color',
					'price' => 'price',
					'sale_price' => 'sale_price',
				);
				foreach ( $choice['options'] as $gen_option ) {
					$option = array(
						'value' => '_',
					);
					foreach ( $gen_option as $key => $value ) {
						if ( ! array_key_exists( $key, $option_keys ) ) {
							continue;
						}

						$option_value = $value;
						if ( 'thumbnail' === $key ) {
							$url = WPCB_BASE_URL . $value;
							$option_value = wpcb_get_attachment_id_by_url($url);
						}

						$option[ $option_keys[ $key ] ] = array( array(
							'value' => $option_value
						) );
						if ( isset( $option['price'] ) ) {
							$has_price = true;
						}
					}
					$options[] = $option;
				}

				if ( $has_price && ! get_post_meta( $post_id, '_price_type', true ) ) {
					update_post_meta( $post_id, '_price_type', 'fixed' );
				}

				update_post_meta( $post_id, '_options', $options );

				$choice_imports[ $choice['title'] ] = $post_id;
			}
		}

		if ( isset( $json_array['configuration'] ) ) {
			$config = $json_array['configuration'];

			// create configuration
			$configuration_id = wp_insert_post( array(
				'post_title'  => $config['title'],
				'post_type'   => 'wpcb_configuration',
				'post_status' => 'publish',
			));

			update_post_meta( $configuration_id, '_template', 'classic' );
			update_post_meta( $configuration_id, '_product_display', 'shortcode' );
			update_post_meta( $configuration_id, '_product_display', $config['title'] );

			if ( 'image' === $import_type ) {
				update_post_meta( $configuration_id, '_gallery_type', 'stacked' );
				update_post_meta( $configuration_id, '_gallery_controls', 'bullets' );

				if ( isset( $config['image_views'] ) ) {
					foreach ( $config['image_views'] as $index => $image_path ) {
						$image_url = WPCB_BASE_URL . $image_path;
						$image_id = wpcb_get_attachment_id_by_url( $image_url );
						update_post_meta( $configuration_id, "_image_views|||$index|value", $image_id );
					}
				}
			} else {
				$model_url = WPCB_BASE_URL . $config['model'];
				$file_id = wpcb_get_attachment_id_by_url( $model_url );

				update_post_meta( $configuration_id, "_wpcb_model_file", $file_id );
			}

			if ( isset( $config['action'] ) ) {
				update_post_meta( $configuration_id, '_button_action', $config['action'] );
			}
			if ( isset( $config['price'] ) ) {
				update_post_meta( $configuration_id, '_price', $config['price'] );
			}

			$blocks = array();
			foreach ( $config['blocks'] as $block_data ){
				$block = [
					'blockName' => $block_data['type'],
					'attrs' => [
						'data' => []
					]
				];

				$field_id = $choice_imports[ $block_data['title'] ];

				if ( 'carbon-fields/wcb-choice' == $block_data['type'] ) {
					$block['attrs']['data']['wpcb_field'] = $field_id;
					$block['attrs']['data']['wpcb_input_toggler'] = '';
					$block['attrs']['data']['wpcb_field_hidden'] = '';
					$block['attrs']['data']['wpcb_field_collapsible'] = '';
					$block['attrs']['data']['wpcb_field_collapsible_state'] = '';
					$block['attrs']['data']['width'] = '';
					$block['attrs']['data']['width_mobile'] = '';
					$block['attrs']['data']['wpcb_field_apply_rules'] = '';
					$block['attrs']['data']['wpcb_field_edit_options'] = '';
				}

				$blocks[] = $block;
			}

			// Convert blocks back to string
			$new_content = wpcb_serialize_blocks($blocks);

			wp_update_post( array(
				'ID' => $configuration_id,
				'post_content' => $new_content
			));
		}

		if ( isset( $json_array['visuals'] ) ) {
			$visual_id = wp_insert_post( array(
				'post_title'  => $config['title'],
				'post_type'   => 'wpcb_visual',
				'post_status' => 'draft',
			));

			update_post_meta( $visual_id, '_configuration|||0|value', $configuration_id );

			$visual_data = [];
			if ( isset( $json_array['visuals']['images'] ) ) {
				foreach ( $json_array['visuals']['images'] as $image_data ) {
					$visual_image = [
						'value' => '_',
						'image' => [],
						'layer' => [],
						'index' => [],
						'rules' => []
					];

					if ( isset( $image_data['image'] ) && is_array( $image_data['image'] ) ) {
						foreach ( $image_data['image'] as $image_path ) {
							$image_url = WPCB_BASE_URL . $image_path;
							$image_id = wpcb_get_attachment_id_by_url( $image_url );

							$visual_image['image'][] = [ 'value' => $image_id ];
						}
					}

					if ( isset( $image_data['display_rules'] ) && is_array( $image_data['display_rules'] ) ) {
						foreach ( $image_data['display_rules'] as $display_rule ) {
							foreach ( $display_rule as $field => $option ) {
								$field_id = $choice_imports[ $field ];
								$option_id = wpcb_get_field_option_by_label( $field_id, $option );

								$visual_image['rules'][] = [
									'value' => '_',
									'choice' => [
										[ 'value' => $field_id ],
									],
									'option' => [
										[ 'value' => $option_id ]
									]
								];
							}
						}
					}

					$visual_data[] = $visual_image;
				}
			}

			if ( isset( $json_array['visuals']['textures'] ) ) {
				foreach ( $json_array['visuals']['textures'] as $image_data ) {
					$visual_image = [
						'value' => '_',
						'type' => [
							[ 'value' => $image_data['type'] ],
						],
						'name' => [
							[ 'value' => $image_data['name'] ],
						],
						'texture_type' => [
							[ 'value' => $image_data['texture_type'] ],
						],
						'texture' => '',
						'rules' => []
					];

					if ( isset( $image_data['texture'] ) && '' !== $image_data['texture'] ) {
						$image_url = WPCB_BASE_URL . $image_data['texture'];
						$image_id = wpcb_get_attachment_id_by_url( $image_url );

						$visual_image['texture'] = [
							[ 'value' => $image_id ],
						];
					}

					if ( isset( $image_data['display_rules'] ) && is_array( $image_data['display_rules'] ) ) {
						foreach ( $image_data['display_rules'] as $display_rule ) {
							foreach ( $display_rule as $field => $option ) {
								$field_id = $choice_imports[ $field ];
								$option_id = wpcb_get_field_option_by_label( $field_id, $option );

								$visual_image['rules'][] = [
									'value' => '_',
									'choice' => [
										[ 'value' => $field_id ],
									],
									'option' => [
										[ 'value' => $option_id ]
									]
								];
							}
						}
					}

					$visual_data[] = $visual_image;
				}
			}

			update_post_meta( $visual_id, '_visuals', $visual_data );

			// Double update to ensure saved.
			$visual_id = wp_update_post( array(
				'ID'          => $visual_id,
				'post_title'  => $config['title'],
				'post_status' => 'publish',
			));
		}

		// SET NOTICE
		set_transient( 'wpcb_admin_notices', array(
			array(
				'text' => __( 'Demo configuration imported successfully!', 'wcb-configurator-builder' ),
				'type' => 'success',
				'dismissible' => '1'
			)
		));

		// WP SAFE REDIRECT
		wp_safe_redirect( admin_url( 'edit.php?post_type=wpcb_configuration&page=welcome' ) );
		die();
	}

	/**
	 * Show plugin notices.
	 *
	 * @since 1.0.0
	 */
	public function show_plugin_admin_notices() {
		if ( $notices = get_transient( 'wpcb_admin_notices' ) ) {
			foreach ( $notices as $notice ) {
				wp_admin_notice( $notice['text'], array( 'type' => $notice['type'], 'dismissible' => $notice['dismissible'] ) );
			}
			delete_transient('wpcb_admin_notices');
		}
	}

	/**
	 * Customize the footer copy for the admin area.
	 *
	 * @since    1.0.0
	 */
	public function edit_admin_footer_text( $content ) {
		if ( $content ) {
			return sprintf(
				// translators: 1: website link, 2: review stars
				__( 'Thank you for creating with %1$s. Please rate %2$s to help spread the word!', 'wcb-configurator-builder'),
				'<a href="https://wpconfiguratorbuilder.com" target="_blank">WCB</a>',
				'<a href="https://wordpress.org/support/plugin/wcb-configurator-builder/reviews/" target="_blank">★★★★★</a>'
			);
		}
	}

	/**
	 * Short description.
	 *
	 * @since    1.0.0
	 */
	public function edit_admin_footer_version( $content ) {
		if ( $content ) {
			return __( 'WCB version ', 'wcb-configurator-builder') . $this->version;
		}
	}

	/**
	 * Show duplication success message
	 *
	 * @since    1.0.0
	 */
	public function show_duplicate_post_notice() {
		if ( isset( $_GET['duplicate_success'] ) && $_GET['duplicate_success'] == '1') {
			echo '<div class="notice notice-success is-dismissible">
				<p>' . esc_attr__( 'Post duplicated successfully!', 'wcb-configurator-builder' ) . '</p>
			</div>';
		}
	}

	/**
	 * Hide WCB admin pages for specific roles
	 *
	 * @since    1.2.0
	 */
	public function hide_menu_for_roles() {
		if ( $this->has_role_access() ) {
			return;
		}

		// Main menu
		$base = 'edit.php?post_type=wpcb_configuration';
		remove_menu_page( $base );
		// Clean up any possible submenus added by the plugin
		remove_submenu_page( $base, $base );
		remove_submenu_page( $base, 'post-new.php?post_type=wpcb_configuration' );
		remove_submenu_page( $base, 'edit.php?post_type=wpcb_choice' );
		remove_submenu_page( $base, 'edit.php?post_type=wpcb_input' );
		remove_submenu_page( $base, 'edit.php?post_type=wpcb_visual' );
		remove_submenu_page( $base, 'edit.php?post_type=wpcb_formula' );
		remove_submenu_page( $base, $base . '&page=wpcb-settings' );
		remove_submenu_page( $base, $base . '&page=welcome' );
		remove_submenu_page( $base, $base . '&page=setup' );
		remove_submenu_page( $base, $base . '&page=tools' );
		remove_submenu_page( $base, $base . '&page=wcb-configurator-builder-pricing' );
	}

	/**
	 * Hide WCB admin bar actions for specific roles
	 *
	 * @since    1.2.0
	 */
	public function remove_admin_bar_for_roles( $wp_admin_bar ) {
		if ( $this->has_role_access() ) {
			return;
		}
		// Remove quick “+ New” nodes for each CPT
		foreach ( $this->post_types as $type ) {
			$wp_admin_bar->remove_node( 'new-' . $type );
		}
		// Just in case the plugin adds its own node
		$wp_admin_bar->remove_node( 'wpcb_configuration' );
	}

	/**
	 * Block direct access to WCB admin pages for specific roles
	 *
	 * @since    1.2.0
	 */
	public function block_all_wcb_screens_for_roles( $screen ) {
		if ( $this->has_role_access() ) {
			return;
		}

		// List of restricted WCB custom post types
		$restricted_cpts = $this->post_types;

		// Block if current screen post type is restricted
		$post_type = isset( $screen->post_type ) ? $screen->post_type : false;
		if ( isset( $_GET['post_type'] ) && '' !== $_GET['post_type'] ) {
			$post_type = sanitize_text_field( wp_unslash( $_GET['post_type'] ) );
		}
		if ( $post_type && in_array( $post_type, $restricted_cpts, true ) ) {
			wp_die( esc_attr__( 'You do not have permission to access this page.', 'wcb-configurator-builder' ), 403 );
		}

		if ( isset( $_GET['post'] ) ) {
			// Block post edit screens like post.php?post=123
			$post_id   = (int) $_GET['post'];
			$post_type = get_post_type( $post_id );
			if ( $post_type && in_array( $post_type, $restricted_cpts, true ) ) {
				wp_die( esc_attr__( 'You do not have permission to access this page.', 'wcb-configurator-builder' ), 403 );
			}
		}
	}

	/**
	 * Check role access for WCB admin pages
	 *
	 * @since    1.2.0
	 */
	private function has_role_access() {
		$roles = wpcb_get_theme_option( 'wpcb_access_roles' ) ?: array();
		$roles[] = 'administrator';

		$has_access = false;
		foreach ( $roles as $role ) {
			if ( current_user_can( $role ) ) {
				$has_access = true;
				break;
			}
		}

		return $has_access;
	}

	/**
	 * Allow 3D model uploads
	 *
	 * @since    1.0.0
	 */
	public function allow_glb_mime_types($mimes) {
		$mimes['gltf'] = 'model/gltf+json';
		$mimes['glb']  = 'model/gltf-binary';
		$mimes['hdr']  = 'image/hdr';
		return $mimes;
	}

	/**
	 * Modify mime type check for user.
	 *
	 * @since    1.0.0
	 */
	public function add_glb_mime_check($data, $file, $filename, $mimes, $real_mime = null) {
		$ext = $type = $proper_filename = false;
		if (isset($data['ext'])) {
			$ext = $data['ext'];
		}
		if (isset($data['type'])) {
			$ext = $data['type'];
		}
		if (isset($data['proper_filename'])) {
			$ext = $data['proper_filename'];
		}

		if ($ext != false && $type != false) {
			return $data;
		}

		$f_sp = explode(".", $filename);
		$f_exp_count = count($f_sp);
		if ($f_exp_count <= 1) {
			return $data;
		}

		$f_name = $f_sp[0];
		$f_ext  = $f_sp[$f_exp_count - 1];

		$allowed_mimes = array(
			'gltf' => 'model/gltf+json',
			'glb'  => 'model/gltf-binary',
			'hdr'  => 'image/hdr',
		);

		$flag = false;
		foreach ($allowed_mimes as $mime_ext => $mime_type) {
			if (trim($mime_ext) === $f_ext) {
				$ext = $f_ext;
				$type = trim($mime_type);
				$flag = true;
				break;
			}
		}

		if (!$flag) {
			return $data;
		}

		return compact('ext', 'type', 'proper_filename');
	}
}
