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

use Chill\MainBundle\Entity\Location;
use Chill\MainBundle\Entity\PostalCode;
use Chill\MainBundle\Entity\Scope;
use Chill\MainBundle\Entity\User;
use Chill\MainBundle\Entity\UserJob;
use Chill\PersonBundle\Entity\AccompanyingPeriod;
use Chill\PersonBundle\Entity\Person;

interface AccompanyingPeriodACLAwareRepositoryInterface
{
    public const USER_IS_REFERRER = 0b0010;   // 2 in decimal
    public const USER_IS_WORK_REFERRER = 0b0100; // 4 in decimal
    public const USER_IS_INTERVENING = 0b1000; // 8 in decimal

    /**
     * Finds associations for a given user within a specific date range and step filters.
     *
     * @param \DateTimeImmutable|null $from the start date for filtering when intervention in accompanying period took place
     * @param \DateTimeImmutable|null $to   the end date for filtering when intervention in accompanying period took place
     *
     * @return array the list of user associations matching the given criteria
     */
    public function findByUserAssociation(User $user, array $steps, ?\DateTimeImmutable $from, ?\DateTimeImmutable $to, int $filter, ?int $start = 0, ?int $limit = 1000): array;

    public function countByUserAssociation(User $user, array $steps, ?\DateTimeImmutable $from, ?\DateTimeImmutable $to, int $filter): int;

    /**
     * @param array|UserJob[]  $jobs
     * @param array|Scope[]    $services
     * @param array|Location[] $administrativeLocations
     */
    public function countByUnDispatched(array $jobs, array $services, array $administrativeLocations): int;

    /**
     * @param array|PostalCode[] $postalCodes
     */
    public function countByUserAndPostalCodesOpenedAccompanyingPeriod(?User $user, array $postalCodes): int;

    /**
     * @return array<AccompanyingPeriod>
     */
    public function findByPerson(
        Person $person,
        string $role,
        ?array $orderBy = [],
        ?int $limit = null,
        ?int $offset = null,
    ): array;

    /**
     * @param array|UserJob[]  $jobs                    if empty, does not take this argument into account
     * @param array|Scope[]    $services                if empty, does not take this argument into account
     * @param array|Location[] $administrativeLocations
     *
     * @return list<AccompanyingPeriod>
     */
    public function findByUnDispatched(array $jobs, array $services, array $administrativeLocations, ?array $orderBy = null, ?int $limit = null, ?int $offset = null): array;

    /**
     * @param array|PostalCode[] $postalCodes
     *
     * @return list<AccompanyingPeriod>
     */
    public function findByUserAndPostalCodesOpenedAccompanyingPeriod(?User $user, array $postalCodes, array $orderBy = [], int $limit = 0, int $offset = 50): array;
}
