<?php

declare(strict_types=1);

namespace Enot;

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

use Throwable;

final class EnotNotifierEmail extends EnotNotifier
{
	protected static function format(): string
	{
		$severity = Enot::getSeverityLevel(self::$e);

		$message = sprintf(
			'<h1>' . Enot::__('Error notification', 'error-monitor-and-notifier') . '</h1>'
				. '<p>PHP %1$s (%2$s): %3$s in %4$s on line %5$d</p>',
			self::severityName($severity),
			$severity,
			\esc_html(self::$e->getMessage()),
			\esc_html(self::$e->getFile()),
			filter_var(self::$e->getLine(), FILTER_SANITIZE_NUMBER_INT),
		);

		$message .= sprintf(
			"<p>Stack trace:</p><p><code>%s</code></p>",
			str_replace(ABSPATH, '', self::$e->getTraceAsString()),
		);

		if (!empty($_SERVER['REQUEST_URI'])) {
			$message .= "\nREQUEST_URI: <code>" . self::urlReplaceSensitiveArgs(\esc_url_raw(\wp_unslash($_SERVER['REQUEST_URI']))) . "</code>";
		}

		if (!empty($_SERVER['HTTP_USER_AGENT'])) {
			$message .= "\nUser Agent: <code>" . \sanitize_text_field(\wp_unslash($_SERVER['HTTP_USER_AGENT'])) . "</code>";
		}

		if (!empty($_SERVER['HTTP_REFERER'])) {
			$message .= ", referer: <code>" .  self::urlReplaceSensitiveArgs(\esc_url_raw(\wp_unslash($_SERVER['HTTP_REFERER']))) . "</code>";
		}

		$message .= "\nRequest IP: <code>" . self::getRequestIp() . "</code>";

		$user_id = \get_current_user_id();
		$message .= sprintf(
			"\n\n" . '%1$s: %2$s',
			Enot::__('User', 'error-monitor-and-notifier'),
			$user_id === 0
				? Enot::__('Guest', 'error-monitor-and-notifier')
				: sprintf('%1$d <a href="%2$s">%3$s</a>',
					$user_id,
                    \esc_url(\add_query_arg(['user_id' => $user_id], \self_admin_url('user-edit.php'))),
                     Enot::__('User Profile', 'error-monitor-and-notifier'),
				)
		);

		// Disable error recommendation
		$error_type = 'UNKNOWN';
		switch ($severity) {
			case -1:
				$error_type = 'EXCEPTION';
				break;
			default:
				$error_type = self::severityName($severity);
		}

		$message .= sprintf(
			'<p>ℹ  <a href="%1$s">%2$s</a> %3$s</p>',
			\esc_url(\admin_url('admin.php?page=' . ENOT_PLUGIN_ADMIN_MENU_SETTINGS_SLUG)),
			\esc_html(\__('Disable', 'error-monitor-and-notifier')),
			sprintf(
				Enot::__('%s error notifications in the plugin settings if emails arrive too frequently.', 'error-monitor-and-notifier'),
				\esc_html($error_type),
			)
		);

		return $message;
	}

	public static function notify(Throwable $e): bool
	{
		$severity = Enot::getSeverityLevel($e);

		if (Enot::$config['email'] === '' || !self::isNotificationEnabled($severity)) {
			return false;
		}

		self::$e = $e;

		$is_email_sent = false;

		$subject = sprintf(
			Enot::__('%s - %s: a level %s error has occured', 'error-monitor-and-notifier'),
			htmlspecialchars_decode(\esc_html(\get_bloginfo('name'))),
			ENOT_PLUGIN_NAME,
			self::severityName($severity),
		);

		$headers = "From: " . \get_bloginfo('admin_email') . "\r\n"
			. "MIME-Version: 1.0\r\n"
			. "Content-Type: text/html; charset=UTF-8\r\n";

		$email_message = self::format();

		if (function_exists('\wp_mail') && \apply_filters('enot_use_wp_mail', true)) {
			$is_email_sent = \wp_mail(
				Enot::$config['email'],
				\apply_filters('enot_wp_mail_subject', $subject),
				nl2br($email_message),
				$headers,
			);
		} else {
			$is_email_sent = mail(
				Enot::$config['email'],
				\apply_filters('enot_mail_subject', $subject),
				nl2br($email_message),
				$headers,
			);
		}

		if (!$is_email_sent) {
			Enot::$config['trigger_error_response_message'] = Enot::__('Sending email failed.', 'error-monitor-and-notifier');
			return false;
		}

		return $is_email_sent;
	}
}
