<?php

namespace App\Support\Help;

use Illuminate\Contracts\Cache\Repository as CacheRepository;
use Illuminate\Contracts\Filesystem\FileNotFoundException;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Storage;
use RuntimeException;

class HelpRepository
{
    public function __construct(private readonly CacheRepository $cache) {}

    public function list(string $audience, string $locale): Collection
    {
        $key = $this->cacheKey($audience, $locale);

        return $this->cache->remember($key, now()->addMinutes(10), fn () => $this->load($audience, $locale));
    }

    public function find(string $audience, string $locale, string $slug): ?array
    {
        return $this->list($audience, $locale)
            ->first(fn ($article) => Arr::get($article, 'slug') === $slug);
    }

    private function load(string $audience, string $locale): Collection
    {
        $disk = config('help.disk');
        $compiledPath = trim(config('help.compiled_path'), '/');
        $path = sprintf('%s/%s/%s/articles.json', $compiledPath, $audience, $locale);

        if (! Storage::disk($disk)->exists($path)) {
            throw new RuntimeException(sprintf('Help cache missing for %s/%s. Run help:sync.', $audience, $locale));
        }

        try {
            $contents = Storage::disk($disk)->get($path);
        } catch (FileNotFoundException $e) {
            throw new RuntimeException($e->getMessage());
        }

        $decoded = json_decode($contents, true, flags: JSON_THROW_ON_ERROR);

        return collect($decoded);
    }

    private function cacheKey(string $audience, string $locale): string
    {
        return sprintf('help.%s.%s', $audience, $locale);
    }
}
