<?php

declare(strict_types=1);

namespace Enot;

// Avoid direct access to this piece of code
defined('ABSPATH') || exit;

use DateTimeImmutable;

final class EnotAdmin
{
	private static array $config;

	private static ?object $api_response_data = null;

	public static function init(): void
	{
		self::$config = Enot::config();

		\add_action('admin_enqueue_scripts', static function ($hook_suffix) {
			self::loadPageSettingsScripts($hook_suffix);
		});

		\add_action('admin_menu', static function (): void {
			self::initPages();
		});

		\add_action('wp_ajax_enot_trigger_error', static function (): void {
			self::triggerError();
		});

		\add_filter('plugin_action_links', static function (array $actions, string $plugin_file, array $plugin_data, string $context): array {
			return self::addLinks($actions, $plugin_file, $plugin_data, $context,);
		}, 10, 4);

		\add_filter('all_plugins', [__CLASS__, 'modifyPluginDescription']);

		\add_action('current_screen', [__CLASS__, 'processPostRequest']);
	}

	public static function processPostRequest(): void
	{
		$screen = \get_current_screen();
		if ($screen === null) {
			return;
		}

		$screen_page = strstr($screen->id, 'enot'); // e.g. enot-settings

		if ($screen_page === false) {
			return;
		}

		if (strncmp($screen_page, 'enot-', 5) !== 0) {
			return;
		}

		// phpcs:disable WordPress.Security.NonceVerification.Missing
		$page = isset($_POST[ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG])
			? \sanitize_text_field(\wp_unslash($_POST[ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG]))
			: null;
		if ($page === null) {
			return;
		}

		switch ($page) {
			case 'general':
				self::processGeneralSettingsForm();
				break;
			case 'email':
				self::processEmailSettingsForm();
				break;
			default:
				break;
		}
	}

	private static function addLinks(
		array $actions,
		string $plugin_file,
		array $plugin_data,
		string $context
	): array {
		if ($plugin_file !== ENOT_PLUGIN_BASENAME) {
			return $actions;
		}

		$actions[] = sprintf(
			'<a href="%s">%s</a>',
			\admin_url('admin.php') . '?page=enot-settings',
			\__('Settings', 'error-monitor-and-notifier'),
		);

		$license = null;

		if ($license === null || $license->status !== 'Active') {
			$actions[] = sprintf(
				'<a href="%s" target="_blank">%s</a>',
				\trailingslashit(\esc_url(ENOT_PLUGIN_SITE_URL)),
				\__('Upgrade to Premium', 'error-monitor-and-notifier'),
			);
		}

		return $actions;
	}

	public static function modifyPluginDescription(array $all_plugins): array
	{
		if (isset($all_plugins[ENOT_PLUGIN_BASENAME])) {
			$all_plugins[ENOT_PLUGIN_BASENAME]['Description'] = \__(
				'Automatically detects PHP and JavaScript errors, errors in database queries, and sends a notification with detailed technical information about the failure',
				'error-monitor-and-notifier'
			);
		}

		return $all_plugins;
	}

	private static function loadPageSettingsStyles(): void
	{
		\wp_enqueue_style(
			'enot_settings',
			ENOT_PLUGIN_ROOT_URL . 'assets/css/admin.css',
			[],
			ENOT_PLUGIN_VERSION,
			'all',
		);
	}

	private static function loadPageSettingsScripts(string $hook_suffix): void
	{
		if (substr($hook_suffix, -strlen('page_enot-email')) === 'page_enot-email') {
			\wp_register_script(
				'enot-admin-settings-email',
				ENOT_PLUGIN_ROOT_URL . 'assets/js/admin-settings-email.js',
				['jquery'],
				ENOT_PLUGIN_VERSION,
				[
					'strategy' => 'defer',
					'in_footer' => true,
				],
			);

			$ajax_trigger_error_nonce = \wp_create_nonce('enot_trigger_error');

			$inline_script = sprintf(
			    'const enotData = {"ajax_nonce": "%s", "ajax_url": "%s"};',
			    \esc_js($ajax_trigger_error_nonce),
			    \esc_url_raw(\admin_url('admin-ajax.php'))
			);

			\wp_add_inline_script('enot-admin-settings-email', $inline_script, 'before');
			\wp_enqueue_script('enot-admin-settings-email');

		}
	}

	private static function triggerError(): void
	{
		if (!\check_ajax_referer('enot_trigger_error')) {
			\wp_send_json_error(['message' => 'Wrong nonce', 'code' => 403,]);
		}

		$error_type = isset($_POST['trigger_error_type']) ? \sanitize_text_field(\wp_unslash($_POST['trigger_error_type'])) : null;
		$email      = isset($_POST['email']) ? \sanitize_email(\wp_unslash($_POST['email'])) : null;

		if ($error_type === null) {
			echo \wp_json_encode(['message' => \__('The error trigger type is empty', 'error-monitor-and-notifier')]);
			exit;
		} elseif (!in_array($error_type, self::$config['trigger_error_types'], true)) {
			echo \wp_json_encode(['message' => \__('Wrong an error trigger type', 'error-monitor-and-notifier')]);
			exit;
		}

		Enot::triggerError($error_type, $email);
		\wp_die();
	}

