<?php

namespace App\Support;

use Illuminate\Http\Request;
use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface;

/**
 * ErrorPageHelper
 *
 * Centralises all logic for building the data passed to the custom error view.
 * Keeps bootstrap/app.php clean and makes the error definitions easy to extend.
 */
class ErrorPageHelper
{
    // ─────────────────────────────────────────────────────────────────────────
    // Dashboard detection
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Determine whether the failing request originated from a dashboard/admin
     * area so we can show a "Back to Dashboard" button instead of "Back to Home".
     */
    public static function isDashboardRequest(Request $request): bool
    {
        $path = ltrim($request->path(), '/');

        $dashboardPrefixes = [
            'dashboard',
            'admin',
            'users',
            'roles',
            'profile',
            'settings',
            'config',
            'samples',
            'self-paced/dashboard',
            'training/dashboard',
            'mentorship/dashboard',
            'membership/dashboard',
            'advocacy/dashboard',
            'research/dashboard',
            'knowledge-sharing/dashboard',
            'partners/dashboard',
            'topbar-notifications',
            'email-subscribers',
        ];

        foreach ($dashboardPrefixes as $prefix) {
            if (str_starts_with($path, $prefix)) {
                return true;
            }
        }

        return false;
    }

    // ─────────────────────────────────────────────────────────────────────────
    // Error definitions
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Returns the full definition for every supported HTTP error code.
     *
     * Each entry contains:
     *   title       — short human-readable name
     *   description — plain-English explanation shown to the user
     *   icon        — FontAwesome 6 class for the large icon
     *   badgeIcon   — FontAwesome 6 class for the small badge icon
     *   themeClass  — CSS class that controls the colour scheme
     *   iconPulse   — optional 'icon-pulse' class for animated icons
     */
    public static function definitions(): array
    {
        return [
            // ── 2xx (informational — unlikely to be shown, but covered) ──────
            200 => [
                'title'       => 'OK',
                'description' => 'The request was successful. If you are seeing this page, something unexpected happened while rendering the response.',
                'icon'        => 'fas fa-circle-check',
                'badgeIcon'   => 'fas fa-circle-check',
                'themeClass'  => 'theme-2xx',
            ],
            202 => [
                'title'       => 'Accepted',
                'description' => 'Your request has been accepted and is being processed. Please check back shortly.',
                'icon'        => 'fas fa-hourglass-half',
                'badgeIcon'   => 'fas fa-hourglass-half',
                'themeClass'  => 'theme-2xx',
            ],

            // ── 3xx (redirects) ───────────────────────────────────────────────
            301 => [
                'title'       => 'Moved Permanently',
                'description' => 'The page you requested has been permanently moved to a new location. Please update your bookmarks.',
                'icon'        => 'fas fa-arrow-right-arrow-left',
                'badgeIcon'   => 'fas fa-arrows-rotate',
                'themeClass'  => 'theme-3xx',
            ],
            304 => [
                'title'       => 'Not Modified',
                'description' => 'The content has not changed since your last visit. Your browser\'s cached version is up to date.',
                'icon'        => 'fas fa-database',
                'badgeIcon'   => 'fas fa-database',
                'themeClass'  => 'theme-3xx',
            ],
            307 => [
                'title'       => 'Temporary Redirect',
                'description' => 'This resource has been temporarily moved. You will be redirected automatically.',
                'icon'        => 'fas fa-route',
                'badgeIcon'   => 'fas fa-route',
                'themeClass'  => 'theme-3xx',
            ],
            308 => [
                'title'       => 'Permanent Redirect',
                'description' => 'This resource has been permanently moved to a new URL. Please update your links.',
                'icon'        => 'fas fa-map-signs',
                'badgeIcon'   => 'fas fa-map-signs',
                'themeClass'  => 'theme-3xx',
            ],

            // ── 4xx (client errors) ───────────────────────────────────────────
            400 => [
                'title'       => 'Bad Request',
                'description' => 'The server could not understand your request due to invalid syntax or missing parameters. Please check your input and try again.',
                'icon'        => 'fas fa-triangle-exclamation',
                'badgeIcon'   => 'fas fa-triangle-exclamation',
                'themeClass'  => 'theme-4xx',
            ],
            401 => [
                'title'       => 'Unauthorised',
                'description' => 'You need to be logged in to access this page. Please sign in with your credentials and try again.',
                'icon'        => 'fas fa-lock',
                'badgeIcon'   => 'fas fa-lock',
                'themeClass'  => 'theme-auth',
            ],
            402 => [
                'title'       => 'Payment Required',
                'description' => 'Access to this resource requires a valid payment or active subscription. Please complete your payment to continue.',
                'icon'        => 'fas fa-credit-card',
                'badgeIcon'   => 'fas fa-credit-card',
                'themeClass'  => 'theme-4xx',
            ],
            403 => [
                'title'       => 'Forbidden',
                'description' => 'You do not have permission to access this page. If you believe this is a mistake, please contact your administrator.',
                'icon'        => 'fas fa-ban',
                'badgeIcon'   => 'fas fa-ban',
                'themeClass'  => 'theme-auth',
            ],
            404 => [
                'title'       => 'Page Not Found',
                'description' => 'The page you are looking for does not exist, may have been moved, or the link you followed might be broken.',
                'icon'        => 'fas fa-compass',
                'badgeIcon'   => 'fas fa-magnifying-glass',
                'themeClass'  => 'theme-404',
            ],
            405 => [
                'title'       => 'Method Not Allowed',
                'description' => 'The HTTP method used for this request is not supported by this endpoint. Please check the request method and try again.',
                'icon'        => 'fas fa-hand',
                'badgeIcon'   => 'fas fa-hand',
                'themeClass'  => 'theme-4xx',
            ],
            419 => [
                'title'       => 'Page Expired',
                'description' => 'Your session has expired or the security token for this page is no longer valid. This usually happens after a period of inactivity. Please go back and try again.',
                'icon'        => 'fas fa-clock-rotate-left',
                'badgeIcon'   => 'fas fa-clock',
                'themeClass'  => 'theme-419',
            ],
            421 => [
                'title'       => 'Misdirected Request',
                'description' => 'Your request was sent to a server that is not able to produce a response for this combination of scheme and authority.',
                'icon'        => 'fas fa-network-wired',
                'badgeIcon'   => 'fas fa-network-wired',
                'themeClass'  => 'theme-4xx',
            ],
            429 => [
                'title'       => 'Too Many Requests',
                'description' => 'You have sent too many requests in a short period of time. Please slow down and wait a moment before trying again.',
                'icon'        => 'fas fa-gauge-high',
                'badgeIcon'   => 'fas fa-gauge-high',
                'themeClass'  => 'theme-429',
            ],

            // ── 5xx (server errors) ───────────────────────────────────────────
            500 => [
                'title'       => 'Internal Server Error',
                'description' => 'Something went wrong on our end. Our team has been notified and is working to fix the issue. Please try again in a few moments.',
                'icon'        => 'fas fa-server',
                'badgeIcon'   => 'fas fa-circle-exclamation',
                'themeClass'  => 'theme-5xx',
                'iconPulse'   => 'icon-pulse',
            ],
            501 => [
                'title'       => 'Not Implemented',
                'description' => 'The server does not support the functionality required to fulfil this request. This feature may not yet be available.',
                'icon'        => 'fas fa-code',
                'badgeIcon'   => 'fas fa-code',
                'themeClass'  => 'theme-5xx',
            ],
            502 => [
                'title'       => 'Bad Gateway',
                'description' => 'The server received an invalid response from an upstream server. This is usually a temporary issue — please try again shortly.',
                'icon'        => 'fas fa-plug-circle-xmark',
                'badgeIcon'   => 'fas fa-plug-circle-xmark',
                'themeClass'  => 'theme-5xx',
                'iconPulse'   => 'icon-pulse',
            ],
            503 => [
                'title'       => 'Service Unavailable',
                'description' => 'The service is temporarily unavailable, possibly due to maintenance or high traffic. Please try again in a few minutes.',
                'icon'        => 'fas fa-wrench',
                'badgeIcon'   => 'fas fa-wrench',
                'themeClass'  => 'theme-5xx',
                'iconPulse'   => 'icon-pulse',
            ],
            504 => [
                'title'       => 'Gateway Timeout',
                'description' => 'The server did not receive a timely response from an upstream server. Please check your connection and try again.',
                'icon'        => 'fas fa-hourglass-end',
                'badgeIcon'   => 'fas fa-hourglass-end',
                'themeClass'  => 'theme-5xx',
                'iconPulse'   => 'icon-pulse',
            ],
            505 => [
                'title'       => 'HTTP Version Not Supported',
                'description' => 'The server does not support the HTTP protocol version used in the request. Please try using a modern browser.',
                'icon'        => 'fas fa-code-branch',
                'badgeIcon'   => 'fas fa-code-branch',
                'themeClass'  => 'theme-5xx',
            ],

            // ── Cloudflare-specific errors ────────────────────────────────────
            520 => [
                'title'       => 'Unknown Error',
                'description' => 'The origin server returned an unexpected or empty response. This is a Cloudflare-reported issue. Please try again or contact support if the problem persists.',
                'icon'        => 'fas fa-cloud-bolt',
                'badgeIcon'   => 'fas fa-cloud-bolt',
                'themeClass'  => 'theme-cf',
                'iconPulse'   => 'icon-pulse',
            ],
            525 => [
                'title'       => 'SSL Handshake Failed',
                'description' => 'Cloudflare could not complete an SSL/TLS handshake with the origin server. This is a network-level issue — please try again shortly.',
                'icon'        => 'fas fa-shield-halved',
                'badgeIcon'   => 'fas fa-shield-halved',
                'themeClass'  => 'theme-cf',
            ],
            526 => [
                'title'       => 'Invalid SSL Certificate',
                'description' => 'Cloudflare could not validate the SSL certificate on the origin server. Our team has been notified. Please try again later.',
                'icon'        => 'fas fa-certificate',
                'badgeIcon'   => 'fas fa-certificate',
                'themeClass'  => 'theme-cf',
            ],
        ];
    }

