<?php
/**
 * Main plugin bootstrap.
 *
 * @package TonItaliaRegistration
 */

defined( 'ABSPATH' ) || exit;

/**
 * Class TON_Reg_Plugin
 */
class TON_Reg_Plugin {

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

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

	/**
	 * Constructor.
	 */
	private function __construct() {
		load_plugin_textdomain( 'ton-italia-registration', false, dirname( plugin_basename( TON_REG_PLUGIN_FILE ) ) . '/languages' );

		add_action( 'init', array( $this, 'init' ) );
		add_action( 'admin_init', array( $this, 'block_subscriber_admin' ) );
		add_action( 'admin_menu', array( $this, 'trim_subscriber_admin_menu' ), 999 );
		add_action( 'load-index.php', array( $this, 'redirect_subscriber_dashboard' ) );
		add_filter( 'show_admin_bar', array( $this, 'hide_admin_bar_for_subscribers' ) );

		TON_Reg_Registration_Form::register();
		TON_Reg_Registration_Handler::register();
		TON_Reg_Profile::register();
		add_action( TON_Reg_Mailchimp::CRON_HOOK, array( 'TON_Reg_Mailchimp', 'sync_registration' ) );
		add_action( TON_Reg_Renewal_Reminders::CRON_HOOK, array( 'TON_Reg_Renewal_Reminders', 'run_daily' ) );
		add_action( 'update_option_ton_reg_mailchimp_api_key', array( 'TON_Reg_Mailchimp', 'ensure_api_key_no_autoload' ) );

		if ( is_admin() ) {
			TON_Reg_Admin::register();
		}
	}

	/**
	 * Init hooks.
	 */
	public function init() {
		$this->maybe_upgrade();
	}

	/**
	 * Run DB / folder upgrades when plugin files are updated.
	 */
	private function maybe_upgrade() {
		$db_version = (string) get_option( 'ton_reg_db_version', '0' );

		if ( version_compare( $db_version, '1.1', '<' ) ) {
			TON_Reg_Database::create_table();
			TON_Reg_Documents::install_folders();
			$db_version = '1.1';
		}

		if ( version_compare( $db_version, '1.2', '<' ) ) {
			TON_Reg_Database::create_table();
			$db_version = '1.2';
		}

		if ( version_compare( $db_version, '1.3', '<' ) ) {
			TON_Reg_Database::create_table();

			$mailchimp_options = array(
				'ton_reg_mailchimp_enabled',
				'ton_reg_mailchimp_api_key',
				'ton_reg_mailchimp_list_id',
				'ton_reg_mailchimp_tags',
				'ton_reg_mailchimp_permission_ids',
			);
			$defaults = TON_Reg_Defaults::options();
			foreach ( $mailchimp_options as $key ) {
				if ( false === get_option( $key ) && isset( $defaults[ $key ] ) ) {
					add_option( $key, $defaults[ $key ], '', 'ton_reg_mailchimp_api_key' === $key ? 'no' : 'yes' );
				}
			}

			if ( get_option( 'ton_reg_mailchimp_api_key' ) ) {
				TON_Reg_Mailchimp::ensure_api_key_no_autoload();
			}

			$db_version = '1.3';
		}

		if ( version_compare( $db_version, '1.4', '<' ) ) {
			self::purge_legacy_bonifico_documents();
			$db_version = '1.4';
		}

		if ( version_compare( $db_version, '1.5', '<' ) ) {
			TON_Reg_Membership_Cards::create_table();
			if ( false === get_option( TON_Reg_Membership_Card::OPTION_ACTIVE_YEAR ) ) {
				add_option( TON_Reg_Membership_Card::OPTION_ACTIVE_YEAR, (int) gmdate( 'Y' ) );
			}
			if ( false === get_option( TON_Reg_Membership_Card::OPTION_TEMPLATES ) ) {
				add_option( TON_Reg_Membership_Card::OPTION_TEMPLATES, array() );
			}
			$db_version = '1.5';
		}

		if ( version_compare( $db_version, '1.6', '<' ) ) {
			TON_Reg_Membership_Renewals::create_table();
			TON_Reg_Renewal_Reminders::schedule_cron();

			$renewal_options = array(
				'ton_reg_email_renewal_first_subject',
				'ton_reg_email_renewal_first_body',
				'ton_reg_email_renewal_second_subject',
				'ton_reg_email_renewal_second_body',
				'ton_reg_email_renewal_admin_subject',
				'ton_reg_email_renewal_admin_body',
				'ton_reg_renewal_reminders_start_year',
			);
			$defaults = TON_Reg_Defaults::options();
			foreach ( $renewal_options as $key ) {
				if ( false === get_option( $key ) && isset( $defaults[ $key ] ) ) {
					add_option( $key, $defaults[ $key ] );
				}
			}

			$db_version = '1.6';
		}

		update_option( 'ton_reg_db_version', $db_version );
	}

