<?php
/**
 * Core bootstrap class.
 *
 * @package Briefify
 */

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

/**
 * Class Briefify_Core
 *
 * Singleton responsible for loading dependencies and wiring the plugin together.
 */
class Briefify_Core {

	/**
	 * Single instance.
	 *
	 * @var Briefify_Core|null
	 */
	private static $instance = null;

	/**
	 * @var Briefify_CPT
	 */
	public $cpt;

	/**
	 * @var Briefify_Form
	 */
	public $form;

	/**
	 * @var Briefify_Shortcode
	 */
	public $shortcode;

	/**
	 * @var Briefify_Email
	 */
	public $email;

	/**
	 * @var Briefify_Admin
	 */
	public $admin;

	/**
	 * @var Briefify_Pro_Status|null Null unless nrbb_is_pro().
	 */
	public $pro_status;

	/**
	 * @var Briefify_Pro_Branding|null Null unless nrbb_is_pro().
	 */
	public $pro_branding;

	/**
	 * @var Briefify_Pro_Pdf|null Null unless nrbb_is_pro().
	 */
	public $pro_pdf;

	/**
	 * Get the singleton instance.
	 *
	 * @return Briefify_Core
	 */
	public static function instance() {
		if ( null === self::$instance ) {
			self::$instance = new self();
		}

		return self::$instance;
	}

	/**
	 * Constructor.
	 */
	private function __construct() {
		$this->includes();
		$this->init_hooks();
	}

	/**
	 * Require dependency files.
	 */
	private function includes() {
		require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-cpt.php';
		require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-form.php';
		require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-shortcode.php';
		require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-email.php';

		if ( is_admin() ) {
			require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-admin.php';
		}

		// Pro files live entirely in includes/pro/ and are never required
		// (let alone loaded) for a non-Pro install — nrbb_is_pro() is the
		// only gate. The free package this plugin ships to WordPress.org
		// excludes the pro/ folder entirely; this check is what keeps that
		// safe even if it were ever present by mistake.
		if ( nrbb_is_pro() ) {
			$this->require_pro_files();
		}
	}

	/**
	 * Require each Pro class file, individually guarded with file_exists().
	 *
	 * nrbb_is_pro() is a license check, not a proof that includes/pro/
	 * actually exists on disk — a site can have an active Pro license
	 * (Freemius already knows about it) while still running the free
	 * WP.org package, e.g. right after buying and before the Premium zip
	 * is actually installed. Requiring a missing file is a fatal error
	 * for the whole site, not just Pro features, so every file is
	 * checked before its require_once. Each file is independent (no
	 * cross-dependencies between the three Pro classes), so a missing
	 * one only costs that one feature — init_hooks() below only
	 * instantiates whichever classes actually got defined.
	 */
	private function require_pro_files() {
		$pro_files = array(
			'includes/pro/class-briefify-pro-status.php',
			'includes/pro/class-briefify-pro-branding.php',
			'includes/pro/class-briefify-pro-pdf.php',
		);

		foreach ( $pro_files as $pro_file ) {
			$path = BRIEFIFY_PLUGIN_DIR . $pro_file;

			if ( file_exists( $path ) ) {
				require_once $path;
			}
		}
	}

	/**
	 * Load translations and instantiate sub-classes.
	 */
	private function init_hooks() {
		// No manual load_plugin_textdomain() call: since WP 4.6, core loads
		// translations "just in time" from the Text Domain / Domain Path
		// declared in briefify.php's header alone — a bundled languages/
		// briefify-fr_FR.mo is picked up automatically. Verified live after
		// removing this (see ROADMAP.md).

		$this->cpt       = new Briefify_CPT();
		$this->email     = new Briefify_Email();
		$this->form      = new Briefify_Form( $this->email );
		$this->shortcode = new Briefify_Shortcode( $this->form );

		if ( is_admin() ) {
			$this->admin = new Briefify_Admin( $this->email );
		}

		// class_exists() rather than a bare nrbb_is_pro(): the class is
		// only actually defined if require_pro_files() above found its
		// file on disk. Instantiating a class that failed to load would
		// be the same fatal error require_pro_files() was written to
		// avoid, just one line later.
		if ( nrbb_is_pro() ) {
			if ( class_exists( 'Briefify_Pro_Status' ) ) {
				$this->pro_status = new Briefify_Pro_Status();
			}

			if ( class_exists( 'Briefify_Pro_Branding' ) ) {
				$this->pro_branding = new Briefify_Pro_Branding();
			}

			if ( class_exists( 'Briefify_Pro_Pdf' ) ) {
				$this->pro_pdf = new Briefify_Pro_Pdf();
			}
		}
	}

	/**
	 * Runs on plugin activation.
	 */
	public static function activate() {
		require_once BRIEFIFY_PLUGIN_DIR . 'includes/class-briefify-cpt.php';
		$cpt = new Briefify_CPT();
		$cpt->register_post_type();

		if ( false === get_option( 'briefify_settings' ) ) {
			// Every key Briefify_Admin::sanitize_settings() can produce,
			// initialized here too — not because a missing key currently
			// crashes anything (every read of $settings[...] elsewhere is
			// isset()/empty()-guarded), but so activation and a manual
			// settings save always leave the option in the same shape.
			update_option(
				'briefify_settings',
				array(
					'notification_email'   => get_option( 'admin_email' ),
					'default_template'     => 'web',
					'send_confirmation'    => true,
					'confirmation_subject' => '',
				)
			);
		}

		flush_rewrite_rules();
	}

	/**
	 * Runs on plugin deactivation.
	 */
	public static function deactivate() {
		flush_rewrite_rules();
	}
}
