<?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\Repository;

use Chill\PersonBundle\Entity\Person;
use Chill\ThirdPartyBundle\Entity\ThirdParty;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\ORM\Query\ResultSetMappingBuilder;

final readonly class PersonTicketACLAwareRepository implements PersonTicketACLAwareRepositoryInterface
{
    public function __construct(private EntityManagerInterface $em) {}

    public function findPersonPreviouslyAssociatedWithCaller(Person|ThirdParty $caller, int $start = 0, int $limit = 100): array
    {
        $resultSetMappingBuilder = new ResultSetMappingBuilder($this->em);
        $resultSetMappingBuilder->addRootEntityFromClassMetadata(Person::class, 'p');

        $callerClause = match ($caller instanceof Person) {
            true => 'caller_history.person_id = :callerId',
            false => 'caller_history.thirdparty_id = :callerId',
        };

        $query = <<<SQL
        SELECT DISTINCT {$resultSetMappingBuilder->generateSelectClause()} FROM chill_person_person p
        WHERE p.id IN (
            SELECT person_id
            FROM chill_ticket.person_history person_history
            WHERE person_history.endDate IS NULL
              AND EXISTS (
                SELECT 1 FROM chill_ticket.caller_history
                WHERE
                    caller_history.ticket_id = person_history.ticket_id
                  AND caller_history.endDate IS NULL
                  AND {$callerClause}
            )
            ORDER BY person_history.startDate DESC, p.id ASC
        )
        OFFSET :start LIMIT :limit;
        SQL;

        $nql = $this->em->createNativeQuery($query, $resultSetMappingBuilder);
        $nql
            ->setParameter('callerId', $caller->getId())
            ->setParameter('start', $start)
            ->setParameter('limit', $limit);


        return $nql->getResult();
    }
}
