<?php

namespace App\Monitor\Framework\Repository;

use App\Base\Util\Paginator;
use App\Monitor\Framework\Entity\Monitor;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Component\Security\Core\User\UserInterface;

/**
 * @extends ServiceEntityRepository<Monitor>
 */
class MonitorRepository extends ServiceEntityRepository
{
    private Paginator $paginator;

    public function __construct(ManagerRegistry $registry, Paginator $paginator)
    {
        parent::__construct($registry, Monitor::class);
        $this->paginator = $paginator;
    }

    public function getUserMonitorsPaginated(UserInterface $user, int $page, int $perPage, string $searchTerm): Paginator
    {
        $query = $this->createQueryBuilder('m')
            ->andWhere('m.status IN (:statuses)')
            ->andWhere('m.user = :user')
            ->orderBy('m.id', 'ASC')
            ->setParameter('statuses', ['Active', 'New', 'In Progress', 'Complete'])
            ->setParameter('user', $user)
            ->getQuery();

        return $this->paginator->paginate($query, $page, $perPage);
    }

    public function whereAirDateNotNull()
    {
        $query = $this->createQueryBuilder('m')
            ->andWhere('m.airDate IS NOT NULL')
            ->getQuery();
        return $query->getResult();
    }

    public function getActiveUserMonitors()
    {
        return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
            ->andWhere('m.status IN (:statuses)')
            ->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)')
            ->andWhere('m.parent IS NULL')
            ->setParameter('statuses', ['New', 'In Progress', 'Active'])
            ->setParameter('term', '%'.$this->term.'%')
            ->orderBy('m.id', 'DESC')
            ->getQuery()
        );
    }

    public function getChildMonitorsByParentId(int $parentId)
    {
        return $this->asPaginator(
            $this->monitorRepository->createQueryBuilder('m')
                ->andWhere("m.parent = :parentId")
                ->setParameter('parentId', $parentId)
                ->orderBy('m.id', 'DESC')
                ->getQuery()
        );
    }

    public function getCompleteUserMonitors()
    {
        return $this->asPaginator($this->monitorRepository->createQueryBuilder('m')
            ->andWhere('m.status = :status')
            ->andWhere('(m.title LIKE :term OR m.imdbId LIKE :term OR m.monitorType LIKE :term OR m.status LIKE :term)')
            ->setParameter('status', 'Complete')
            ->setParameter('term', '%'.$this->term.'%')
            ->orderBy('m.id', 'DESC')
            ->getQuery()
        );
    }

    public function countUserChildrenByParentId(int $userId, string $imdbId): ?int
    {
        return $this->createQueryBuilder('m')
            ->select('COUNT(m.id)')
            ->andWhere('m.user = :user')
            ->andWhere('m.imdbId = :imdbId')
            ->setParameter('user', $userId)
            ->setParameter('imdbId', $imdbId)
            ->getQuery()
            ->getSingleScalarResult()
        ;
    }

    public function countUserActiveChildrenByParentId(int $userId, string $imdbId): ?int
    {
        return $this->createQueryBuilder('m')
            ->select('COUNT(m.id)')
            ->andWhere('m.user = :user')
            ->andWhere('m.imdbId = :imdbId')
            ->andWhere('m.status IN (:statuses)')
            ->setParameter('user', $userId)
            ->setParameter('statuses', ['Active', 'New', 'In Progress'])
            ->setParameter('imdbId', $imdbId)
            ->getQuery()
            ->getSingleScalarResult()
        ;
    }

    public function countUserCompleteChildrenByParentId(int $userId, string $imdbId): ?int
    {
        return $this->createQueryBuilder('m')
            ->select('COUNT(m.id)')
            ->andWhere('m.user = :user')
            ->andWhere('m.imdbId = :imdbId')
            ->andWhere('m.status IN (:statuses)')
            ->setParameter('user', $userId)
            ->setParameter('statuses', ['Complete'])
            ->setParameter('imdbId', $imdbId)
            ->getQuery()
            ->getSingleScalarResult()
        ;
    }
}
