<?php

declare(strict_types=1);

namespace Archive\Archived;

use App\Framework\View\Cache\CacheDependency;
use App\Framework\View\Cache\DependencyType;

final readonly class DependencyCollection
{
    /** @param CacheDependency[] $dependencies */
    public function __construct(
        private array $dependencies = [],
    ) {
        foreach ($dependencies as $dependency) {
            if (!$dependency instanceof CacheDependency) {
                throw new \InvalidArgumentException('All items must be CacheDependency instances');
            }
        }
    }

    public static function empty(): self
    {
        return new self([]);
    }

    public static function fromStrings(array $strings): self
    {
        $dependencies = array_map(
            fn(string $str) => CacheDependency::fromString($str),
            $strings
        );

        return new self($dependencies);
    }

    public function add(CacheDependency $dependency): self
    {
        // Prevent duplicates
        foreach ($this->dependencies as $existing) {
            if ($existing->equals($dependency)) {
                return $this;
            }
        }

        return new self([...$this->dependencies, $dependency]);
    }

    public function has(string $key): bool
    {
        foreach ($this->dependencies as $dependency) {
            if ($dependency->key === $key) {
                return true;
            }
        }
        return false;
    }

    public function ofType(DependencyType $type): self
    {
        return new self(
            array_filter(
                $this->dependencies,
                fn(CacheDependency $dep) => $dep->type === $type
            )
        );
    }

    public function count(): int
    {
        return count($this->dependencies);
    }

    public function isEmpty(): bool
    {
        return empty($this->dependencies);
    }

    public function toArray(): array
    {
        return array_map(
            fn(CacheDependency $dep) => $dep->toArray(),
            $this->dependencies
        );
    }

    /** @return CacheDependency[] */
    public function all(): array
    {
        return $this->dependencies;
    }
}
