<?php

declare(strict_types=1);

/**
 * Test Script for ErrorHandling Module
 *
 * Tests the current error handling system with various exception types
 * to verify handler registration, priority execution, and response generation.
 */

require_once __DIR__ . '/../../vendor/autoload.php';

use App\Framework\ErrorHandling\Handlers\{
    ValidationErrorHandler,
    DatabaseErrorHandler,
    HttpErrorHandler,
    FallbackErrorHandler
};
use App\Framework\ErrorHandling\{ErrorHandlerManager, ErrorHandlerRegistry};
use App\Framework\Validation\Exceptions\ValidationException;
use App\Framework\Validation\ValidationResult;
use App\Framework\Database\Exception\DatabaseException;
use App\Framework\Http\Exception\HttpException;
use App\Framework\Http\Status;
use App\Framework\Exception\ExceptionContext;
use App\Framework\Logging\Logger;
use App\Framework\Logging\ValueObjects\LogContext;
use App\Framework\Logging\LogLevel;

echo "=== ErrorHandling Module Test ===\n\n";

// Setup Logger (mock for testing)
$logger = new class implements Logger {
    public function debug(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::debug] {$message}\n";
    }

    public function info(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::info] {$message}\n";
    }

    public function notice(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::notice] {$message}\n";
    }

    public function warning(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::warning] {$message}\n";
    }

    public function error(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::error] {$message}\n";
        if ($context && $context->structured) {
            echo "   Context: " . print_r($context->structured, true) . "\n";
        }
    }

    public function critical(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::critical] {$message}\n";
    }

    public function alert(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::alert] {$message}\n";
    }

    public function emergency(string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::emergency] {$message}\n";
    }

    public function log(LogLevel $level, string $message, ?LogContext $context = null): void {
        echo "📝 [Logger::{$level->value}] {$message}\n";
    }
};

// Setup ErrorHandlerManager
$registry = new ErrorHandlerRegistry();
$manager = new ErrorHandlerManager($registry);

// Register handlers in priority order
echo "Registering handlers...\n";
$manager->register(new ValidationErrorHandler());
$manager->register(new DatabaseErrorHandler($logger));
$manager->register(new HttpErrorHandler());
$manager->register(new FallbackErrorHandler($logger));
echo "✅ All handlers registered\n\n";

// Test 1: ValidationException
echo "--- Test 1: ValidationException ---\n";
try {
    $validationResult = new ValidationResult();
    $validationResult->addErrors('email', ['Email is required', 'Email format is invalid']);
    $validationResult->addErrors('password', ['Password must be at least 8 characters']);

    $exception = new ValidationException($validationResult);

    $result = $manager->handleException($exception);

    echo "✅ Handled: " . ($result->handled ? 'Yes' : 'No') . "\n";
    echo "   Message: {$result->message}\n";
    echo "   Status Code: {$result->statusCode}\n";
    echo "   Error Type: {$result->data['error_type']}\n";
    echo "   Errors: " . print_r($result->data['errors'], true) . "\n";
} catch (\Throwable $e) {
    echo "❌ Error: {$e->getMessage()}\n";
}
echo "\n";

// Test 2: DatabaseException
echo "--- Test 2: DatabaseException ---\n";
try {
    $exception = DatabaseException::fromContext(
        'Connection failed: Too many connections',
        ExceptionContext::empty()
    );

    $result = $manager->handleException($exception);

    echo "✅ Handled: " . ($result->handled ? 'Yes' : 'No') . "\n";
    echo "   Message: {$result->message}\n";
    echo "   Status Code: {$result->statusCode}\n";
    echo "   Error Type: {$result->data['error_type']}\n";
    echo "   Retry After: {$result->data['retry_after']} seconds\n";
} catch (\Throwable $e) {
    echo "❌ Error: {$e->getMessage()}\n";
}
echo "\n";

// Test 3: HttpException
echo "--- Test 3: HttpException (404 Not Found) ---\n";
try {
    $exception = new HttpException(
        'Resource not found',
        Status::NOT_FOUND,
        headers: ['X-Resource-Type' => 'User']
    );

    $result = $manager->handleException($exception);

    echo "✅ Handled: " . ($result->handled ? 'Yes' : 'No') . "\n";
    echo "   Message: {$result->message}\n";
    echo "   Status Code: {$result->statusCode}\n";
    echo "   Error Type: {$result->data['error_type']}\n";
    echo "   Headers: " . print_r($result->data['headers'], true) . "\n";
} catch (\Throwable $e) {
    echo "❌ Error: {$e->getMessage()}\n";
}
echo "\n";

// Test 4: Generic RuntimeException (Fallback)
echo "--- Test 4: Generic RuntimeException (Fallback Handler) ---\n";
try {
    $exception = new \RuntimeException('Something unexpected happened');

    $result = $manager->handleException($exception);

    echo "✅ Handled: " . ($result->handled ? 'Yes' : 'No') . "\n";
    echo "   Message: {$result->message}\n";
    echo "   Status Code: {$result->statusCode}\n";
    echo "   Error Type: {$result->data['error_type']}\n";
    echo "   Exception Class: {$result->data['exception_class']}\n";
    echo "   Is Final: " . ($result->isFinal ? 'Yes' : 'No') . "\n";
} catch (\Throwable $e) {
    echo "❌ Error: {$e->getMessage()}\n";
}
echo "\n";

// Test 5: PDOException (Database Handler)
echo "--- Test 5: PDOException ---\n";
try {
    $exception = new \PDOException('SQLSTATE[HY000] [2002] Connection refused');

    $result = $manager->handleException($exception);

    echo "✅ Handled: " . ($result->handled ? 'Yes' : 'No') . "\n";
    echo "   Message: {$result->message}\n";
    echo "   Status Code: {$result->statusCode}\n";
    echo "   Error Type: {$result->data['error_type']}\n";
} catch (\Throwable $e) {
    echo "❌ Error: {$e->getMessage()}\n";
}
echo "\n";

// Test 6: Handler Priority Order
echo "--- Test 6: Handler Priority Verification ---\n";
$handlers = $manager->getHandlers();
echo "Registered handlers in priority order:\n";
foreach ($handlers as $index => $handler) {
    $priority = $handler->getPriority();
    $name = $handler->getName();
    echo "   " . ($index + 1) . ". {$name} (Priority: {$priority->value})\n";
}
echo "\n";

echo "=== All Tests Completed ===\n";
