<?php

/**
 * Class responsible for loading the plugin on the admin side.
 */

namespace BoostsiteAIContentGenerator;

/**
 * Admin pages loader.
 */
class AdminLoader {

	/**
	 * The application domain.
	 *
	 * @var string
	 */
	protected $prefix;

	/**
	 * Checks if user is logged in.
	 *
	 * @var boolean
	 */
	protected $is_logged_in;

	/**
	 * Checks if user has a set schedule.
	 *
	 * @var boolean
	 */
	protected $has_schedule;

	/**
	 * Checks if user has a missing api key.
	 *
	 * @var boolean
	 */
	protected $missing_api_key;

	/**
	 * Stores the settings instance.
	 *
	 * @var object
	 */
	protected $settings;

	/**
	 * Stores the Boostsite instance.
	 *
	 * @var object
	 */
	protected $boostsite;

	/**
	 * Initialize this class.
	 *
	 * @param  mixed $prefix Plugin prefix.
	 * @return void
	 */
	public function __construct( $prefix ) {
		$this->prefix = $prefix;

		// Load the classes.
		$this->settings  = new Api\SettingController();
		$this->boostsite = new Boostsite();

		// On setup use values from settings.
		$this->is_logged_in = (bool) $this->settings->get_single_setting( 'email' );
		$this->has_schedule = (bool) count( $this->settings->get_single_setting( 'schedules' ) );
		add_action( 'admin_menu', array( $this, 'admin_menu' ) );
	}

	/**
	 * Register our menu page.
	 *
	 * @return void
	 */
	public function admin_menu() {
		$capability = 'manage_options';
		$slug       = $this->prefix;

		add_menu_page(
			esc_html( __( 'AI Content Generator', 'boostsite-ai-content-generator' ) ),
			esc_html( __( 'AI Content Generator', 'boostsite-ai-content-generator' ) ),
			$capability,
			$slug,
			array( $this, 'plugin_page' ),
			'dashicons-text' // tip: https://developer.wordpress.org/resource/dashicons.
		);

		// Add menu page for authorization callback.
		add_menu_page(
			esc_html( __( 'AI Content Generator Authorization', 'boostsite-ai-content-generator' ) ),
			'',
			$capability,
			'boostsite-menu',
			array( $this, 'authorization_page' )
		);

		// Hide the menu page.
		remove_menu_page( 'boostsite-menu' );

		if ( current_user_can( $capability ) && $this->is_logged_in && $this->has_schedule ) {
			add_submenu_page(
				$slug,
				esc_html( __( 'List of articles', 'boostsite-ai-content-generator' ) ),
				esc_html( __( 'List of articles', 'boostsite-ai-content-generator' ) ),
				$capability,
				$slug,
				array( $this, 'plugin_page' )
			);
			add_submenu_page(
				$slug,
				esc_html( __( 'Schedules', 'boostsite-ai-content-generator' ) ),
				esc_html( __( 'Schedules', 'boostsite-ai-content-generator' ) ),
				$capability,
				"admin.php?page={$slug}#/schedules"
			);
			add_submenu_page(
				$slug,
				esc_html( __( 'Settings', 'boostsite-ai-content-generator' ) ),
				esc_html( __( 'Settings', 'boostsite-ai-content-generator' ) ),
				$capability,
				"admin.php?page={$slug}#/settings"
			);
		}
	}

	/**
	 * Load scripts and styles for the app.
	 *
	 * @return void
	 */
	public function enqueue_scripts() {
		wp_enqueue_style( $this->prefix . '-admin' );
		wp_enqueue_script( $this->prefix . '-admin' );
	}

	/**
	 * Check if user is logged in.
	 *
	 * @return void
	 */
	public function check_user() {
		// Check if user is logged in.
		$this->is_logged_in = $this->boostsite->update_user();

		// Check if logged in user has a schedule.
		if ( $this->is_logged_in ) {
			$this->has_schedule = $this->boostsite->check_schedule();
		}
	}

	/**
	 * Check if user has a missing api key.
	 *
	 * @return void
	 */
	public function check_missing_api_key() {
		if ( ! $this->is_logged_in ) {
			return false;
		}

		$has_plugin = $this->settings->get_single_setting( 'has_plugin' );
		if ( ! $has_plugin ) {
			return false;
		}

		return empty( $this->settings->get_single_setting( 'api_key' ) );
	}

