<?php

declare(strict_types=1);

/*
 * Chill is a software for social workers
 *
 * For the full copyright and license information, please view
 * the LICENSE file that was distributed with this source code.
 */

namespace Chill\MainBundle\Tests\Templating\Entity;

use Chill\MainBundle\Entity\Address;
use Chill\MainBundle\Entity\Country;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Templating\Entity\AddressRender;
use Chill\MainBundle\Templating\TranslatableStringHelper;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

/**
 * @internal
 *
 * @coversNothing
 */
final class AddressRenderTest extends KernelTestCase
{
    protected function setUp(): void
    {
        self::bootKernel();
    }

    /**
     * @dataProvider complexAddressDataProviderBE
     */
    public function testRenderComplexAddressBE(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function complexAddressDataProviderBE(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'Belgium'])
            ->setCountryCode('BE');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setBuildingName('Résidence "Les Bleuets"');
        $addr->setFlat('1');
        $addr->setFloor('2');
        $addr->setCorridor('3');
        $addr->setSteps('4');

        yield [$addr, 'Résidence "Les Bleuets" - appart 1 - ét 2 - coul 3 - esc 4 — Rue ABC, 5 — 012345 Locality — Belgium'];
    }

    /**
     * @dataProvider complexAddressDataProviderFR
     */
    public function testRenderComplexAddressFR(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function complexAddressDataProviderFR(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'France'])
            ->setCountryCode('FR');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setBuildingName('Résidence "Les Bleuets"');
        $addr->setFlat('1');
        $addr->setFloor('2');
        $addr->setCorridor('3');
        $addr->setSteps('4');
        $addr->setExtra('A droite de la porte');
        $addr->setDistribution('CEDEX');

        yield [$addr, 'appart 1 - ét 2 - coul 3 - esc 4 — Résidence "Les Bleuets" — 5, Rue ABC — A droite de la porte — 012345 Locality CEDEX — France'];
    }

    /**
     * @dataProvider noFullAddressDataProviderBE
     */
    public function testRenderNoFullAddressBE(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function noFullAddressDataProviderBE(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'Belgium'])
            ->setCountryCode('BE');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setPostcode($postCode)
            ->setIsNoAddress(true);

        yield [$addr, '012345 Locality — Belgium'];
    }

    /**
     * @dataProvider simpleAddressDataProviderBE
     */
    public function testRenderStringSimpleAddressBE(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function simpleAddressDataProviderBE(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'Belgium'])
            ->setCountryCode('BE');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        yield [$addr, 'Rue ABC, 5 — 012345 Locality — Belgium'];
    }

    /**
     * @dataProvider simpleAddressDataProviderFR
     */
    public function testRenderStringSimpleAddressFR(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function simpleAddressDataProviderFR(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'France'])
            ->setCountryCode('FR');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        yield [$addr, '5, Rue ABC — 012345 Locality — France'];
    }

    /**
     * @dataProvider addressDataProviderBEWithBuilding
     */
    public function testRenderWithBuildingAddressBE(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function addressDataProviderBEWithBuilding(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'Belgium'])
            ->setCountryCode('BE');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setBuildingName('Résidence "Les Bleuets"');

        yield [$addr, 'Résidence "Les Bleuets" — Rue ABC, 5 — 012345 Locality — Belgium'];
    }

    /**
     * @dataProvider addressDataProviderFRWithBuilding
     */
    public function testRenderWithBuildingAddressFR(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function addressDataProviderFRWithBuilding(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'France'])
            ->setCountryCode('FR');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setBuildingName('Résidence "Les Bleuets"');

        yield [$addr, 'Résidence "Les Bleuets" — 5, Rue ABC — 012345 Locality — France'];
    }

    /**
     * @dataProvider addressDataProviderBEWithSteps
     */
    public function testRenderWithStepsAddressBE(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function addressDataProviderBEWithSteps(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'Belgium'])
            ->setCountryCode('BE');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setSteps('4');

        yield [$addr, 'esc 4 — Rue ABC, 5 — 012345 Locality — Belgium'];
    }

    /**
     * @dataProvider addressDataProviderFRWithSteps
     */
    public function testRenderWithStepsAddressFR(Address $addr, string $expectedString): void
    {
        $engine = self::getContainer()->get(\Twig\Environment::class);
        $translatableStringHelper = self::getContainer()->get(TranslatableStringHelper::class);
        $renderer = new AddressRender($engine, $translatableStringHelper);

        $this->assertEquals($expectedString, $renderer->renderString($addr, []));
    }

    public static function addressDataProviderFRWithSteps(): \Iterator
    {
        $addr = new Address();
        $country = (new Country())
            ->setName(['fr' => 'France'])
            ->setCountryCode('FR');
        $postCode = new PostalCode();
        $postCode->setName('Locality')
            ->setCode('012345')
            ->setCountry($country);

        $addr->setStreet('Rue ABC')
            ->setStreetNumber('5')
            ->setPostcode($postCode);

        $addr->setSteps('4');

        yield [$addr, 'esc 4 — 5, Rue ABC — 012345 Locality — France'];
    }
}
