<?php

declare(strict_types=1);

namespace Ferienpass\AdminBundle\Tests\Controller\Page;

use Ferienpass\AdminBundle\Controller\Page\OffersController;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Routing\Attribute\Route;

final class OffersControllerTest extends TestCase
{
    public function testClassRoutePrefix(): void
    {
        $ref = new \ReflectionClass(OffersController::class);
        $attrs = $ref->getAttributes(Route::class);

        self::assertCount(1, $attrs);
        self::assertSame('/angebote', $attrs[0]->newInstance()->getPath());
    }

    
    #[DataProvider('expectedRouteNamesProvider')]
    
    public function testRouteNameExists(string $routeName): void
    {
        $ref = new \ReflectionClass(OffersController::class);
        $routeNames = $this->collectRouteNames($ref);

        self::assertContains($routeName, $routeNames, \sprintf('Route "%s" should exist in OffersController', $routeName));
    }

    public static function expectedRouteNamesProvider(): iterable
    {
        yield 'offers index' => ['admin_offers_index'];
        yield 'offers export' => ['admin_offers_export'];
        yield 'offers show' => ['admin_offers_show'];
        yield 'offers new' => ['admin_offers_new'];
        yield 'offers proof' => ['admin_offers_proof'];
        yield 'offers complete' => ['admin_offers_complete'];
        yield 'offers duplicate' => ['admin_offers_duplicate'];
        yield 'offers delete' => ['admin_offers_delete'];
        yield 'offers cancel' => ['admin_offers_cancel'];
        yield 'offers relaunch' => ['admin_offers_relaunch'];
        yield 'offers apply' => ['admin_offers_apply'];
        yield 'offers reorder' => ['admin_offers_reorder'];
        yield 'offers increase seats' => ['admin_offers_increase_seats'];
        yield 'offers variants' => ['admin_offers_variants'];
    }

    public function testControllerIsFinal(): void
    {
        $ref = new \ReflectionClass(OffersController::class);
        self::assertTrue($ref->isFinal());
    }

    private function collectRouteNames(\ReflectionClass $ref): array
    {
        $routeNames = [];
        foreach ($ref->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
            foreach ($method->getAttributes(Route::class) as $attr) {
                $route = $attr->newInstance();
                if (null !== $route->getName()) {
                    $routeNames[] = $route->getName();
                }
            }
        }

        return $routeNames;
    }
}
