<?php

declare(strict_types=1);

namespace Bot\Infrastructure\Repository;

use Bot\Domain\Entity\Ad;
use Bot\Domain\Repository\AdsRepositoryInterface;

/**
 * پیاده‌سازی in-memory برای تبلیغات.
 */
final class InMemoryAdsRepository implements AdsRepositoryInterface
{
    /** @var array<int,Ad> keyed by id */
    private array $adsById = [];
    private int $nextId = 1;

    /** @var array<int,list<Ad>> keyed by owner_admin_id */
    private array $adsByOwnerAdminId = [];

    public function findById(int $id): ?Ad
    {
        return $this->adsById[$id] ?? null;
    }

    /**
     * @return Ad[]
     */
    public function findByOwnerAdminId(int $ownerAdminId): array
    {
        return array_values($this->adsByOwnerAdminId[$ownerAdminId] ?? []);
    }

    /**
     * @return Ad[]
     */
    public function findEnabledByOwnerAdminId(int $ownerAdminId): array
    {
        $all = $this->adsByOwnerAdminId[$ownerAdminId] ?? [];

        return array_values(array_filter(
            $all,
            static fn (Ad $ad): bool => $ad->isEnabled(),
        ));
    }

    public function save(Ad $ad): void
    {
        // اگر ad جدید است (id=0)، ID جدید اختصاص می‌دهیم
        if ($ad->getId() === 0) {
            $newAd = new Ad(
                $this->nextId++,
                $ad->getOwnerAdminId(),
                $ad->getText(),
                $ad->getBannerUrl(),
                $ad->getFrequency(),
                $ad->isEnabled(),
            );
            $ad = $newAd;
        }

        $id         = $ad->getId();
        $ownerAdmin = $ad->getOwnerAdminId();

        $this->adsById[$id] = $ad;

        if (!isset($this->adsByOwnerAdminId[$ownerAdmin])) {
            $this->adsByOwnerAdminId[$ownerAdmin] = [];
        }

        $this->adsByOwnerAdminId[$ownerAdmin][$id] = $ad;
    }

    public function delete(int $id): void
    {
        $ad = $this->adsById[$id] ?? null;
        if ($ad === null) {
            return;
        }

        $ownerAdmin = $ad->getOwnerAdminId();
        unset($this->adsById[$id]);
        unset($this->adsByOwnerAdminId[$ownerAdmin][$id]);
    }
}


