<?php

/**
 * Plugin bootstrap class.
 */

namespace IGD;

defined( 'ABSPATH' ) || exit;

final class Main {

	/**
	 * Singleton instance.
	 *
	 * @var self|null
	 */
	private static $instance = null;

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

		return self::$instance;
	}

	/**
	 * Prevent direct construction.
	 */
	private function __construct() {

		if ( ! $this->check_environment() ) {
			wp_die(
				esc_html__( 'Plugin requirements not met.', 'integrate-google-drive' ),
				esc_html__( 'Plugin Error', 'integrate-google-drive' )
			);
		}

		$this->load_instances();
		$this->register_hooks();

		do_action( 'igd_loaded' );
	}

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

	/**
	 * Prevent unserialization.
	 */
	public function __wakeup() {
		_doing_it_wrong( __FUNCTION__, esc_html__( 'Unserializing is not allowed.', 'integrate-google-drive' ), '1.0.0' );
	}

	/**
	 * Load required files.
	 */
	private function load_instances(): void {
		Enqueue::instance();
		Ajax::instance();
		Shortcode::instance();
		Hooks::instance();
		Integrations::instance();

		if ( is_admin() ) {
			Admin::instance();
		}

		if ( igd_fs()->can_use_premium_code__premium_only() ) {
			Notifications::instance();
			Proofing::instance();
			Restrictions::instance();
			PrivateFolders::instance();
			Importer::instance();

			if ( Helpers::get_settings( 'enableStatistics' ) ) {
				Statistics::instance();
			}
		}

	}

	/**
	 * Register WordPress hooks.
	 */
	private function register_hooks(): void {

		register_activation_hook( IGD_FILE, [ $this, 'activate' ] );
		register_deactivation_hook( IGD_FILE, [ $this, 'deactivate' ] );
		register_uninstall_hook( IGD_FILE, [ __CLASS__, 'uninstall' ] );

		add_action( 'admin_notices', [ $this, 'render_notices' ], 15 );
		add_action( 'plugins_loaded', [ $this, 'load_textdomain' ] );

		$plugin = plugin_basename( IGD_FILE );

		add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 2 );
		add_filter( "plugin_action_links_{$plugin}", [ $this, 'plugin_action_links' ] );

		// Handle uninstall
		igd_fs()->add_action( 'after_uninstall', [ $this, 'uninstall' ] );
	}

	/**
	 * Validate environment.
	 */
	public function check_environment(): bool {

		$errors = [];

		if ( version_compare( PHP_VERSION, '7.4', '<' ) ) {
			$errors[] = sprintf(
				esc_html__( 'Requires PHP %1$s or later. Current version: %2$s', 'integrate-google-drive' ),
				'7.4',
				PHP_VERSION
			);
		}

		if ( version_compare( get_bloginfo( 'version' ), '5.0', '<' ) ) {
			$errors[] = esc_html__( 'Requires WordPress 5.0 or later.', 'integrate-google-drive' );
		}

		if ( ! function_exists( 'curl_init' ) ) {
			$errors[] = esc_html__( 'PHP cURL extension is required.', 'integrate-google-drive' );
		}

		if ( ! extension_loaded( 'json' ) ) {
			$errors[] = esc_html__( 'PHP JSON extension is required.', 'integrate-google-drive' );
		}

		if ( empty( $errors ) ) {
			return true;
		}

		deactivate_plugins( plugin_basename( IGD_FILE ) );

		foreach ( $errors as $error ) {
			$this->add_notice( 'error', '<p>' . esc_html( $error ) . '</p>' );
		}

		return false;
	}

	/**
	 * Load plugin textdomain.
	 */
	public function load_textdomain(): void {
		load_plugin_textdomain(
			'integrate-google-drive',
			false,
			dirname( plugin_basename( IGD_FILE ) ) . '/languages'
		);
	}

	/**
	 * Activation handler.
	 */
	public function activate(): void {
		$this->run_installer( 'activate' );
	}

	/**
	 * Deactivation handler.
	 */
	public function deactivate(): void {
		$this->run_installer( 'deactivate' );
	}

	/**
	 * Installer
	 *
	 * @param string $method Method name.
	 */
	private function run_installer( string $method ): void {
		if ( is_callable( [ Install::class, $method ] ) ) {
			Install::$method();
		}
	}

	/**
	 * Uninstall callback.
	 */
	public static function uninstall(): void {

		Install::deactivate();

		if ( Helpers::get_settings( 'deleteData' ) ) {
			delete_option( 'igd_tokens' );
			delete_option( 'igd_accounts' );
			delete_option( 'igd_settings' );
			delete_option( 'igd_cached_folders' );

			Helpers::delete_cache();
		}
	}

	/**
	 * Plugin row meta links.
	 */
	public function plugin_row_meta( array $meta, string $file ): array {

		if ( plugin_basename( IGD_FILE ) !== $file ) {
			return $meta;
		}

		$meta[] = sprintf(
			'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
			esc_url( 'https://softlabbd.com/docs-category/integrate-google-drive-docs/' ),
			esc_html__( 'Docs', 'integrate-google-drive' )
		);

		$meta[] = sprintf(
			'<a href="%s" target="_blank" rel="noopener noreferrer">%s</a>',
			esc_url( 'https://softlabbd.com/support/' ),
			esc_html__( 'Support', 'integrate-google-drive' )
		);

		return $meta;
	}

	/**
	 * Plugin action links.
	 */
	public function plugin_action_links( array $links ): array {

		$links[] = sprintf(
			'<a href="%s">%s</a>',
			esc_url( admin_url( 'admin.php?page=integrate-google-drive-settings' ) ),
			esc_html__( 'Settings', 'integrate-google-drive' )
		);

		if ( ! igd_fs()->can_use_premium_code__premium_only() ) {
			$links[] = sprintf(
				'<a href="%s" target="_blank" rel="noopener noreferrer" class="igd-pro-link">%s</a>',
				esc_url( 'https://softlabbd.com/integrate-google-drive-pricing' ),
				esc_html__( 'Get Pro', 'integrate-google-drive' )
			);
		}

		return $links;
	}

	/**
	 * Store admin notice.
	 */
	public function add_notice( string $type, string $message ): void {

		$notices   = get_option( 'igd_notices', [] );
		$notices[] = [
			'type'    => sanitize_key( $type ),
			'message' => wp_kses_post( $message ),
		];

		update_option( 'igd_notices', $notices );
	}

	/**
	 * Render admin notices.
	 */
	public function render_notices(): void {

		$notices = get_option( 'igd_notices', [] );

		foreach ( $notices as $notice ) {
			printf(
				'<div class="notice notice-%1$s is-dismissible"><p>%2$s</p></div>',
				esc_attr( $notice['type'] ?? 'info' ),
				wp_kses_post( $notice['message'] ?? '' )
			);
		}

		delete_option( 'igd_notices' );
	}
}
