<?php
/**
 * Plugin core orchestrator.
 *
 * @package MerchantKits\AttendanceManager
 */

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

/**
 * Singleton that wires together the plugin's components and hooks.
 */
class MKAM_Core {

	/**
	 * Single shared instance.
	 *
	 * @var MKAM_Core|null
	 */
	protected static $instance = null;

	/**
	 * Admin handler.
	 *
	 * @var MKAM_Admin|null
	 */
	public $admin = null;

	/**
	 * Cron handler.
	 *
	 * @var MKAM_Cron|null
	 */
	public $cron = null;

	/**
	 * Retrieve the shared instance.
	 *
	 * @return MKAM_Core
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Constructor: load components and register hooks.
	 */
	private function __construct() {
		$this->init_components();
		$this->register_hooks();
	}

	/**
	 * Prevent cloning.
	 *
	 * @return void
	 */
	private function __clone() {}

	/**
	 * Prevent unserialization.
	 *
	 * @return void
	 */
	public function __wakeup() {}

	/**
	 * Instantiate the plugin's runtime components.
	 *
	 * @return void
	 */
	private function init_components() {
		if ( class_exists( 'MKAM_Cron' ) ) {
			$this->cron = new MKAM_Cron();
		}

		if ( class_exists( 'MKAM_Email' ) ) {
			new MKAM_Email();
		}

		if ( is_admin() && class_exists( 'MKAM_Admin' ) ) {
			$this->admin = new MKAM_Admin();
		}

		if ( class_exists( 'MKAM_Frontend' ) ) {
			new MKAM_Frontend();
		}

		if ( class_exists( 'MKAM_REST_API' ) ) {
			add_action( 'rest_api_init', array( new MKAM_REST_API(), 'register_routes' ) );
		}

		if ( is_admin() && class_exists( 'MKAM_AI_Insights' ) ) {
			add_action( 'wp_ajax_mkam_test_connection', array( new MKAM_AI_Insights(), 'ajax_test_connection' ) );
		}

		if ( is_admin() && class_exists( 'MKAM_Export' ) ) {
			$export = new MKAM_Export();
			add_action( 'wp_ajax_mkam_export', array( $export, 'ajax_export' ) );
		}

		$this->init_premium();
	}

	/**
	 * Load and boot Pro-only features when a valid license is active.
	 *
	 * The Pro classes live in *__premium_only.php files that Freemius strips
	 * from the free build, so they are required explicitly (not autoloaded).
	 *
	 * @return void
	 */
	private function init_premium() {
		if ( ! function_exists( 'mkam_fs' ) || ! mkam_fs()->can_use_premium_code() ) {
			return;
		}

		$premium = array(
			'class-pro-ai-query__premium_only.php'        => 'MKAM_Pro_AI_Query',
			'class-pro-leave-policies__premium_only.php'  => 'MKAM_Pro_Leave_Policies',
			'class-pro-geofence__premium_only.php'        => 'MKAM_Pro_Geofence',
		);

		foreach ( $premium as $file => $class ) {
			$path = MKAM_INCLUDES_DIR . $file;
			if ( file_exists( $path ) ) {
				require_once $path;
				if ( class_exists( $class ) ) {
					new $class();
				}
			}
		}
	}

	/**
	 * Register global hooks.
	 *
	 * @return void
	 */
	private function register_hooks() {
		add_action( 'init', array( $this, 'maybe_upgrade' ) );
		add_filter( 'cron_schedules', array( $this, 'add_cron_schedules' ) );
	}

	/**
	 * Run database/migration upgrades when the stored version is behind.
	 *
	 * @return void
	 */
	public function maybe_upgrade() {
		$installed = get_option( 'mkam_db_version', '0' );

		if ( version_compare( $installed, MKAM_DB_VERSION, '<' ) ) {
			require_once MKAM_INCLUDES_DIR . 'class-activator.php';
			MKAM_Activator::create_tables();
			update_option( 'mkam_db_version', MKAM_DB_VERSION );
		}
	}

	/**
	 * Register the weekly cron schedule if it is not already present.
	 *
	 * @param array $schedules Existing schedules.
	 * @return array
	 */
	public function add_cron_schedules( $schedules ) {
		if ( ! isset( $schedules['weekly'] ) ) {
			$schedules['weekly'] = array(
				'interval' => WEEK_IN_SECONDS,
				'display'  => __( 'Once Weekly', 'merchantkits-attendance-manager' ),
			);
		}

		return $schedules;
	}

	/**
	 * Resolve the capability required for admin features.
	 *
	 * @return string
	 */
	public static function admin_capability() {
		return apply_filters( 'mkam_admin_capabilities', 'manage_options' );
	}
}