	private static function initPages(): void
	{
		$page_settings = \add_menu_page(
			sprintf('%s - %s', ENOT_PLUGIN_NAME, \__('Settings', 'error-monitor-and-notifier')), // Page Title
			'Error Monitor',                                               // Menu Name
			'manage_options',                                              // Capability
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                          // Menu Slug
			static function () {                                           // Function
				self::displayPageSettings();
			},
			'dashicons-bell',                                               // Icon URL
			90,                                                             // Position
		);

		$page_telegram = \add_submenu_page(
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                          // Parent slug
			sprintf('%s - %s', ENOT_PLUGIN_NAME, \__('Settings', 'error-monitor-and-notifier')), // Page Title
			\__('Settings', 'error-monitor-and-notifier'),                                       // Menu Name
			'manage_options',                                              // Capability
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                          // Menu Slug
			static function () {                                           // View Callback
				self::displayPageSettings();
			},
			10,                                                            // Position
		);

		$page_email = \add_submenu_page(
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                         // Parent slug
			sprintf('%s - %s', ENOT_PLUGIN_NAME, \__('Email', 'error-monitor-and-notifier')),   // Page Title
			\__('Email', 'error-monitor-and-notifier'),                                         // Menu Name
			'manage_options',                                             // Capability
			'enot-email',                                                 // Menu Slug
			static function () {                                          // View Callback
				self::displayPageEmail();
			},
			20,                                                           // Position
		);

		$page_telegram = \add_submenu_page(
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                          // Parent slug
			sprintf('%s - %s', ENOT_PLUGIN_NAME, \__('Telegram', 'error-monitor-and-notifier')), // Page Title
			\__('Telegram', 'error-monitor-and-notifier'),                                       // Menu Name
			'manage_options',                                              // Capability
			'enot-telegram',                                               // Menu Slug
			static function () {                                           // View Callback
				self::displayPageTelegram();
			},
			30,                                                            // Position
		);

		$page_license = \add_submenu_page(
			ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG,                          // Parent slug
			sprintf('%s - %s', ENOT_PLUGIN_NAME, \__('License', 'error-monitor-and-notifier')),  // Page Title
			\__('License', 'error-monitor-and-notifier'),                                        // Menu Name
			'manage_options',                                              // Capability
			'enot-license',                                                // Menu Slug
			static function () {                                           // View Callback
				self::displayPageLicense();
			},
			40,                                                            // Position
		);

		\add_action('load-' . $page_settings, static function () {
			self::loadPageSettingsStyles();
		});

		\add_action('load-' . $page_email, static function () {
			self::loadPageSettingsStyles();
		});

		\add_action('load-' . $page_telegram, static function () {
			self::loadPageSettingsStyles();
		});

		\add_action('load-' . $page_license, static function () {
			self::loadPageSettingsStyles();
		});
	}

	private static function displayPageSettings(): void
	{
		$error_levels = Enot::errorLevels();
		$options = \get_option(self::$config['option_name']);

		require_once ENOT_PLUGIN_ROOT_PATH . '/admin/settings.php';
	}

	private static function displayPageEmail(): void
	{
		$options = \get_option(self::$config['option_name']);

		require_once ENOT_PLUGIN_ROOT_PATH . '/admin/email.php';
	}

	private static function displayPageTelegram(): void
	{
		$options = \get_option(self::$config['option_name']);

		$telegram = null;

		require_once ENOT_PLUGIN_ROOT_PATH . '/admin/telegram.php';
	}

	private static function displayPageLicense(): void
	{
		$license = null;
		$api_response_data = self::$api_response_data;

		require_once ENOT_PLUGIN_ROOT_PATH . '/admin/license.php';
	}

	private static function processGeneralSettingsForm(): void
	{
		if (!isset($_POST['_wpnonce']) || !\wp_verify_nonce(\sanitize_text_field(\wp_unslash($_POST['_wpnonce'])), 'enot-admin-general-settings')) {
			exit;
		}

		$options = \get_option(Enot::$config['option_name']);


		$options['severities'] = isset($_POST['severity'])
			? array_map(
				fn(string $severity) => (int) $severity,
				// phpcs:disable WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
				array_map('\sanitize_text_field', \wp_unslash($_POST['severity']))
			) : [];
		$options['exclude_duplicate_notifications'] = isset($_POST['exclude-duplicate-notifications']) ? true : false;
		$options['fatal_error_text'] = isset($_POST['fatal-error-text'])
			? \wp_kses(\wp_unslash($_POST['fatal-error-text']), 'post')
			: self::$config['fatal_error_text'];

		\update_option(self::$config['option_name'], $options, 'yes');
	}

	private static function processEmailSettingsForm(): void
	{
		if (!isset($_POST['_wpnonce']) || !\wp_verify_nonce(\sanitize_text_field(\wp_unslash($_POST['_wpnonce'])), 'enot-admin-email-settings')) {
			exit;
		}

		$options = \get_option(Enot::$config['option_name']);
		$options['email'] = isset($_POST['email']) && filter_var(\wp_unslash($_POST['email']), FILTER_VALIDATE_EMAIL)
			? \sanitize_email(\wp_unslash($_POST['email']))
			: '';
		\update_option(self::$config['option_name'], $options, 'yes');

	    $notice_css = '';
	    if ($options['email'] !== '') {
	        $notice_css = ' notice-success';
	        $notice_message = \__('Email notifications are enabled', 'error-monitor-and-notifier');
	    } else {
	        $notice_message = \__('Email notifications are disabled', 'error-monitor-and-notifier');
	    }

		?>

	    <div id="message" class="notice<?php echo \esc_attr($notice_css) ?> is-dismissible">
	        <p><?php echo \esc_html($notice_message) ?></p>
	    </div>

		<?php
	}
}
