<?php
/**
 * Module Manager Class
 *
 * Manages plugin modules
 *
 * @package SmartyPress_AI_Engine
 * @since 1.0.0
 */

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

/**
 * Module manager class
 */
class SmartyPress_AI_Module_Manager {

	/**
	 * Settings instance
	 *
	 * @var SmartyPress_AI_Settings
	 */
	private $settings;

	/**
	 * Loaded modules
	 *
	 * @var array
	 */
	private $loaded_modules = array();

	/**
	 * Available modules configuration
	 *
	 * @var array
	 */
	private $available_modules = array();

	/**
	 * Constructor
	 *
	 * @param SmartyPress_AI_Settings $settings Settings instance.
	 * @param array                   $available_modules Available modules configuration.
	 */
	public function __construct( $settings, $available_modules = array() ) {
		$this->settings          = $settings;
		$this->available_modules = $available_modules;
	}

	/**
	 * Get modules to load (filtered by settings)
	 *
	 * Similar to Clearfy's get_load_plugin_components()
	 *
	 * @return array Modules to load.
	 */
	public function get_load_plugin_modules() {
		$load_modules = $this->available_modules;

		// Get disabled modules from settings
		$disabled_modules = $this->settings->get_setting( 'deactive_preinstall_modules', array() );

		if ( ! empty( $disabled_modules ) ) {
			foreach ( (array) $load_modules as $module_id => $module ) {
				if ( in_array( $module_id, $disabled_modules, true ) ) {
					unset( $load_modules[ $module_id ] );
				}
			}
		}

		// Filter modules before loading
		$load_modules = apply_filters( 'smartypress_ai_register_modules', $load_modules );

		return $load_modules;
	}

	/**
	 * Check if module is enabled
	 *
	 * @param string $module_id Module ID.
	 * @return bool True if enabled, false otherwise.
	 */
	public function is_module_enabled( $module_id ) {
		return $this->settings->is_module_enabled( $module_id );
	}

	/**
	 * Load module
	 *
	 * @param string $module_id Module ID.
	 * @param array  $module_config Module configuration.
	 * @return bool True on success, false on failure.
	 */
	public function load_module( $module_id, $module_config ) {
		if ( ! isset( $module_config['autoload'] ) || ! isset( $module_config['module_prefix'] ) ) {
			return false;
		}

		$prefix = rtrim( $module_config['module_prefix'], '_' ) . '_';

		// Check if module is already loaded
		if ( defined( $prefix . 'PLUGIN_ACTIVE' ) ) {
			return true;
		}

		$autoload_file = SMARTYPRESS_AI_PLUGIN_DIR . $module_config['autoload'];

		if ( ! file_exists( $autoload_file ) ) {
			return false;
		}

		// Fire hook before loading module
		do_action( 'smartypress_ai_pre_load_module', $module_id, $module_config );

		// Load module
		require_once $autoload_file;

		// Check if module was initialized
		if ( defined( $prefix . 'PLUGIN_ACTIVE' ) ) {
			$this->loaded_modules[ $module_id ] = array(
				'module_id'     => $module_id,
				'module_prefix' => $prefix,
				'module_dir'    => defined( $prefix . 'PLUGIN_DIR' ) ? constant( $prefix . 'PLUGIN_DIR' ) : '',
				'module_url'    => defined( $prefix . 'PLUGIN_URL' ) ? constant( $prefix . 'PLUGIN_URL' ) : '',
			);

			// Fire hook after module loaded
			do_action( 'smartypress_ai_module_loaded', $module_id, $this->loaded_modules[ $module_id ] );

			return true;
		}

		return false;
	}

	/**
	 * Load all enabled modules
	 *
	 * @return array Loaded modules.
	 */
	public function load_modules() {
		$modules_to_load = $this->get_load_plugin_modules();

		foreach ( $modules_to_load as $module_id => $module_config ) {
			if ( $this->is_module_enabled( $module_id ) ) {
				$this->load_module( $module_id, $module_config );
			}
		}

		return $this->loaded_modules;
	}

	/**
	 * Get active modules
	 *
	 * @return array Active modules.
	 */
	public function get_active_modules() {
		return $this->loaded_modules;
	}

	/**
	 * Get loaded module info
	 *
	 * @param string $module_id Module ID.
	 * @return array|null Module info or null.
	 */
	public function get_module_info( $module_id ) {
		return $this->loaded_modules[ $module_id ] ?? null;
	}

	/**
	 * Get admin routes from config for enabled modules
	 *
	 * Returns routes from module config (admin_routes) for modules that are enabled.
	 * Does not depend on module being loaded.
	 *
	 * @return array List of route configs (path, component, title, menu_title, description, module, icon).
	 */
	public function get_admin_routes_from_config() {
		$routes = array();

		foreach ( $this->available_modules as $module_id => $module_config ) {
			if ( ! $this->is_module_enabled( $module_id ) ) {
				continue;
			}

			$module_routes = $module_config['admin_routes'] ?? array();
			if ( ! is_array( $module_routes ) ) {
				continue;
			}

			foreach ( $module_routes as $route ) {
				$route['module'] = $module_id;
				$routes[]        = $route;
			}
		}

		return $routes;
	}

	/**
	 * Get available modules info for admin page
	 *
	 * @return array Modules info with name, description, icon, status.
	 */
	public function get_available_modules_info() {
		$modules_info = array();

		foreach ( $this->available_modules as $module_id => $module_config ) {
			$is_enabled = $this->is_module_enabled( $module_id );
			$is_loaded  = isset( $this->loaded_modules[ $module_id ] );

			// Base metadata from config (available even when module is not loaded)
			$config_metadata = array(
				'name'        => $module_config['name'] ?? '',
				'description' => $module_config['description'] ?? '',
				'icon'        => $module_config['icon'] ?? '',
				'type'        => $module_config['type'] ?? 'internal',
				'build'       => $module_config['build'] ?? 'free',
			);

			// Filter can override when module is loaded (for backward compatibility)
			$filter_metadata = apply_filters( "smartypress_ai_module_{$module_id}_metadata", array() );
			$metadata        = array_merge( $config_metadata, $filter_metadata );

			$modules_info[] = array(
				'id'           => $module_id,
				'name'         => $metadata['name'] ?? ucfirst( str_replace( '_', ' ', $module_id ) ),
				'description'  => $metadata['description'] ?? '',
				'icon'         => $metadata['icon'] ?? '',
				'enabled'      => $is_enabled,
				'loaded'       => $is_loaded,
				'type'         => $metadata['type'] ?? 'internal',
				'build'        => $metadata['build'] ?? 'free',
				'admin_routes' => $module_config['admin_routes'] ?? array(),
			);
		}

		return $modules_info;
	}
}

