<?php

declare(strict_types=1);

namespace CpCreation\VitiCore\PageBuilder\Repository;

use CpCreation\VitiCore\PageBuilder\Model\PageSection;
use CpCreation\VitiCore\Repository\BaseRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

final class PageSectionRepository extends BaseRepository
{
    /**
     * @throws \ReflectionException
     */
    public function __construct(private readonly ManagerRegistry $registry)
    {
        parent::__construct($this->registry, PageSection::class);
    }

    /**
     * @return list<PageSection>
     */
    public function findActiveForPageCode(string $pageCode, ?\DateTimeInterface $referenceDate = null): array
    {
        return $this->createActiveForPageCodeQueryBuilder($pageCode, $referenceDate)
            ->getQuery()
            ->getResult();
    }

    /**
     * @return list<PageSection>
     */
    public function findByPageCodeAdmin(string $pageCode): array
    {
        return $this->createPageCodeQueryBuilder($pageCode)
            ->orderBy('s.position', 'ASC')
            ->addOrderBy('s.createdAt', 'ASC')
            ->getQuery()
            ->getResult();
    }

    private function createActiveForPageCodeQueryBuilder(string $pageCode, ?\DateTimeInterface $referenceDate = null): QueryBuilder
    {
        $referenceDate ??= new \DateTimeImmutable();

        return $this->createPageCodeQueryBuilder($pageCode)
            ->andWhere('s.disabled = FALSE')
            ->andWhere('(s.publishedAt <= :datetime OR s.publishedAt IS NULL)')
            ->andWhere('(s.unPublishedAt >= :datetime OR s.unPublishedAt IS NULL)')
            ->setParameter('datetime', $referenceDate)
            ->orderBy('s.position', 'ASC')
            ->addOrderBy('s.createdAt', 'ASC');
    }

    private function createPageCodeQueryBuilder(string $pageCode): QueryBuilder
    {
        return $this->createQueryBuilder('s')
            ->innerJoin('s.page', 'p')
            ->addSelect('p')
            ->andWhere('p.code = :pageCode')
            ->setParameter('pageCode', trim($pageCode));
    }
}
