<?php

declare( strict_types=1 );

namespace StrykeWP\Core;

/**
 * Shared logging service for STRYKE WP.
 *
 * Writes structured log entries via WordPress's error_log() with a
 * consistent prefix so entries can be filtered in server logs.
 * In later phases this service can be extended to write to a custom DB table.
 *
 * @package StrykeWP\Core
 */
class Logger {

	public const LEVEL_DEBUG   = 'DEBUG';
	public const LEVEL_INFO    = 'INFO';
	public const LEVEL_WARNING = 'WARNING';
	public const LEVEL_ERROR   = 'ERROR';

	private const MAX_BUFFER_SIZE = 500;

	/** @var array<int, array{level: string, message: string, context: array<string,mixed>, timestamp: string}> */
	private array $buffer = [];

	// ---------------------------------------------------------------------------
	// Public API
	// ---------------------------------------------------------------------------

	/** @param array<string,mixed> $context */
	public function debug( string $message, array $context = [] ): void {
		$this->log( $message, self::LEVEL_DEBUG, $context );
	}

	/** @param array<string,mixed> $context */
	public function info( string $message, array $context = [] ): void {
		$this->log( $message, self::LEVEL_INFO, $context );
	}

	/** @param array<string,mixed> $context */
	public function warning( string $message, array $context = [] ): void {
		$this->log( $message, self::LEVEL_WARNING, $context );
	}

	/** @param array<string,mixed> $context */
	public function error( string $message, array $context = [] ): void {
		$this->log( $message, self::LEVEL_ERROR, $context );
	}

	/**
	 * Core log method.
	 *
	 * @param string              $message Human-readable message.
	 * @param string              $level   One of the LEVEL_* constants.
	 * @param array<string,mixed> $context Key-value pairs to interpolate or append.
	 */
	public function log( string $message, string $level = self::LEVEL_INFO, array $context = [] ): void {
		$timestamp = current_time( 'mysql' );

		// Buffer entry for potential in-request access (capped to prevent memory exhaustion).
		if ( count( $this->buffer ) < self::MAX_BUFFER_SIZE ) {
			$this->buffer[] = compact( 'level', 'message', 'context', 'timestamp' );
		}

		// Write to WP debug log when WP_DEBUG_LOG is enabled.
		if ( defined( 'WP_DEBUG_LOG' ) && WP_DEBUG_LOG ) {
			$ctx_str = empty( $context ) ? '' : ' ' . wp_json_encode( $context );
			// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_error_log
			error_log( sprintf( '[STRYKE WP][%s][%s] %s%s', $timestamp, $level, $message, $ctx_str ) );
		}
	}

	/**
	 * Returns all log entries buffered during this request.
	 *
	 * @return array<int, array{level: string, message: string, context: array<string,mixed>, timestamp: string}>
	 */
	public function get_buffer(): array {
		return $this->buffer;
	}
}
