<?php

declare(strict_types=1);

namespace TekDek\Employees\Tests;

use PHPUnit\Framework\TestCase;
use TekDek\Employees\EmployeeController;
use TekDek\Employees\Router;

/**
 * Tests for Router dispatch logic.
 *
 * Note: These tests manipulate $_SERVER globals. In a real CI environment,
 * integration tests via HTTP requests are recommended alongside these.
 */
class RouterTest extends TestCase
{
    private function mockRequest(string $method, string $uri): void
    {
        $_SERVER['REQUEST_METHOD'] = $method;
        $_SERVER['REQUEST_URI'] = $uri;
    }

    private function captureDispatch(?EmployeeController $controller = null): string
    {
        ob_start();
        // Suppress header warnings in CLI test context
        @Router::dispatch($controller);
        return ob_get_clean();
    }

    public function testGetEmployeesRoutesToIndex(): void
    {
        $this->mockRequest('GET', '/api/employees');

        $controller = $this->createMock(EmployeeController::class);
        $controller->expects($this->once())->method('index');
        $controller->expects($this->never())->method('show');

        $this->captureDispatch($controller);
    }

    public function testGetEmployeesTrailingSlash(): void
    {
        $this->mockRequest('GET', '/api/employees/');

        $controller = $this->createMock(EmployeeController::class);
        $controller->expects($this->once())->method('index');

        $this->captureDispatch($controller);
    }

    public function testGetEmployeeBySlugRoutesToShow(): void
    {
        $this->mockRequest('GET', '/api/employees/talos');

        $controller = $this->createMock(EmployeeController::class);
        $controller->expects($this->once())->method('show')->with('talos');

        $this->captureDispatch($controller);
    }

    public function testPostMethodReturns405(): void
    {
        $this->mockRequest('POST', '/api/employees');

        $output = $this->captureDispatch();
        $json = json_decode($output, true);

        $this->assertFalse($json['success']);
        $this->assertStringContainsString('Method not allowed', $json['error']);
    }

    public function testOptionsReturnsCorsHeaders(): void
    {
        $this->mockRequest('OPTIONS', '/api/employees');
        $output = $this->captureDispatch();
        // OPTIONS should return empty body
        $this->assertEmpty($output);
    }

    public function testUnknownRouteReturns404(): void
    {
        $this->mockRequest('GET', '/api/unknown');

        $output = $this->captureDispatch();
        $json = json_decode($output, true);

        $this->assertFalse($json['success']);
        $this->assertStringContainsString('not found', $json['error']);
    }

    public function testSlugWithQueryString(): void
    {
        $this->mockRequest('GET', '/api/employees/daedalus?format=full');

        $controller = $this->createMock(EmployeeController::class);
        $controller->expects($this->once())->method('show')->with('daedalus');

        $this->captureDispatch($controller);
    }
}
