<?php

namespace Tests\Feature\Models;

use Illuminate\Http\Request;
use Illuminate\Routing\Route;
use Mtc\MercuryDataModels\ApiUsageEndpoint;
use Tests\DatabaseTestCase;

class ApiUsageEndpointTest extends DatabaseTestCase
{
    protected bool $needsTenantDatabase = false;

    protected function setUp(): void
    {
        parent::setUp();
        ApiUsageEndpoint::clearIdCache();
    }

    public function testFromRequestUsesMatchedRouteUriPattern(): void
    {
        $this->assertSame(
            'frontend/vehicles/{vehicle}',
            ApiUsageEndpoint::fromRequest($this->requestForRoute('frontend/vehicles/{vehicle}'))
        );
    }

    public function testDifferentConcreteUrlsCollapseToTheSameEndpointKey(): void
    {
        $first = ApiUsageEndpoint::fromRequest($this->requestForRoute('frontend/vehicles/{vehicle}'));
        $second = ApiUsageEndpoint::fromRequest($this->requestForRoute('frontend/vehicles/{vehicle}'));

        $this->assertSame($first, $second);
    }

    public function testFromRequestFallsBackToPathWhenNoRouteMatched(): void
    {
        $request = Request::create('/frontend/vehicles/ford-focus-2024', 'GET');

        $this->assertSame('frontend/vehicles/ford-focus-2024', ApiUsageEndpoint::fromRequest($request));
    }

    public function testResolveIdIsIdempotentAndCreatesOneRow(): void
    {
        $id = ApiUsageEndpoint::resolveId('frontend/offers/{offer}');

        // Clear the cache so the second call has to hit the database again.
        ApiUsageEndpoint::clearIdCache();
        $again = ApiUsageEndpoint::resolveId('frontend/offers/{offer}');

        $this->assertSame($id, $again);
        $this->assertSame(1, ApiUsageEndpoint::query()->where('endpoint', 'frontend/offers/{offer}')->count());
    }

    public function testResolveIdReturnsNullForEmptyEndpoint(): void
    {
        $this->assertNull(ApiUsageEndpoint::resolveId(null));
        $this->assertNull(ApiUsageEndpoint::resolveId(''));
    }

    private function requestForRoute(string $uri): Request
    {
        $route = new Route('GET', $uri, []);
        $request = Request::create('/' . str_replace(['{', '}'], '', $uri), 'GET');
        $request->setRouteResolver(fn () => $route);

        return $request;
    }
}
