<?php
namespace WPD_Platform\Services;

if (!defined('ABSPATH')) {
    exit(); // Exit if accessed directly.
}

class ErrorLogService
{
    private $errorHandler;
    private $exceptionHandler;

    public function __construct()
    {
        // Set up custom handlers
        $this->setupErrorLogging();
    }

    /**
     * Set up error logging, exception handling, and fatal error handling.
     */
    private function setupErrorLogging()
    {
        // Custom error handler for non-fatal errors
        $this->errorHandler = set_error_handler([$this, 'errorHandler']);

        // Custom exception handler for uncaught exceptions
        $this->exceptionHandler = set_exception_handler([$this, 'exceptionHandler']);

        // Shutdown handler to catch fatal errors
        register_shutdown_function([$this, 'shutdownHandler']);
    }

    /**
     * Custom error handler for non-fatal errors.
     */
    public function errorHandler($code, $message, $file = '', $line = 0)
    {
        try {
            // Log only severe errors (skip warnings and deprecated messages)
            if (!$this->isSevereError($code)) {
                return false; // Let PHP's default error handler take care of it
            }

            // Log severe error
            $this->logErrorAction($file, 'Severe Error', $message);
        } catch (\Throwable $e) {
            // Silence any error in the handler itself
        }

        // Call the previous error handler if it exists
        if ($this->errorHandler) {
            return call_user_func($this->errorHandler, $code, $message, $file, $line);
        }

        return true; // Suppress default error handler
    }

    /**
     * Custom exception handler for uncaught exceptions.
     */
    public function exceptionHandler($exception)
    {
        try {
            // Log exception
            $this->logErrorAction($exception->getFile(), 'Exception', $exception->getMessage());
        } catch (\Throwable $e) {
            // Silence any error in the handler itself
        }

        // Call the previous exception handler if it exists
        if ($this->exceptionHandler) {
            return call_user_func($this->exceptionHandler, $exception);
        }
    }

    /**
     * Shutdown handler to catch fatal errors.
     */
    public function shutdownHandler()
    {
        // Check for the last error before shutdown
        $error = error_get_last();

        // If the error is fatal, log it
        if ($error && $this->isFatalError($error['type'])) {
            $this->logErrorAction($error['file'], 'Fatal Error', $error['message']);
        }
    }

    /**
     * Helper function to check if the error is severe.
     */
    private function isSevereError($errorCode)
    {
        // Define the severe error types to log
        $severeErrors = [E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_PARSE, E_USER_ERROR];
        return in_array($errorCode, $severeErrors);
    }

    /**
     * Helper function to check if the error is fatal (to be handled in shutdown).
     */
    private function isFatalError($errorCode)
    {
        // Fatal errors that we want to catch in shutdown
        return in_array($errorCode, [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR]);
    }

  /**
 * Log error action (used by both error and exception handlers).
 *
 * @param string $fileName The file where the error occurred.
 * @param string $action Type of error (e.g., Fatal Error, Exception).
 * @param string $errorMessage The error message.
 */
private function logErrorAction($fileName, $action, $errorMessage)
{
    // Retrieve current log data from dol_error_log
    $errorLog = get_option('dol_error_log', array());

    // Make the file path relative to the WordPress root directory (ABSPATH)
    if (strpos($fileName, ABSPATH) === 0) {
        $fileName = str_replace(ABSPATH, '', $fileName);
    }

    // Truncate the error message to a maximum of 150 characters
    $errorMessage = (strlen($errorMessage) > 250) ? substr($errorMessage, 0, 250) . '...' : $errorMessage;

    // Build the log entry
    $logEntry = array(
        'timestamp'   => current_time('timestamp'),
        'action'      => sanitize_text_field($action),
        'object_type' => sanitize_text_field($fileName), // Relative file path as object type
        'object_name' => sanitize_text_field($errorMessage), // The error message as object name
    );

    // Append to the existing log data
    $errorLog[] = $logEntry;

    // Trim the oldest entries if necessary
    if (count($errorLog) > 500) {
        $errorLog = array_slice($errorLog, -500);
    }

    // Update the option with the new combined log data
    update_option('dol_error_log', $errorLog, false);
}

}
