<?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\ReportBundle\Tests\Timeline;

use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Tests\TestHelper as MainTestHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\ReportBundle\Entity\Report;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

/**
 * Test a report is shown into timeline.
 *
 * @internal
 *
 * @coversNothing
 */
final class TimelineProviderTest extends WebTestCase
{
    private static ?object $em = null;

    private Person $person;

    /**
     * @var Report
     */
    private $report;

    /**
     * Create a person with a report associated with the person.
     */
    protected function setUp(): void
    {
        self::bootKernel();

        self::$em = self::$kernel->getContainer()
            ->get('doctrine.orm.entity_manager');

        $center = self::$em->getRepository(\Chill\MainBundle\Entity\Center::class)
            ->findOneBy(['name' => 'Center A']);

        $person = (new Person(new \DateTime('2015-05-01')))
            ->setGender(Person::FEMALE_GENDER)
            ->setFirstName('Nelson')
            ->setLastName('Mandela')
            ->setCenter($center);
        self::$em->persist($person);
        $this->person = $person;

        $scopesSocial = array_filter(
            self::$em
                ->getRepository(Scope::class)
                ->findAll(),
            static fn (Scope $scope) => 'social' === $scope->getName()['en']
        );

        $report = (new Report())
            ->setUser(self::$em->getRepository(\Chill\MainBundle\Entity\User::class)
                ->findOneByUsername('center a_social'))
            ->setDate(new \DateTime('2015-05-02'))
            ->setPerson($this->person)
            ->setCFGroup($this->getHousingCustomFieldsGroup())
            ->setCFData(['has_logement' => 'own_house',
                'house-desc' => 'blah blah', ])
            ->setScope(end($scopesSocial));

        self::$em->persist($report);
        $this->report = $report;

        self::$em->flush();
    }

    protected function tearDown(): void
    {
        // static::$em->refresh($this->person);
        // static::$em->refresh($this->report);
        // static::$em->remove($this->person);
        // static::$em->remove($this->report);
    }

    public function testReportIsNotVisibleToUngrantedUsers()
    {
        $client = self::createClient(
            [],
            MainTestHelper::getAuthenticatedClientOptions('center a_administrative')
        );

        $crawler = $client->request('GET', '/fr/person/'.$this->person->getId()
              .'/timeline');

        $this->assertEquals(
            0,
            $crawler->filter('.report_entry .summary')
                ->count(),
            'the page does not contains a .report .summary element'
        );
    }

    /**
     * Test that a report is shown in timeline.
     */
    public function testTimelineReport()
    {
        $client = self::createClient(
            [],
            MainTestHelper::getAuthenticatedClientOptions()
        );

        $crawler = $client->request('GET', '/fr/person/'.$this->person->getId()
              .'/timeline');

        $this->assertTrue(
            $client->getResponse()->isSuccessful(),
            'The page timeline is loaded successfully'
        );
        $this->assertStringContainsString(
            'a ajouté un rapport',
            $crawler->text(),
            'the page contains the text "a publié un rapport"'
        );
    }

    public function testTimelineReportWithSummaryField()
    {
        // load the page
        $client = self::createClient(
            [],
            MainTestHelper::getAuthenticatedClientOptions()
        );

        $crawler = $client->request('GET', '/fr/person/'.$this->person->getId()
              .'/timeline');

        // performs tests
        $this->assertTrue(
            $client->getResponse()->isSuccessful(),
            'The page timeline is loaded successfully'
        );
        $this->assertGreaterThan(
            0,
            $crawler->filter('.report_entry .summary')
                ->count(),
            'the page contains a .report .summary element'
        );
        $this->assertSelectorTextContains('.report_entry .summary', 'blah blah', 'the page contains the text "blah blah"');
        $this->assertSelectorTextContains('.report_entry .summary', 'Propriétaire', 'the page contains the mention "Propriétaire"');
    }

    /**
     * get a random custom fields group.
     *
     * @return \Chill\CustomFieldsBundle\Entity\CustomFieldsGroup
     */
    private function getHousingCustomFieldsGroup()
    {
        $groups = self::$em
            ->getRepository(\Chill\CustomFieldsBundle\Entity\CustomFieldsGroup::class)
            ->findAll();

        foreach ($groups as $group) {
            if ('Situation de logement' === $group->getName()['fr']) {
                return $group;
            }
        }

        return $groups[random_int(0, \count($groups) - 1)];
    }
}
