<?php

namespace Tests\Feature;

use App\Domain\Shared\Context\BranchContext;
use Illuminate\Support\Facades\Route;
use Tests\TestCase;

/**
 * The branch lock names its destination in config, but the cross-branch view
 * it points at is not built yet. route() throws on an undefined name, so every
 * caller that navigates — rather than merely gates — must resolve the target
 * through BranchContext instead of reading the config key raw.
 */
class BranchLockRedirectTest extends TestCase
{
    public function test_redirect_target_is_always_a_defined_route(): void
    {
        $name = app(BranchContext::class)->redirectRouteName();

        $this->assertTrue(
            Route::has($name),
            "Branch-lock redirect target [{$name}] is not a defined route; route() would throw."
        );
    }

    public function test_redirect_target_degrades_to_the_dashboard_while_unbuilt(): void
    {
        config(['branch_lock.redirect_route' => 'executive.not-built-yet']);

        $this->assertSame('dashboard', app(BranchContext::class)->redirectRouteName());
    }

    public function test_redirect_target_honours_the_configured_route_once_it_exists(): void
    {
        Route::get('/__executive-probe', fn () => '')->name('executive.probe');
        // ->name() is applied after the route is added, so the router's name
        // lookup has to be rebuilt before Route::has() can see it.
        Route::getRoutes()->refreshNameLookups();
        config(['branch_lock.redirect_route' => 'executive.probe']);

        $this->assertSame('executive.probe', app(BranchContext::class)->redirectRouteName());
    }

    public function test_lock_stays_dormant_while_its_destination_is_missing(): void
    {
        config(['branch_lock.redirect_route' => 'executive.not-built-yet']);

        $this->assertFalse(app(BranchContext::class)->isLocked());
    }

    public function test_no_caller_reads_the_redirect_route_key_directly(): void
    {
        $offenders = [];

        foreach (['app/Livewire', 'app/Http/Middleware'] as $dir) {
            $files = new \RecursiveIteratorIterator(
                new \RecursiveDirectoryIterator(base_path($dir))
            );

            foreach ($files as $file) {
                if ($file->getExtension() !== 'php') {
                    continue;
                }

                if (str_contains(file_get_contents($file->getPathname()), "branch_lock.redirect_route")) {
                    $offenders[] = str_replace(base_path().'/', '', $file->getPathname());
                }
            }
        }

        $this->assertSame(
            [],
            $offenders,
            'These read branch_lock.redirect_route directly instead of BranchContext::redirectRouteName(): '
                .implode(', ', $offenders)
        );
    }
}
