<?php

declare(strict_types=1);

namespace App\Support;

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;

/**
 * 识别 Livewire 组件更新与前端资源请求（Livewire 3/4、子目录部署路径差异集中在此）。
 */
final class DberpLivewireRequest
{
    /**
     * Livewire 4 默认路由名（见 `php artisan route:list --path=livewire`）。
     */
    public const LIVEWIRE_UPDATE_ROUTE_NAME = 'default-livewire.update';

    public static function isComponentUpdateRequest(Request $request): bool
    {
        if ($request->routeIs(self::LIVEWIRE_UPDATE_ROUTE_NAME, 'livewire.update')) {
            return true;
        }

        return self::pathIsComponentUpdate(trim($request->path(), '/'));
    }

    public static function isFrontendAssetRequest(Request $request): bool
    {
        if (! in_array($request->method(), ['GET', 'HEAD'], true)) {
            return false;
        }

        $path = self::normalizePath($request->path());

        if ($path === '') {
            return false;
        }

        return (bool) preg_match('#(?:^|/)livewire(?:-[a-z0-9]+)?/(?:livewire(?:\.min)?\.js|css/|js/)#', $path);
    }

    /**
     * @return list<string> 带前导斜杠的 URI，供测试与运维核对
     */
    public static function registeredUpdateUris(): array
    {
        $uris = [];

        $route = Route::getRoutes()->getByName(self::LIVEWIRE_UPDATE_ROUTE_NAME);

        if ($route !== null) {
            $uris[] = '/'.ltrim((string) $route->uri(), '/');
        }

        $legacy = Route::getRoutes()->getByName('livewire.update');

        if ($legacy !== null) {
            $uri = '/'.ltrim((string) $legacy->uri(), '/');

            if (! in_array($uri, $uris, true)) {
                $uris[] = $uri;
            }
        }

        if ($uris === []) {
            $uris[] = '/livewire/update';
        }

        return $uris;
    }

    public static function pathIsComponentUpdate(string $path): bool
    {
        $normalized = self::normalizePath($path);

        if ($normalized === '') {
            return false;
        }

        return (bool) preg_match('#(?:^|/)livewire(?:-[a-z0-9]+)?/update$#', $normalized);
    }

    private static function normalizePath(string $path): string
    {
        return trim(str_replace('\\', '/', $path), '/');
    }
}