	/**
	 * Render our admin page.
	 *
	 * @return void
	 */
	public function plugin_page() {
		// Update the user only when visiting the plugin page.
		$this->check_user();
		$this->enqueue_scripts();
		$this->missing_api_key = $this->check_missing_api_key();

		$post_controller      = new Api\PostController();
		$boostsite_controller = new Api\BoostsiteController();

		// output data for use on client-side
		// https://wordpress.stackexchange.com/questions/344537/authenticating-with-rest-api.
		$app_vars = apply_filters(
			'boostsite_ai_admin_app_vars',
			array(
				'rest'               => array(
					'endpoints' => array(
						'settings'  => esc_url_raw( rest_url( $this->settings->get_endpoint() ) ),
						'posts'     => esc_url_raw( rest_url( $post_controller->get_endpoint() ) ),
						'boostsite' => esc_url_raw( rest_url( $boostsite_controller->get_endpoint() ) ),
					),
					'nonce'     => wp_create_nonce( 'wp_rest' ),
				),
				'settings'           => $this->settings->get_settings_raw( false ),
				'prefix'             => $this->prefix,
				'admin_url'          => admin_url( '/' ),
				'home_url'           => home_url(),
				'plugin_url'         => rtrim( \BoostsiteAIContentGenerator\Main::$base_url, '/' ),
				'is_logged_in'       => $this->is_logged_in,
				'is_api_key_missing' => $this->missing_api_key,
				'wordpress'          => array(
					'users'    => $this->get_users(),
					'keywords' => $this->get_post_keywords(),
					'timezone' => $this->get_timezone(),
				),
			)
		);

		wp_localize_script( $this->prefix . '-admin', 'boostsite_ai_config_admin', $app_vars );

		$content = '<div class="admin-app-wrapper"><div id="vue-admin-app"></div></div>';
		echo wp_kses_post( $content );
	}

	/**
	 * Handle the authorization page.
	 *
	 * @return void
	 */
	public function authorization_page() {
		// Security check: ensure user is logged in and has permission.
		if ( ! is_user_logged_in() || ! current_user_can( 'manage_options' ) ) {
			wp_die( esc_html__( 'You do not have permission to access this page.', 'boostsite-ai-content-generator' ) );
		}

		$auth_data = array();

		if ( isset( $_GET['session_id'] ) ) {
			// Validate session_id format.
			$session_id = sanitize_text_field( $_GET['session_id'] );
			if ( ! empty( $session_id ) ) {
				$auth_data = array( 'action' => 'close' );
			} else {
				$auth_data = array(
					'action'  => 'error',
					'message' => 'Invalid session data.',
				);
			}
		} elseif ( ! ( isset( $_GET['status'] ) && '200' === $_GET['status'] && isset( $_GET['user_id'] ) && isset( $_GET['email'] ) ) ) {
			// Handle auth error.
			$auth_data = array(
				'action'  => 'error',
				'message' => 'There was an unexpected error during authentication.',
			);
		} else {
			// Handle successful auth.
			$status  = sanitize_text_field( $_GET['status'] );
			$user_id = sanitize_text_field( $_GET['user_id'] );
			$email   = sanitize_email( $_GET['email'] );

			// Validate parameters more thoroughly.
			if ( '200' !== $status || empty( $user_id ) || empty( $email ) || ! is_email( $email ) ) {
				$auth_data = array(
					'action'  => 'error',
					'message' => 'Invalid authentication data received.',
				);
			} else {
				try {
					// Store user settings.
					$settings = array(
						'email' => $email,
						'plan'  => 'FREE',
					);

					$this->boostsite->save_user( $user_id, $settings );
					$auth_data = array( 'action' => 'close' );
				} catch ( \Exception $e ) {
					$auth_data = array(
						'action'  => 'error',
						'message' => 'There was an unexpected error during authentication.',
					);
				}
			}
		}

		// Enqueue and localize the script.
		wp_enqueue_script( $this->prefix . '-auth-callback' );
		wp_localize_script( $this->prefix . '-auth-callback', 'boostsiteAuthData', $auth_data );

		// Output simple HTML template.
		?>
		<!DOCTYPE html>
		<html>
		<head>
			<meta charset="utf-8">
			<title>Authorization</title>
			<?php wp_head(); ?>
		</head>
		<body>
			<p>Processing authorization...</p>
			<?php wp_footer(); ?>
		</body>
		</html>
		<?php
		exit;
	}

	/**
	 * Get all the users.
	 *
	 * @return array
	 */
	public function get_users() {
		// Get all the users.
		$users     = get_users();
		$usernames = array();

		foreach ( $users as $user ) {
			$usernames[] = $user->user_login;
		}

		return $usernames;
	}

	/**
	 * Get post keywords.
	 *
	 * @return array
	 */
	public function get_post_keywords() {
		global $wpdb;

		// Query to get all distinct values for the specified meta key.
		$results = $wpdb->get_col(
			$wpdb->prepare(
				"
					SELECT DISTINCT meta_value
					FROM {$wpdb->postmeta}
					WHERE meta_key = %s
				",
				'wp_autopost_ai_post_keywords'
			)
		);

		// Return just unieque keywords.
		$unique_keywords = array();

		// Flatten the array.
		if ( ! empty( $results ) ) {
			foreach ( $results as $value ) {
				$unique_keywords = array_merge( explode( ',', $value ), $unique_keywords );
			}
		}

		// Return unique results.
		return array_values( array_unique( $unique_keywords ) );
	}

	/**
	 * Get timezone in the correct format.
	 *
	 * @return string
	 */
	public function get_timezone() {
		$tz   = wp_timezone();
		$name = $tz->getName();

		// If timezone is UTC format return nothing.
		if ( preg_match( '/^[+\-]\d{1,2}:\d{2}$/', $name ) ) {
			return '';
		}

		// Return the timezone name.
		return $name;
	}
}
