<?php

declare(strict_types=1);

namespace Builder\Core\Foundation\Revisions;

final class RevisionDataExtractor
{
    /**
     * Extract all media IDs referenced in a single revision's data.
     *
     * @param  array<string, mixed>  $data
     * @return list<int>
     */
    public static function mediaIds(array $data): array
    {
        $ids = [];

        foreach ((array) ($data[RevisionDiff::KEY_MEDIA] ?? []) as $collection) {
            foreach ((array) $collection as $mediaId) {
                $ids[] = (int) $mediaId;
            }
        }

        foreach (self::allBlocks($data) as $block) {
            foreach ((array) ($block['media'] ?? []) as $collection) {
                foreach ((array) $collection as $mediaId) {
                    $ids[] = (int) $mediaId;
                }
            }
        }

        return $ids;
    }

    /**
     * Extract all block type keys referenced in a single revision's data.
     *
     * @param  array<string, mixed>  $data
     * @return list<string>
     */
    public static function blockKeys(array $data): array
    {
        return array_values(
            collect(self::allBlocks($data))
                ->filter(fn (array $block): bool => isset($block['key']))
                ->map(fn (array $block): string => (string) $block['key'])
                ->values()
                ->all(),
        );
    }

    /**
     * Yield all blocks (direct and inside translations) from revision data.
     *
     * @param  array<string, mixed>  $data
     * @return list<array<string, mixed>>
     */
    private static function allBlocks(array $data): array
    {
        $blocks = [];

        foreach ((array) ($data[RevisionDiff::KEY_BLOCKS] ?? []) as $group) {
            foreach ((array) $group as $block) {
                $blocks[] = $block;
            }
        }

        foreach ((array) ($data[RevisionDiff::KEY_TRANSLATIONS] ?? []) as $translation) {
            foreach ((array) ($translation[RevisionDiff::KEY_BLOCKS] ?? []) as $group) {
                foreach ((array) $group as $block) {
                    $blocks[] = $block;
                }
            }
        }

        return $blocks;
    }
}
