<?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 Services\RollingDate;

use Chill\MainBundle\Service\RollingDate\RollingDate;
use Chill\MainBundle\Service\RollingDate\RollingDateConverter;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Clock\MockClock;

/**
 * @internal
 *
 * @coversNothing
 */
final class RollingDateConverterTest extends TestCase
{
    private function buildConverter(\DateTimeImmutable|string $pivot = 'now'): RollingDateConverter
    {
        return new RollingDateConverter(new MockClock($pivot));
    }

    public function testConversionFixedDate()
    {
        $rollingDate = new RollingDate(RollingDate::T_FIXED_DATE, new \DateTimeImmutable('2022-01-01'));

        $this->assertEquals(
            '2022-01-01',
            $this->buildConverter()->convert($rollingDate)->format('Y-m-d')
        );
    }

    public function testConvertOnDateNow()
    {
        $rollingDate = new RollingDate(RollingDate::T_YEAR_PREVIOUS_START);

        $actual = $this->buildConverter()->convert($rollingDate);

        $this->assertEquals(
            (int) (new \DateTimeImmutable('now'))->format('Y') - 1,
            (int) $actual->format('Y')
        );
        $this->assertEquals(1, (int) $actual->format('m'));
        $this->assertEquals(1, (int) $actual->format('d'));
    }

    /**
     * @dataProvider generateDataConversionDate
     */
    public function testConvertOnPivotDate(string $roll, string $expectedDateTime, string $format)
    {
        $pivot = \DateTimeImmutable::createFromFormat('Y-m-d His', '2022-11-07 000000');
        $rollingDate = new RollingDate($roll, null, $pivot);

        $this->assertEquals(
            \DateTime::createFromFormat($format, $expectedDateTime),
            $this->buildConverter()->convert($rollingDate)
        );
    }

    /**
     * @dataProvider generateDataConversionDate
     */
    public function testConvertOnClock(string $roll, string $expectedDateTime, string $format)
    {
        $pivot = \DateTimeImmutable::createFromFormat('Y-m-d His', '2022-11-07 000000');
        $rollingDate = new RollingDate($roll, null);

        $this->assertEquals(
            \DateTime::createFromFormat($format, $expectedDateTime),
            $this->buildConverter($pivot)->convert($rollingDate)
        );
    }

    public static function generateDataConversionDate(): iterable
    {
        $format = 'Y-m-d His';

        yield [RollingDate::T_MONTH_CURRENT_START, '2022-11-01 000000', $format];

        yield [RollingDate::T_MONTH_NEXT_START, '2022-12-01 000000', $format];

        yield [RollingDate::T_MONTH_PREVIOUS_START, '2022-10-01 000000', $format];

        yield [RollingDate::T_QUARTER_CURRENT_START, '2022-10-01 000000', $format];

        yield [RollingDate::T_QUARTER_NEXT_START, '2023-01-01 000000', $format];

        yield [RollingDate::T_QUARTER_PREVIOUS_START, '2022-07-01 000000', $format];

        yield [RollingDate::T_TODAY, '2022-11-07 000000', $format];

        yield [RollingDate::T_WEEK_CURRENT_START, '2022-11-07 000000', $format];

        yield [RollingDate::T_WEEK_NEXT_START, '2022-11-14 000000', $format];

        yield [RollingDate::T_WEEK_PREVIOUS_START, '2022-10-31 000000', $format];

        yield [RollingDate::T_YEAR_CURRENT_START, '2022-01-01 000000', $format];

        yield [RollingDate::T_YEAR_NEXT_START, '2023-01-01 000000', $format];

        yield [RollingDate::T_YEAR_PREVIOUS_START, '2021-01-01 000000', $format];
    }
}
