<?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\TicketBundle\Tests\Action\Ticket\Handler;

use Chill\MainBundle\Phonenumber\PhonenumberHelper;
use Chill\PersonBundle\Entity\Person;
use Chill\PersonBundle\Repository\PersonACLAwareRepositoryInterface;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Chill\ThirdPartyBundle\Repository\ThirdPartyRepository;
use Chill\TicketBundle\Action\Ticket\AssociateByPhonenumberCommand;
use Chill\TicketBundle\Action\Ticket\Handler\AssociateByPhonenumberCommandHandler;
use Chill\TicketBundle\Entity\Ticket;
use Doctrine\ORM\EntityManagerInterface;
use libphonenumber\PhoneNumber;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Psr\Log\NullLogger;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
use Symfony\Component\Clock\MockClock;
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;

/**
 * @internal
 *
 * @coversNothing
 */
class AssociateByPhonenumberCommandHandlerTest extends TestCase
{
    use ProphecyTrait;

    private function getHandler(
        PersonACLAwareRepositoryInterface $personACLAwareRepository,
        ThirdPartyRepository $thirdPartyRepository,
    ): AssociateByPhonenumberCommandHandler {
        $entityManager = $this->prophesize(EntityManagerInterface::class);
        $phonenumberHelper = new PhonenumberHelper(
            new ArrayAdapter(),
            new ParameterBag([
                'chill_main.phone_helper' => [
                    'default_carrier_code' => 'BE',
                ],
            ]),
            new NullLogger()
        );

        return new AssociateByPhonenumberCommandHandler(
            $personACLAwareRepository,
            $thirdPartyRepository,
            $phonenumberHelper,
            new MockClock(),
            $entityManager->reveal()
        );
    }

    public function testHandleWithPersonFoundByPhonenumber(): void
    {
        $person = new Person();

        $personAclAwareRepository = $this->prophesize(PersonACLAwareRepositoryInterface::class);
        $personAclAwareRepository->findByPhone(Argument::any())->willReturn([$person]);
        $thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class);
        $thirdPartyRepository->findByPhonenumber(Argument::type(PhoneNumber::class))->willReturn([]);

        $handler = $this->getHandler($personAclAwareRepository->reveal(), $thirdPartyRepository->reveal());

        $ticket = new Ticket();
        $handler($ticket, new AssociateByPhonenumberCommand('+3281136917'));

        self::assertSame($person, $ticket->getCaller());
    }

    public function testHandleWithThirdPartyFoundByPhonenumber(): void
    {
        $personAclAwareRepository = $this->prophesize(PersonACLAwareRepositoryInterface::class);
        $personAclAwareRepository->findByPhone(Argument::any())->willReturn([]);
        $thirdPartyRepository = $this->prophesize(ThirdPartyRepository::class);
        $thirdPartyRepository->findByPhonenumber(Argument::type(PhoneNumber::class))->willReturn([$thirdParty = new ThirdParty()]);

        $handler = $this->getHandler($personAclAwareRepository->reveal(), $thirdPartyRepository->reveal());

        $ticket = new Ticket();
        $handler($ticket, new AssociateByPhonenumberCommand('081136917'));

        self::assertSame($thirdParty, $ticket->getCaller());
    }
}
