<?php
/**
 * Logger Helper using Monolog with fallback to error_log.
 *
 * @package PrimeLink
 */

namespace PrimeLink\Helpers;

if ( ! defined( 'ABSPATH' ) ) {
    exit;
}

/**
 * Logger Helper class for structured logging.
 * Uses Monolog if available, falls back to error_log().
 */
final class LoggerHelper {

    /**
     * Logger instance.
     *
     * @var \Monolog\Logger|null
     */
    private static $logger = null;

    /**
     * Initialize logger.
     *
     * @return void
     */
    private static function init_logger() {
        if ( self::$logger !== null ) {
            return;
        }

        // Monolog 3.x requires PHP 8.0+
        if ( version_compare( PHP_VERSION, '8.0.0', '<' ) ) {
            self::$logger = false;
            return;
        }

        // Try Monolog (prefixed or normal)
        $monolog_logger_class = null;
        if ( class_exists( '\PrimeLink\Vendor\Monolog\Logger' ) ) {
            $monolog_logger_class = '\PrimeLink\Vendor\Monolog\Logger';
            $monolog_handler_class = '\PrimeLink\Vendor\Monolog\Handler\StreamHandler';
            $monolog_formatter_class = '\PrimeLink\Vendor\Monolog\Formatter\LineFormatter';
        } elseif ( class_exists( '\Monolog\Logger' ) ) {
            $monolog_logger_class = '\Monolog\Logger';
            $monolog_handler_class = '\Monolog\Handler\StreamHandler';
            $monolog_formatter_class = '\Monolog\Formatter\LineFormatter';
        }

        if ( $monolog_logger_class ) {
            try {
                self::$logger = new $monolog_logger_class( 'primelink' );

                // Get upload directory for log file
                $upload_dir = wp_upload_dir();
                $log_dir = $upload_dir['basedir'] . '/primelink/logs';
                
                // Create log directory if it doesn't exist
                if ( ! file_exists( $log_dir ) ) {
                    wp_mkdir_p( $log_dir );
                }

                // Add file handler with rotation
                $log_file = $log_dir . '/primelink-' . date( 'Y-m-d' ) . '.log';
                // Use constant from the detected class
                $debug_level = defined( $monolog_logger_class . '::DEBUG' ) ? constant( $monolog_logger_class . '::DEBUG' ) : 100;
                $handler = new $monolog_handler_class( $log_file, $debug_level );
                
                // Set format
                $formatter = new $monolog_formatter_class(
                    "[%datetime%] %level_name%: %message% %context% %extra%\n",
                    'Y-m-d H:i:s'
                );
                $handler->setFormatter( $formatter );
                self::$logger->pushHandler( $handler );

                // Add WooCommerce debug log handler if WP_DEBUG is enabled
                if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
                    $wp_handler = new $monolog_handler_class( WP_CONTENT_DIR . '/debug.log', $debug_level );
                    $wp_handler->setFormatter( $formatter );
                    self::$logger->pushHandler( $wp_handler );
                }
            } catch ( \Exception $e ) {
                // Fallback to error_log if Monolog fails
                self::$logger = false;
            }
        } else {
            // Monolog not available
            self::$logger = false;
        }
    }

    /**
     * Log debug message.
     *
     * @param string $message Log message.
     * @param array  $context Additional context.
     * @return void
     */
    public static function debug( $message, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->debug( $message, $context );
        } else {
            error_log( '[PrimeLink DEBUG] ' . $message . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' ) );
        }
    }

    /**
     * Log info message.
     *
     * @param string $message Log message.
     * @param array  $context Additional context.
     * @return void
     */
    public static function info( $message, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->info( $message, $context );
        } else {
            error_log( '[PrimeLink INFO] ' . $message . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' ) );
        }
    }

    /**
     * Log warning message.
     *
     * @param string $message Log message.
     * @param array  $context Additional context.
     * @return void
     */
    public static function warning( $message, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->warning( $message, $context );
        } else {
            error_log( '[PrimeLink WARNING] ' . $message . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' ) );
        }
    }

    /**
     * Log error message.
     *
     * @param string $message Log message.
     * @param array  $context Additional context.
     * @return void
     */
    public static function error( $message, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->error( $message, $context );
        } else {
            error_log( '[PrimeLink ERROR] ' . $message . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' ) );
        }
    }

    /**
     * Log critical error message.
     *
     * @param string $message Log message.
     * @param array  $context Additional context.
     * @return void
     */
    public static function critical( $message, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->critical( $message, $context );
        } else {
            error_log( '[PrimeLink CRITICAL] ' . $message . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' ) );
        }
    }

    /**
     * Log exception.
     *
     * @param \Exception|\Throwable $exception Exception to log.
     * @param array                  $context   Additional context.
     * @return void
     */
    public static function exception( $exception, $context = array() ) {
        self::init_logger();
        if ( self::$logger ) {
            self::$logger->error(
                $exception->getMessage(),
                array_merge(
                    $context,
                    array(
                        'exception' => get_class( $exception ),
                        'file'      => $exception->getFile(),
                        'line'      => $exception->getLine(),
                        'trace'     => $exception->getTraceAsString(),
                    )
                )
            );
        } else {
            error_log(
                sprintf(
                    '[PrimeLink EXCEPTION] %s in %s:%d - %s',
                    get_class( $exception ),
                    $exception->getFile(),
                    $exception->getLine(),
                    $exception->getMessage()
                ) . ( ! empty( $context ) ? ' ' . wp_json_encode( $context ) : '' )
            );
        }
    }
}

