<?php

namespace Lightscale\LaralightSvg;

use Illuminate\Support\Facades\Storage;

class SvgCollection
{
    protected array $paths = [];

    private ?SvgCollectionState $state = null;

    public function __construct(
        private readonly string $name
    )
    {}

    public function addPath(string $path)
    {
        $this->paths[] = $path;
    }

    public function getName(): string
    {
        return $this->name;
    }

    public function getSvgUrl(string $svg): string
    {
        $this->getState()->addSvg($svg);
        return route('laralight-svg.serve-svg', $this->getName()) . "#{$svg}";
    }

    protected function getState(): SvgCollectionState
    {
        if ($this->state === null) {
            $this->state = new SvgCollectionState($this->getName());
        }
        return $this->state;
    }

    public function getSvg(): ?string
    {
        $state = $this->getState();
        if ($state->hasPending()) {
            $this->compileSvg();
        }
        return $state->getFullSvg();
    }

    protected function compileSvg(): void
    {
        $state = $this->getState();
        $svg = $state->getFullSvg();
        $compiler = new SvgSpriteCompiler($svg);

        if ($compiler->isNew()) {
            $state->clearExisting(false);
        }

        $pending = $state->getPending();
        $added = [];
        $disks = array_map(
            fn($p) => Storage::build(['driver' => 'local', 'root' => $p]),
            array_reverse($this->paths)
        );

        foreach ($pending as $pendingSvg) {
            $file = $this->getFile($disks, $pendingSvg);
            if ($file !== null && $compiler->addSvg($pendingSvg, $file)) {
                $added[] = $pendingSvg;
            }
        }

        $state->clearPending(false);
        $state->concatExisting($added, false);
        $state->setFullSvg($compiler->getSvg(), false);
        $state->push();
    }

    protected function getFile(array $disks, string $svg): ?string
    {
        foreach ($disks as $disk) {
            $file = $disk->get("{$svg}.svg");
            if ($file !== null) return $file;
        }
        return null;
    }

}