	/**
	 * One-time cleanup after removing «Ricevuta bonifico» upload type.
	 */
	private static function purge_legacy_bonifico_documents() {
		global $wpdb;

		$table = TON_Reg_Database::table_name();
		$ids   = $wpdb->get_col( "SELECT id FROM {$table} WHERE doc_bonifico_id IS NOT NULL AND doc_bonifico_id > 0" );

		if ( ! is_array( $ids ) ) {
			return;
		}

		foreach ( $ids as $registration_id ) {
			TON_Reg_Documents::delete_legacy_bonifico_document( (int) $registration_id );
		}
	}

	/**
	 * @return bool
	 */
	public static function is_restricted_subscriber() {
		if ( ! is_user_logged_in() ) {
			return false;
		}

		$user = wp_get_current_user();
		return in_array( 'subscriber', (array) $user->roles, true ) && ! current_user_can( 'manage_options' );
	}

	/**
	 * Whether a subscriber may access the current wp-admin request.
	 *
	 * @return bool
	 */
	public static function subscriber_can_access_admin() {
		global $pagenow;

		if ( 'profile.php' === $pagenow ) {
			return true;
		}

		if ( 'admin-post.php' === $pagenow && 'ton_reg_download_card' === ( $_REQUEST['action'] ?? '' ) ) {
			return true;
		}

		return false;
	}

	/**
	 * Prevent subscribers from accessing wp-admin except profile and card download.
	 */
	public function block_subscriber_admin() {
		if ( ! is_user_logged_in() || wp_doing_ajax() || current_user_can( 'manage_options' ) ) {
			return;
		}

		if ( ! self::is_restricted_subscriber() ) {
			return;
		}

		if ( self::subscriber_can_access_admin() ) {
			return;
		}

		global $pagenow;
		if ( 'index.php' === $pagenow ) {
			wp_safe_redirect( admin_url( 'profile.php' ) );
			exit;
		}

		wp_safe_redirect( home_url() );
		exit;
	}

	/**
	 * Keep only the Profile menu item for subscribers in wp-admin.
	 */
	public function trim_subscriber_admin_menu() {
		if ( ! self::is_restricted_subscriber() ) {
			return;
		}

		global $menu;

		if ( ! is_array( $menu ) ) {
			return;
		}

		foreach ( $menu as $item ) {
			if ( ! is_array( $item ) || empty( $item[2] ) ) {
				continue;
			}
			if ( 'profile.php' !== $item[2] ) {
				remove_menu_page( $item[2] );
			}
		}
	}

	/**
	 * Send subscribers to their profile instead of the dashboard.
	 */
	public function redirect_subscriber_dashboard() {
		if ( ! self::is_restricted_subscriber() ) {
			return;
		}

		wp_safe_redirect( admin_url( 'profile.php' ) );
		exit;
	}

	/**
	 * @param bool $show Whether to show admin bar.
	 * @return bool
	 */
	public function hide_admin_bar_for_subscribers( $show ) {
		if ( ! is_user_logged_in() ) {
			return $show;
		}
		$user = wp_get_current_user();
		if ( in_array( 'subscriber', (array) $user->roles, true ) && ! current_user_can( 'manage_options' ) ) {
			return false;
		}
		return $show;
	}
}
