<?php

namespace Tests\Feature\Api\V1\FullSurface;

use Illuminate\Support\Facades\Route;
use Tests\Feature\Api\V1\FullSurface\Support\FullSurfaceE2EContractCase;

class ApiClientCompatibilityVersioningContractTest extends FullSurfaceE2EContractCase
{
    public function test_publicly_registered_api_routes_remain_versioned_or_explicitly_legacy(): void
    {
        $allowedUnversioned = [
            'api/login', 'api/logout', 'api/user', 'api/register', 'api/forgot-password', 'api/reset-password',
            'api/docs', 'api/health', 'api/db-check', 'api/badge-scan', 'api/scanner',
        ];

        foreach ($this->apiRoutes() as $route) {
            $uri = $route->uri();
            if (str_starts_with($uri, 'api/v1/')) {
                $this->assertTrue(true);
                continue;
            }

            $isAllowed = false;
            foreach ($allowedUnversioned as $allowed) {
                if (str_starts_with($uri, $allowed)) {
                    $isAllowed = true;
                    break;
                }
            }

            $this->assertTrue(
                $isAllowed,
                $uri . ' is an unversioned API route. If this is deliberate legacy support, add it to the explicit allow-list.'
            );
        }
    }

    public function test_route_names_are_unique_enough_for_client_generation(): void
    {
        $seen = [];
        foreach (Route::getRoutes()->getRoutes() as $route) {
            $name = $route->getName();
            if ($name === null || ! str_starts_with($route->uri(), 'api/')) {
                continue;
            }

            $key = $name . '|' . $this->primaryMethod($route);
            $this->assertArrayNotHasKey($key, $seen, 'Duplicate API route name/method pair: ' . $key . ' for ' . $route->uri() . ' and ' . ($seen[$key] ?? 'unknown'));
            $seen[$key] = $route->uri();
        }
    }

    public function test_legacy_and_current_auth_contracts_return_compatible_failure_shapes(): void
    {
        $pairs = [
            ['/api/login', '/api/v1/auth/login'],
            ['/user/login', '/api/v1/auth/login'],
        ];

        foreach ($pairs as [$legacy, $current]) {
            $legacyResponse = $this->postJson($legacy, ['email' => 'bad@example.test', 'password' => 'wrong']);
            $currentResponse = $this->postJson($current, ['email' => 'bad@example.test', 'password' => 'wrong']);

            $this->assertNoServerError($legacyResponse, $legacy . ' legacy auth failure');
            $this->assertNoServerError($currentResponse, $current . ' current auth failure');
            $this->assertStatusIn($legacyResponse, [400, 401, 403, 419, 422], $legacy . ' legacy auth failure');
            $this->assertStatusIn($currentResponse, [400, 401, 403, 419, 422], $current . ' current auth failure');
        }
    }
}
