<?php

declare(strict_types=1);

namespace App\Repository;

use App\Entity\DrinkType;
use App\Entity\Order;
use App\Enum\OrderStatus;
use DateTimeImmutable;
use Doctrine\ORM\EntityManagerInterface;

/**
 * @extends AbstractRepository<Order>
 */
class OrderRepository extends AbstractRepository
{
    public function __construct(EntityManagerInterface $entityManager)
    {
        parent::__construct($entityManager, $entityManager->getClassMetadata(Order::class));
    }

    /**
     * @return array<int, Order>
     */
    public function findByStatus(OrderStatus $status): array
    {
        return $this->findBy(
            [
                'status' => $status,
            ],
            [
                'createdAt' => 'DESC',
            ],
        );
    }

    /**
     * @param array<OrderStatus> $stati
     * @return array<int, Order>
     */
    public function findByMultipleStatus(array $stati): array
    {
        $qb = $this->getEntityManager()->createQueryBuilder();
        $qb
            ->select('o')
            ->from(Order::class, 'o')
            ->where('o.status IN (:stati)')
            ->setParameter('stati', $stati)
            ->orderBy('o.createdAt', 'DESC');

        /** @var array<int, Order> $result */
        $result = $qb->getQuery()->getResult();
        return $result;
    }

    /**
     * @return array<int, Order>
     */
    public function findByDateRange(DateTimeImmutable $start, DateTimeImmutable $end): array
    {
        $qb = $this->getEntityManager()->createQueryBuilder();
        $qb
            ->select('o')
            ->from(Order::class, 'o')
            ->where('o.createdAt >= :start')
            ->andWhere('o.createdAt <= :end')
            ->setParameter('start', $start)
            ->setParameter('end', $end)
            ->orderBy('o.createdAt', 'DESC');

        /** @var array<int, Order> $result */
        $result = $qb->getQuery()->getResult();
        return $result;
    }

    /**
     * Find the last N orders that contain a specific drink type
     *
     * @param DrinkType $drinkType The drink type to search for
     * @param int $limit The maximum number of orders to return
     * @return array<int, Order> The last N orders containing the drink type, ordered by creation date (newest first)
     */
    public function findLastOrdersForDrinkType(DrinkType $drinkType, int $limit = 5): array
    {
        $qb = $this->getEntityManager()->createQueryBuilder();
        $qb
            ->select('o')
            ->from(Order::class, 'o')
            ->join('o.orderItems', 'oi')
            ->where('oi.drinkType = :drinkType')
            ->andWhere('o.status = :status') // Only consider fulfilled orders
            ->setParameter('drinkType', $drinkType)
            ->setParameter('status', OrderStatus::FULFILLED->value)
            ->orderBy('o.createdAt', 'DESC')
            ->setMaxResults($limit);

        /** @var array<int, Order> $result */
        $result = $qb->getQuery()->getResult();
        return $result;
    }
}
