<?php
/**
 * The core plugin class.
 *
 * This is used to define internationalization, admin-specific hooks, and
 * public-facing site hooks.
 *
 * Also maintains the unique identifier of this plugin as well as the current
 * version of the plugin.
 *
 * @since      1.0.0
 * @package    Ai_Try_N_Buy
 * @subpackage Ai_Try_N_Buy/includes
 * @author     Edu Brazeal <contact@edubrazeal.com>
 */
class Aitnb_Loader {

	/**
	 * The loader that's responsible for maintaining and registering all hooks that power
	 * the plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      Aitnb_Hook_Orchestrator    $loader    Maintains and registers all hooks for the plugin.
	 */
	protected $loader;

	/**
	 * The unique identifier of this plugin.
	 *
	 * @since    1.0.0
	 * @access   protected
	 * @var      string    $plugin_name    The string used to uniquely identify this plugin.
	 */
	protected $plugin_name;

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


	/**
	 * Define the core functionality of the plugin.
	 *
	 * Set the plugin name and the plugin version that can be used throughout the plugin.
	 * Load the dependencies, define the locale, and set the hooks for the admin area and
	 * the public-facing side of the site.
	 *
	 * @since    1.0.0
	 */
	public function __construct() {
		if ( defined( 'AITNB_VERSION' ) ) {
			$this->version = AITNB_VERSION;
		} else {
			$this->version = '1.0.0';
		}

		$this->plugin_name = 'virtual-ai-fit-and-style-assistant';

		$this->load_dependencies();
		$this->set_locale();

		if ( is_admin() ) {
			$this->check_activation_status();
			$this->define_admin_hooks();
		}

		$this->define_public_hooks();
	}

