<?php

namespace App\Services;

use App\Models\User;
use Filament\Facades\Filament;

/**
 * Resolves where an authenticated (tenant) user should land, and whether a
 * given URL is safe for them to be redirected to. Same rule as the source
 * app (dashboard when reachable, else the first module they can access, else
 * a safe fallback that can never loop) — rebuilt against the Filament
 * Resource registry instead of the retired Inertia MenuRenderer/route tree,
 * since that's what navigation actually is now (docs/migration-plan.md).
 *
 * NOTE: until enough Resources exist across the later phases, "first
 * accessible module" only has whatever's shipped so far to choose from —
 * expected to get more useful as more modules land, not a bug.
 */
class UserLanding
{
    public static function urlFor(User $user): string
    {
        $panel = Filament::getPanel('app');

        if ($user->isFullAdmin() || $user->hasPermissionTo('dashboard.access')) {
            return static::panelHomeUrl();
        }

        foreach ($panel->getResources() as $resource) {
            if ($resource::canViewAny()) {
                return $resource::getUrl('index');
            }
        }

        // No reachable resource at all (e.g. a user with no roles): fall back
        // to the panel home. RedirectToAccessibleHome only redirects when the
        // target differs from the current path, so this can never loop —
        // worst case the user sees the dashboard's own (likely empty/403)
        // state rather than bouncing forever.
        return static::panelHomeUrl();
    }

    /**
     * The tenant panel's home URL. NOT $panel->getUrl(): with path tenancy the
     * panel path is the literal string "{workspace}/app", so
     * url(getPath()) emits "/%7Bworkspace%7D/app" — the route helper resolves
     * the parameter via URL::defaults() (set by IdentifyTenant) instead
     * (docs/path-based-tenancy-plan.md Phase 4).
     */
    private static function panelHomeUrl(): string
    {
        return route('filament.app.pages.dashboard');
    }

    /**
     * Whether the user is allowed to reach the given URL, based on which
     * Filament Resource (if any) owns that path and its canViewAny() gate.
     * Unmatched URLs are treated as unsafe so we never redirect into a 403.
     */
    public static function canAccess(User $user, string $url): bool
    {
        if ($user->isFullAdmin()) {
            return true;
        }

        $panel = Filament::getPanel('app');
        $path = parse_url($url, PHP_URL_PATH) ?: '/';

        foreach ($panel->getResources() as $resource) {
            $resourcePath = parse_url($resource::getUrl('index'), PHP_URL_PATH) ?: '';

            if ($resourcePath !== '' && str_starts_with($path, $resourcePath)) {
                return $resource::canViewAny();
            }
        }

        return true;
    }
}
