<?php

namespace domain\Subscription\Subscription;

use domain\Product\Product\Product;
use domain\User\User\User;
use domain\_\AbstractRepository;

class SubscriptionRepository extends AbstractRepository
{
    protected SubscriptionRepositoryQuery $query;
    protected SubscriptionSolver $subscriptionSolver;

    public function loadDependencies(): void
    {
        $this->loadQuery(SubscriptionRepositoryQuery::class);
        $this->subscriptionSolver = $this->loadService(SubscriptionSolver::class);
    }

    public function getDefaultOptionsSearch(): array
    {
        return [
            self::WITH => ['producer'],
            self::JOIN_WITH => ['user', 'productSubscription', 'productSubscription.product', 'pointSale'],
            self::ORDER_BY => 'user.name ASC',
            self::ATTRIBUTE_ID_PRODUCER => 'subscription.id_producer'
        ];
    }

    public function findOneSubscriptionById(int $id): ?Subscription
    {
        return $this->createDefaultQuery()
            ->filterById($id)
            ->findOne();
    }

    public function findSubscriptions()
    {
        return $this->createDefaultQuery()->find();
    }

    /**
     * Retourne les abonnements pour une date donnée.
     */
    public function findSubscriptionsByDate(string $date)
    {
        $date = date('Y-m-d', strtotime($date));
        $subscriptionArray = $this->findSubscriptions();
        $subscriptionReturnArray = [];

        foreach ($subscriptionArray as $subscription) {
            if ($date >= $subscription->date_begin &&
                (!$subscription->date_end || $date <= $subscription->date_end)
                && $this->subscriptionSolver->isSubscriptionMatchWith($subscription, $date)) {
                $subscriptionReturnArray[] = $subscription;
            }
        }

        return $subscriptionReturnArray;
    }

    public function findSubscriptionsByUser(User $user)
    {
        return $this->createDefaultQuery()
            ->filterByUser($user)
            ->find();
    }

    public function countSubscriptionsByUser(User $user)
    {
        return count($this->findSubscriptionsByUser($user));
    }

    public function findSubscriptionsLatestAdded()
    {
        return $this->createDefaultQuery()
            ->filterByCreatedOrUpdatedByUserDuringPastWeek()
            ->find();
    }

    public function findSubscriptionsWithProduct(Product $product)
    {
        $subscriptionsArray = $this->createDefaultQuery()->find();
        $subscriptionsWithProductArray = [];

        foreach($subscriptionsArray as $subscription) {
            if($this->subscriptionSolver->containProduct($subscription, $product)) {
                $subscriptionsWithProductArray[] = $subscription;
            }
        }

        return $subscriptionsWithProductArray;
    }
}