    // ─────────────────────────────────────────────────────────────────────────
    // View data builder
    // ─────────────────────────────────────────────────────────────────────────

    /**
     * Build the complete array of variables passed to errors/error.blade.php.
     */
    public static function buildViewData(
        int $statusCode,
        bool $isDashboard,
        HttpExceptionInterface $exception,
        Request $request
    ): array {
        $definitions = self::definitions();

        // Use the specific definition if available, otherwise fall back to
        // a generic definition based on the error category (4xx / 5xx).
        if (isset($definitions[$statusCode])) {
            $def = $definitions[$statusCode];
        } elseif ($statusCode >= 500) {
            $def = $definitions[500];
        } elseif ($statusCode >= 400) {
            $def = $definitions[400];
        } elseif ($statusCode >= 300) {
            $def = $definitions[301];
        } else {
            $def = [
                'title'       => 'Error ' . $statusCode,
                'description' => 'An unexpected error occurred. Please try again or contact support.',
                'icon'        => 'fas fa-circle-exclamation',
                'badgeIcon'   => 'fas fa-circle-exclamation',
                'themeClass'  => 'theme-5xx',
            ];
        }

        // Allow the exception message to override the description when it is
        // a meaningful, user-facing string (not a raw PHP exception message).
        $exceptionMessage = $exception->getMessage();
        if (
            $exceptionMessage
            && strlen($exceptionMessage) < 300
            && !str_contains($exceptionMessage, '\\')
            && !str_contains($exceptionMessage, '::')
        ) {
            $def['description'] = $exceptionMessage;
        }

        // Extract Retry-After header for 429 responses
        $retryAfter = 60;
        if ($statusCode === 429) {
            $headers = $exception->getHeaders();
            if (isset($headers['Retry-After'])) {
                $retryAfter = (int) $headers['Retry-After'];
            }
        }

        return [
            'statusCode'       => $statusCode,
            'errorTitle'       => $def['title'],
            'errorDescription' => $def['description'],
            'errorIcon'        => $def['icon'],
            'badgeIcon'        => $def['badgeIcon'],
            'themeClass'       => $def['themeClass'],
            'iconPulse'        => $def['iconPulse'] ?? '',
            'isDashboard'      => $isDashboard,
            'retryAfter'       => $retryAfter,
            'requestPath'      => $request->path(),
        ];
    }
}
