<?php
/**
 * BookiFlex Core
 *
 * @package    BookiFlex
 * @subpackage Core
 * @author     BookiFlex
 * @copyright  Copyright (c) 2025 BookiFlex
 * @license    GPL-2.0-or-later
 *
 * @link       https://bookiflex.com
 */

declare(strict_types=1);

namespace BookiFlex\Core\Infrastructure\Logger;

use Psr\Log\AbstractLogger;

defined('ABSPATH') || exit;

/**
 * WordPress Debug Logger
 *
 * Simple PSR-3 compliant logger that writes to WordPress debug.log.
 * Requires WP_DEBUG and WP_DEBUG_LOG to be enabled in wp-config.php.
 *
 * Supports minimum log level filtering:
 * - Development (WP_DEBUG=true): 'debug' - logs everything
 * - Production (WP_DEBUG=false): 'warning' - logs warning and above only
 */
class WPLogger extends AbstractLogger
{
    /**
     * PSR-3 log levels with priority values.
     *
     * @var array<string, int>
     */
    private const LEVELS = [
        'debug'     => 100,
        'info'      => 200,
        'notice'    => 250,
        'warning'   => 300,
        'error'     => 400,
        'critical'  => 500,
        'alert'     => 550,
        'emergency' => 600,
    ];

    public function __construct(
        private readonly string $channel = 'bookiflex',
        private readonly string $minLevel = 'debug'
    ) {
    }

    /**
     * Logs with an arbitrary level.
     *
     * @param mixed $level Log level
     * @param string|\Stringable $message Log message
     * @param array<string, mixed> $context Context data
     */
    public function log($level, $message, array $context = []): void
    {
        $levelStr = strtolower((string) $level);

        // Skip logs below minimum level
        $levelPriority = self::LEVELS[$levelStr] ?? 0;
        $minPriority = self::LEVELS[$this->minLevel] ?? 0;
        if ($levelPriority < $minPriority) {
            return;
        }

        $contextJson = $context
            ? ' ' . json_encode($context, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE)
            : '';

        error_log(sprintf(
            '[%s] [%s] [%s] %s%s',
            gmdate('Y-m-d H:i:s'),
            strtoupper($levelStr),
            $this->channel,
            (string) $message,
            $contextJson
        ));
    }
}
