<?php

declare(strict_types=1);

use App\Framework\Router\AdminRoutes;
use App\Framework\Router\ApiRoutes;
use App\Framework\Router\HealthRoutes;
use App\Framework\Router\MediaRoutes;
use App\Framework\Router\RouteHelper;
use App\Framework\Router\UrlGenerator;
use App\Framework\Router\WebRoutes;

describe('RouteHelper', function () {
    beforeEach(function () {
        $this->mockUrlGenerator = mock(UrlGenerator::class);
        $this->routeHelper = new RouteHelper($this->mockUrlGenerator);
    });

    describe('web routes', function () {
        it('generates web route URLs correctly', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(WebRoutes::HOME, [], false)
                ->andReturn('/');

            $result = $this->routeHelper->web(WebRoutes::HOME);

            expect($result)->toBe('/');
        });

        it('generates absolute web route URLs', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(WebRoutes::HOME, [], true)
                ->andReturn('https://example.com/');

            $result = $this->routeHelper->absoluteWeb(WebRoutes::HOME);

            expect($result)->toBe('https://example.com/');
        });

        it('passes parameters correctly', function () {
            $params = ['id' => 123];

            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(WebRoutes::CONTACT, $params, false)
                ->andReturn('/contact?id=123');

            $result = $this->routeHelper->web(WebRoutes::CONTACT, $params);

            expect($result)->toBe('/contact?id=123');
        });
    });

    describe('API routes', function () {
        it('generates API route URLs correctly', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(ApiRoutes::USERS_LIST, [], false)
                ->andReturn('/api/users');

            $result = $this->routeHelper->api(ApiRoutes::USERS_LIST);

            expect($result)->toBe('/api/users');
        });

        it('generates absolute API route URLs', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(ApiRoutes::USERS_LIST, [], true)
                ->andReturn('https://api.example.com/api/users');

            $result = $this->routeHelper->absoluteApi(ApiRoutes::USERS_LIST);

            expect($result)->toBe('https://api.example.com/api/users');
        });
    });

    describe('admin routes', function () {
        it('generates admin route URLs correctly', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(AdminRoutes::DASHBOARD, [], false)
                ->andReturn('/admin');

            $result = $this->routeHelper->admin(AdminRoutes::DASHBOARD);

            expect($result)->toBe('/admin');
        });

        it('generates absolute admin route URLs', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(AdminRoutes::DASHBOARD, [], true)
                ->andReturn('https://admin.example.com/admin');

            $result = $this->routeHelper->absoluteAdmin(AdminRoutes::DASHBOARD);

            expect($result)->toBe('https://admin.example.com/admin');
        });
    });

    describe('health routes', function () {
        it('generates health route URLs correctly', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(HealthRoutes::HEALTH_CHECK, [], false)
                ->andReturn('/health');

            $result = $this->routeHelper->health(HealthRoutes::HEALTH_CHECK);

            expect($result)->toBe('/health');
        });
    });

    describe('media routes', function () {
        it('generates media route URLs correctly', function () {
            $params = ['filename' => 'test.jpg'];

            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(MediaRoutes::SHOW_IMAGE, $params, false)
                ->andReturn('/images/test.jpg');

            $result = $this->routeHelper->media(MediaRoutes::SHOW_IMAGE, $params);

            expect($result)->toBe('/images/test.jpg');
        });
    });

    describe('generic route handling', function () {
        it('generates URLs for any RouteNameInterface', function () {
            $this->mockUrlGenerator->shouldReceive('route')
                ->once()
                ->with(WebRoutes::HOME, [], false)
                ->andReturn('/');

            $result = $this->routeHelper->any(WebRoutes::HOME);

            expect($result)->toBe('/');
        });
    });

    describe('current route checking', function () {
        it('checks if current route matches web route', function () {
            $this->mockUrlGenerator->shouldReceive('isCurrentRoute')
                ->once()
                ->with(WebRoutes::HOME)
                ->andReturn(true);

            $result = $this->routeHelper->isCurrentWeb(WebRoutes::HOME);

            expect($result)->toBeTrue();
        });

        it('checks if current route matches API route', function () {
            $this->mockUrlGenerator->shouldReceive('isCurrentRoute')
                ->once()
                ->with(ApiRoutes::USERS_LIST)
                ->andReturn(false);

            $result = $this->routeHelper->isCurrentApi(ApiRoutes::USERS_LIST);

            expect($result)->toBeFalse();
        });

        it('checks if current route matches admin route', function () {
            $this->mockUrlGenerator->shouldReceive('isCurrentRoute')
                ->once()
                ->with(AdminRoutes::DASHBOARD)
                ->andReturn(true);

            $result = $this->routeHelper->isCurrentAdmin(AdminRoutes::DASHBOARD);

            expect($result)->toBeTrue();
        });

        it('checks if current route matches any route', function () {
            $this->mockUrlGenerator->shouldReceive('isCurrentRoute')
                ->once()
                ->with(HealthRoutes::HEALTH_CHECK)
                ->andReturn(false);

            $result = $this->routeHelper->isCurrent(HealthRoutes::HEALTH_CHECK);

            expect($result)->toBeFalse();
        });
    });
});
