<?php
declare(strict_types=1);

namespace App\Repositories;

use App\Json\FileStore;

class JsonGalleryRepository implements GalleryRepository
{
    public function __construct(private FileStore $store) {}

    private function list(): array
    {
        $d = $this->store->read();
        return $d['items'] ?? [];
    }

    public function all(array $filters = []): array
    {
        $list = $this->list();
        if (!empty($filters['artist_id'])) {
            $list = array_values(array_filter($list, fn($i) => ($i['artist_id'] ?? '') === $filters['artist_id']));
        }
        if (!empty($filters['tag'])) {
            $list = array_values(array_filter($list, fn($i) => in_array($filters['tag'], (array)($i['tags'] ?? []), true)));
        }
        usort($list, fn($a, $b) => (int)($a['sort_index'] ?? 0) - (int)($b['sort_index'] ?? 0));
        return $list;
    }

    public function find(string $id): ?array
    {
        foreach ($this->list() as $i) if (($i['id'] ?? null) === $id) return $i;
        return null;
    }

    public function save(array $item): array
    {
        $now = now_iso();
        if (empty($item['id'])) {
            $item['id'] = uuid();
            $item['created_at'] = $now;
        }
        $this->store->transaction(function ($d) use (&$item) {
            $list = $d['items'] ?? [];
            $found = false;
            foreach ($list as $i => $existing) {
                if (($existing['id'] ?? null) === $item['id']) {
                    $list[$i] = array_merge($existing, $item);
                    $item = $list[$i];
                    $found = true;
                    break;
                }
            }
            if (!$found) $list[] = $item;
            $d['items'] = $list;
            return $d;
        });
        return $item;
    }

    public function delete(string $id): void
    {
        $this->store->transaction(function ($d) use ($id) {
            $d['items'] = array_values(array_filter($d['items'] ?? [], fn($i) => ($i['id'] ?? null) !== $id));
            return $d;
        });
    }
}
