<?php

declare(strict_types=1);

/*
 * This file is part of the VITICORE2 package.
 *
 * (c) CP Creation <web@cpcreation.fr>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace CpCreation\VitiCore\Cart\Repository;

use CpCreation\VitiCore\Cart\Model\WithdrawalRequest;
use CpCreation\VitiCore\Repository\BaseRepository;
use Doctrine\ORM\QueryBuilder;
use Doctrine\Persistence\ManagerRegistry;

final class WithdrawalRequestRepository extends BaseRepository
{
    /**
     * @throws \ReflectionException
     */
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, WithdrawalRequest::class);
    }

    public function createAdminQueryBuilder(?string $search = null, ?string $status = null): QueryBuilder
    {
        $search = mb_strtolower(mb_trim((string) $search));
        $qb = $this->createQueryBuilder('withdrawal_request')
            ->innerJoin('withdrawal_request.cart', 'cart')
            ->addSelect('cart')
            ->orderBy('withdrawal_request.submittedAt', 'DESC');

        if ('' !== $search) {
            $qb
                ->andWhere('(
                    LOWER(withdrawal_request.contractReference) LIKE :search
                    OR LOWER(withdrawal_request.firstname) LIKE :search
                    OR LOWER(withdrawal_request.lastname) LIKE :search
                    OR LOWER(CONCAT(withdrawal_request.firstname, CONCAT(\' \', withdrawal_request.lastname))) LIKE :search
                    OR LOWER(withdrawal_request.receiptEmail) LIKE :search
                )')
                ->setParameter('search', '%' . $search . '%');
        }

        if ('pending' === $status) {
            $qb->andWhere('withdrawal_request.processedAt IS NULL');
        } elseif ('processed' === $status) {
            $qb->andWhere('withdrawal_request.processedAt IS NOT NULL');
        }

        return $qb;
    }

    /**
     * @return list<WithdrawalRequest>
     */
    public function findForAdmin(?string $search = null, ?string $status = null): array
    {
        return $this->createAdminQueryBuilder($search, $status)
            ->getQuery()
            ->getResult();
    }

    public function countPendingForAdmin(): int
    {
        return (int) $this->createQueryBuilder('withdrawal_request')
            ->select('COUNT(withdrawal_request.id)')
            ->andWhere('withdrawal_request.processedAt IS NULL')
            ->getQuery()
            ->getSingleScalarResult();
    }
}