	/**
	 * Load the required dependencies for this plugin.
	 *
	 * Include the following files that make up the plugin:
	 *
	 * - Aitnb_Hook_Orchestrator. Orchestrates the hooks of the plugin.
	 * - Aitnb_i18n. Defines internationalization functionality.
	 * - Aitnb_Admin. Defines all hooks for the admin area.
	 * - Aitnb_Public. Defines all hooks for the public side of the site.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function load_dependencies() {
		$plugin_dir = plugin_dir_path( dirname( __FILE__ ) );

		$core_files = array(
			'includes/class-hook-orchestrator.php',
			'includes/class-i18n.php',
			'includes/class-activator.php',
		);

		foreach ( $core_files as $file ) {
			$file_path = $plugin_dir . $file;
			if ( file_exists( $file_path ) ) {
				require_once $file_path;
			} else {
				wp_die(
					sprintf(
						/* translators: %s: file path */
						esc_html__( 'Required file missing: %s. Please reinstall the AI Try n Buy plugin.', 'virtual-ai-fit-and-style-assistant' ),
						esc_html( $file )
					)
				);
			}
		}

		$public_files = array(
			'public/class-public-main.php',
			'analytics/class-event-tracker.php',
		);

		foreach ( $public_files as $file ) {
			$file_path = $plugin_dir . $file;
			if ( file_exists( $file_path ) ) {
				require_once $file_path;
			} else {
				wp_die(
					sprintf(
						/* translators: %s: file path */
						esc_html__( 'Required file missing: %s. Please reinstall the AI Try n Buy plugin.', 'virtual-ai-fit-and-style-assistant' ),
						esc_html( $file )
					)
				);
			}
		}

		if ( is_admin() ) {
			$admin_files = array(
				'includes/class-style-assistant-cron.php',
				'admin/class-admin-main.php',
				'admin/class-product-metabox.php',
				'analytics/class-analytics-main.php',
			);

			foreach ( $admin_files as $file ) {
				$file_path = $plugin_dir . $file;
				if ( file_exists( $file_path ) ) {
					require_once $file_path;
				} else {
					wp_die(
						sprintf(
							/* translators: %s: file path */
							esc_html__( 'Required file missing: %s. Please reinstall the AI Try n Buy plugin.', 'virtual-ai-fit-and-style-assistant' ),
							esc_html( $file )
						)
					);
				}
			}
		}

		if ( class_exists( 'Aitnb_Hook_Orchestrator' ) ) {
			$this->loader = new Aitnb_Hook_Orchestrator();
		} else {
			wp_die( esc_html__( 'Critical class missing: Aitnb_Hook_Orchestrator. Please reinstall the AI Try n Buy plugin.', 'virtual-ai-fit-and-style-assistant' ) );
		}
	}

	/**
	 * Define the locale for this plugin for internationalization.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function set_locale() {
		if ( class_exists( 'Aitnb_i18n' ) ) {
			$plugin_i18n = new Aitnb_i18n();
			$this->loader->add_action( 'plugins_loaded', $plugin_i18n, 'load_plugin_textdomain' );
		}
	}

	/**
	 * Check if the plugin was activated successfully and show notices if needed.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function check_activation_status() {
		if ( class_exists( 'Aitnb_Activator' ) ) {
			$this->loader->add_action( 'admin_notices', 'Aitnb_Activator', 'show_activation_notice' );
		}
	}

	/**
	 * Register all of the hooks related to the admin area functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_admin_hooks() {
		if ( ! class_exists( 'Aitnb_Admin' ) || ! class_exists( 'Aitnb_Product_Metabox' ) || 
		     ! class_exists( 'Aitnb_Analytics_Main' ) || ! class_exists( 'Aitnb_Event_Tracker' ) ) {
			return;
		}

		$admin_main      = new Aitnb_Admin( $this->get_plugin_name(), $this->get_version() );
		$product_metabox = new Aitnb_Product_Metabox( $this->get_plugin_name(), $this->get_version() );
		$analytics_main  = new Aitnb_Analytics_Main( $this->get_plugin_name(), $this->get_version() );
		$event_tracker   = new Aitnb_Event_Tracker();
		
		if ( class_exists( 'Aitnb_Style_Assistant_Cron' ) ) {
			new Aitnb_Style_Assistant_Cron();
		}

		$this->loader->add_action( 'admin_enqueue_scripts', $admin_main, 'enqueue_styles' );
		$this->loader->add_action( 'admin_enqueue_scripts', $admin_main, 'enqueue_scripts' );
		$this->loader->add_action( 'admin_menu', $admin_main, 'add_plugin_admin_menu' );
		$this->loader->add_action( 'admin_init', $admin_main, 'register_settings' );
		$admin_main->register_ajax_handlers();

		$this->loader->add_action( 'add_meta_boxes', $product_metabox, 'add_metabox' );
		$this->loader->add_action( 'woocommerce_process_product_meta', $product_metabox, 'save_metabox_data' );

		$this->loader->add_action( 'admin_menu', $analytics_main, 'add_dashboard_page' );
		$this->loader->add_action( 'admin_enqueue_scripts', $analytics_main, 'enqueue_assets' );
		$analytics_main->register_ajax_handlers();
		$event_tracker->register_hooks();
		
		$this->loader->add_filter( 'upload_mimes', $this, 'allow_3d_model_uploads', 10, 1 );
		$this->loader->add_filter( 'wp_check_filetype_and_ext', $this, 'check_3d_model_filetype', 10, 4 );

		$this->loader->add_action( 'wp_dashboard_setup', $this, 'add_dashboard_widget' );
	}

	/**
	 * Register all of the hooks related to the public-facing functionality
	 * of the plugin.
	 *
	 * @since    1.0.0
	 * @access   private
	 */
	private function define_public_hooks() {
		if ( ! class_exists( 'Aitnb_Public' ) ) {
			return;
		}

		$plugin_public = new Aitnb_Public( $this->get_plugin_name(), $this->get_version() );
		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_styles' );
		$this->loader->add_action( 'wp_enqueue_scripts', $plugin_public, 'enqueue_scripts' );
		$this->loader->add_action( 'woocommerce_after_add_to_cart_button', $plugin_public, 'add_action_buttons', 10 );

		$options      = get_option( 'aitnb_settings', array() );
		$display_hook = isset( $options['product_page_hook'] ) ? sanitize_text_field( $options['product_page_hook'] ) : 'woocommerce_after_single_product_summary';
		
		$allowed_hooks = array(
			'woocommerce_after_single_product_summary',
			'woocommerce_product_meta_end',
			'woocommerce_after_single_product',
		);
		
		if ( ! in_array( $display_hook, $allowed_hooks, true ) ) {
			$display_hook = 'woocommerce_after_single_product_summary';
		}
		
		$priority = 'woocommerce_after_single_product_summary' === $display_hook ? 20 : 10;

		$this->loader->add_action( $display_hook, $plugin_public, 'add_style_assistant_section', $priority );
	}


	/**
	 * Run the loader to execute all of the hooks with WordPress.
	 *
	 * @since    1.0.0
	 */
	public function run() {
		if ( isset( $this->loader ) && is_object( $this->loader ) ) {
			$this->loader->run();
		}
	}

	/**
	 * The name of the plugin used to uniquely identify it.
	 *
	 * @since     1.0.0
	 * @return    string    The name of the plugin.
	 */
	public function get_plugin_name() {
		return $this->plugin_name;
	}

	/**
	 * Retrieve the version number of the plugin.
	 *
	 * @since     1.0.0
	 * @return    string    The version number of the plugin.
	 */
	public function get_version() {
		return $this->version;
	}
	
	/**
	 * Allows uploading of 3D model files by adding the MIME types to WordPress.
	 *
	 * @since    1.0.0
	 * @param    array    $mime_types    The array of allowed MIME types.
	 * @return   array                   The modified array of MIME types.
	 */
	public function allow_3d_model_uploads( $mime_types ) {
		if ( ! is_array( $mime_types ) ) {
			$mime_types = array();
		}
		
		$mime_types['glb'] = 'model/gltf-binary';
		
		return $mime_types;
	}

	/**
	 * Forces the correct MIME type detection for 3D model files.
	 *
	 * @since    1.0.0
	 * @param    array     $data          File data.
	 * @param    string    $file          Full path to the file.
	 * @param    string    $filename      The filename.
	 * @param    array     $mimes         Array of MIME types.
	 * @return   array                    Modified file data.
	 */
	public function check_3d_model_filetype( $data, $file, $filename, $mimes ) {
		if ( ! is_array( $data ) ) {
			$data = array(
				'ext'             => false,
				'type'            => false,
				'proper_filename' => false,
			);
		}

		$file_ext = strtolower( pathinfo( $filename, PATHINFO_EXTENSION ) );
		
		if ( 'glb' === $file_ext ) {
			$data['ext']  = 'glb';
			$data['type'] = 'model/ggltf-binary';
		}
		
		return $data;
	}

	/**
	 * Adds a dashboard widget to show plugin status and quick stats.
	 *
	 * @since    1.0.0
	 */
	public function add_dashboard_widget() {
		if ( ! current_user_can( 'manage_options' ) ) {
			return;
		}

		wp_add_dashboard_widget(
			'aitnb_status_widget',
			__( 'AI Try n Buy Status', 'virtual-ai-fit-and-style-assistant' ),
			array( $this, 'render_dashboard_widget' )
		);
	}

	/**
	 * Renders the dashboard widget content.
	 *
	 * @since    1.0.0
	 */
	public function render_dashboard_widget() {
		$activation_status = false;
		$record_count      = 0;

		if ( class_exists( 'Aitnb_Activator' ) ) {
			$activation_status = Aitnb_Activator::get_activation_status();
		}

		if ( $activation_status && 'success' === $activation_status['status'] ) {
			$db_manager_path = plugin_dir_path( dirname( __FILE__ ) ) . 'analytics/class-database-manager.php';
			
			if ( file_exists( $db_manager_path ) ) {
				require_once $db_manager_path;
				
				if ( class_exists( 'Aitnb_Database_Manager' ) ) {
					$db_manager = new Aitnb_Database_Manager();

					if ( $db_manager->verify_table_exists() ) {
						$record_count = $db_manager->get_total_record_count();
						if ( false === $record_count ) {
							$record_count = 0;
						}
					}
				}
			}
		}

		$view_path = plugin_dir_path( dirname( __FILE__ ) ) . 'admin/views/dashboard-widget-view.php';
		if ( file_exists( $view_path ) ) {
			require $view_path;
		}
	}
}