<?php

namespace App\Tests\Controller;

use App\Controller\UnsubscribeController;
use App\Service\UnsubscribeManager;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
use Symfony\Component\Routing\RouterInterface;
use Twig\Environment;

class UnsubscribeControllerTest extends TestCase
{
    private function buildController(): UnsubscribeController
    {
        $session = new Session(new MockArraySessionStorage());
        $stack = $this->createStub(RequestStack::class);
        $stack->method('getSession')->willReturn($session);

        $twig = $this->createStub(Environment::class);
        $twig->method('render')->willReturn('<html></html>');

        $router = $this->createStub(RouterInterface::class);
        $router->method('generate')->willReturn('/some/path');

        $container = $this->createStub(ContainerInterface::class);
        $container->method('has')->willReturn(true);
        $container->method('get')->willReturnMap([
            ['twig', $twig],
            ['router', $router],
            ['request_stack', $stack],
        ]);

        $controller = new UnsubscribeController();
        $controller->setContainer($container);

        return $controller;
    }

    public function testInvalidTokenRendersInvalidTemplate(): void
    {
        $manager = $this->createStub(UnsubscribeManager::class);
        $manager->method('isValidToken')->willReturn(false);

        $controller = $this->buildController();
        $response = $controller->__invoke('test@example.com', 'invalid-token', $manager);

        $this->assertSame(200, $response->getStatusCode());
    }

    public function testValidTokenUnsubscribesAndRendersSuccessTemplate(): void
    {
        $manager = $this->createMock(UnsubscribeManager::class);
        $manager->method('isValidToken')->willReturn(true);
        $manager->expects($this->once())->method('unsubscribe')->with('test@example.com');

        $controller = $this->buildController();
        $response = $controller->__invoke('test@example.com', 'valid-token', $manager);

        $this->assertSame(200, $response->getStatusCode());
    }
}
