<?php
/**
 * A Monolog extended class for logging messages into the database.
 */

declare(strict_types=1);
namespace FeData\FastEvents\Logging;

defined( 'ABSPATH' ) || exit;


use FeData\FastEvents\Storage\PluginSettings;
use FeData\FastEvents\Utilities\JsonUtil;
use Monolog\Level;
use Monolog\LogRecord;
use Monolog\Handler\AbstractProcessingHandler;

/**
 * A class for logging messages into the database.
 */
final class LoggerDBHandler extends AbstractProcessingHandler {


	/**
	 * LoggerDBHandler constructor.
	 * Get the level from the Settings and create the parent.
	 *
	 * @since 3.0.0
	 *
	 * @param PluginSettings $settings Plugin settings.
	 */
	public function __construct( private readonly PluginSettings $settings ) {
		parent::__construct( Level::fromName( $this->settings->log_level() ) );
	}

	/**
	 * Singletons should not be cloneable.
	 *
	 * @since 3.0.0
	 */
	private function __clone(): void {
	}


	/**
	 * Prevent from being unserialized.
	 *
	 * @since 3.0.0
	 */
	public function __wakeup(): void {
	}

	/**
	 * Convert Monolog structure to database structure and write to the database.
	 *
	 * @since 3.0.0
	 *
	 * @param LogRecord $record The Monolog record.
	 */
	protected function write( LogRecord $record ): void {
		global $wpdb;

		$context          = $record->context;
		$context['level'] = $record->level->getName();
		$event_id         = $context['event_id'] ?? 0;
		$order_id         = $context['order_id'] ?? 0;
		$log_type         = $context['type'] ?? '';

		/**
		 * Filter the input of the log message.
		 *
		 * @since 2.5.0
		 *
		 * @param string $message The log message.
		 * @param array  $context Additional context information.
		 */
		if ( has_filter( 'fast_events_log_filter' ) ) {
			$context = apply_filters( 'fast_events_log_filter', $record->message, $context );
		}

		$context['plugin_message'] = $record->message;
		$wpdb->query(
			$wpdb->prepare(
				"INSERT INTO {$wpdb->prefix}fe_event_log(event_id, order_id, created_at, log_type, description) " .
				'VALUES(%d, %d, %s, %s, %s)',
				$event_id,
				$order_id,
				current_time( 'mysql' ),
				$log_type,
				JsonUtil::fast_events_json_encode( $context )
			)
		);
		unset( $context['plugin_message'] );

		/**
		 * Action after adding the message to the database.
		 *
		 * @since 2.5.0
		 *
		 * @param string $tmessage The log message.
		 * @param array  $context  Additional context information.
		 */
		if ( has_action( 'fast_events_log' ) ) {
			do_action( 'fast_events_log', $record->message, $context );
		}
	}
}
