<?php

declare(strict_types=1);

namespace MauticPlugin\DealFlowBundle\Entity;

use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

/** @extends ServiceEntityRepository<DealAuditEvent> */
class DealAuditEventRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, DealAuditEvent::class);
    }

    /**
     * @return list<DealAuditEvent>
     */
    public function findByDeal(Deal $deal): array
    {
        return $this->findBy(['deal' => $deal], ['createdAt' => 'DESC']);
    }

    /**
     * @return list<DealAuditEvent>
     */
    public function findRecentForPipeline(Pipeline $pipeline, ?int $currentUserId = null, bool $includeOtherDeals = true, int $limit = 8): array
    {
        $qb = $this->createQueryBuilder('a')
            ->join('a.deal', 'd')
            ->addSelect('d')
            ->leftJoin('d.stage', 's')
            ->addSelect('s')
            ->andWhere('d.pipeline = :pipeline')
            ->setParameter('pipeline', $pipeline)
            ->orderBy('a.createdAt', 'DESC')
            ->setMaxResults($limit);

        $this->applyVisibilityScope($qb, 'd', $currentUserId, $includeOtherDeals);

        return $qb->getQuery()->getResult();
    }

    private function applyVisibilityScope(QueryBuilder $qb, string $alias, ?int $currentUserId, bool $includeOtherDeals): void
    {
        if ($includeOtherDeals) {
            return;
        }

        if (null === $currentUserId) {
            $qb->andWhere('1 = 0');

            return;
        }

        $qb->andWhere(sprintf(
            '(%1$s.ownerId = :dealflowCurrentUserId OR (%1$s.ownerId IS NULL AND %1$s.createdBy = :dealflowCurrentUserId))',
            $alias
        ))
            ->setParameter('dealflowCurrentUserId', $currentUserId);
    }
}
