<?php

declare(strict_types=1);

/*
 * This file is part of the Ferienpass package.
 *
 * (c) Richard Henkenjohann <richard@ferienpass.online>
 *
 * For more information visit the project website <https://ferienpass.online>
 * or the documentation under <https://docs.ferienpass.online>.
 */

namespace Ferienpass\CmsBundle\Tests\Twig\Extension;

use Contao\PageModel;
use Ferienpass\CmsBundle\Translation\DeeplTranslator;
use Ferienpass\CmsBundle\Twig\Extension\MachineTranslationExtension;
use PHPUnit\Framework\Attributes\AllowMockObjectsWithoutExpectations;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

#[AllowMockObjectsWithoutExpectations]
class MachineTranslationExtensionTest extends TestCase
{
    public function testMachineTranslateReturnsEmptyStringForEmptyContent(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('', $extension->machineTranslate(''));
        $this->assertSame('', $extension->machineTranslate(null));
    }

    public function testMachineTranslateReturnsContentWhenNoRequest(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $requestStack->method('getCurrentRequest')->willReturn(null);

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('some content', $extension->machineTranslate('some content'));
    }

    public function testMachineTranslateReturnsContentWhenLocaleIsGerman(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $request = new Request();
        $request->setLocale('de');
        $requestStack->method('getCurrentRequest')->willReturn($request);

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('some content', $extension->machineTranslate('some content'));
    }

    public function testMachineTranslateSuccess(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $request = new Request();
        $request->setLocale('en');

        $pageModel = $this->getMockBuilder(PageModel::class)
            ->disableOriginalConstructor()
            ->getMock();
        $pageModel->method('__get')->willReturnMap([['rootLanguage', 'de']]);

        $request->attributes->set('pageModel', $pageModel);
        $requestStack->method('getCurrentRequest')->willReturn($request);

        $translator->method('getTargetLang')->willReturn('EN-US');
        $translator->method('translate')->willReturn('translated content');

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('translated content', $extension->machineTranslate('some content'));
    }

    public function testMachineTranslateReturnsContentOnFailure(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $request = new Request();
        $request->setLocale('en');

        $pageModel = $this->getMockBuilder(PageModel::class)
            ->disableOriginalConstructor()
            ->getMock();
        $pageModel->method('__get')->willReturnMap([['rootLanguage', 'de']]);

        $request->attributes->set('pageModel', $pageModel);
        $requestStack->method('getCurrentRequest')->willReturn($request);

        $translator->method('getTargetLang')->willReturn('EN-US');
        $translator->method('translate')->willReturn(null);

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('some content', $extension->machineTranslate('some content'));
    }

    public function testMachineTranslateSkipsWhenLocaleMatchesPageLanguage(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $request = new Request();
        $request->setLocale('en');

        $pageModel = $this->getMockBuilder(PageModel::class)
            ->disableOriginalConstructor()
            ->getMock();
        $pageModel->method('__get')->willReturnMap([['rootLanguage', 'en']]);

        $request->attributes->set('pageModel', $pageModel);
        $requestStack->method('getCurrentRequest')->willReturn($request);

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('some content', $extension->machineTranslate('some content'));
    }

    public function testMachineTranslateTranslatesWhenLocaleDiffersFromPageLanguage(): void
    {
        $translator = $this->createStub(DeeplTranslator::class);
        $requestStack = $this->createStub(RequestStack::class);
        $request = new Request();
        $request->setLocale('en');

        $pageModel = $this->getMockBuilder(PageModel::class)
            ->disableOriginalConstructor()
            ->getMock();
        $pageModel->method('__get')->willReturnMap([['rootLanguage', 'de']]);

        $request->attributes->set('pageModel', $pageModel);
        $requestStack->method('getCurrentRequest')->willReturn($request);

        $translator->method('getTargetLang')->willReturn('EN-US');
        $translator->method('translate')->willReturn('translated content');

        $extension = new MachineTranslationExtension($translator, $requestStack);

        $this->assertSame('translated content', $extension->machineTranslate('some content'));
    }
}
