<?php

declare(strict_types=1);

/**
 * APO-210 Card 2 — Canonical scene background catalog.
 *
 * Defines the four built-in scene backgrounds available in the creative layer.
 * Scenes are decorative DOM elements injected by the creative runtime as the
 * first child of each [data-mc-scene] section, behind all content.
 *
 * implementationType values:
 *   css    — pure CSS (no JS required at runtime)
 *   svg    — inline SVG element (no JS required at runtime)
 *   canvas — Canvas 2D animated via rAF (requiresJs: true)
 */
final class MyronSceneCatalog
{
    /** @var list<array<string, mixed>>|null */
    private static ?array $scenes = null;

    /**
     * @return list<array<string, mixed>>
     */
    public function list(): array
    {
        if (self::$scenes !== null) {
            return self::$scenes;
        }

        self::$scenes = [
            [
                'id'                 => 'gradient-flow',
                'label'              => 'Gradient Flow',
                'implementationType' => 'css',
                'requiresJs'         => false,
                'supportedParams'    => [
                    ['key' => 'colorA',   'label' => 'Color A (hex)', 'type' => 'string', 'default' => ''],
                    ['key' => 'colorB',   'label' => 'Color B (hex)', 'type' => 'string', 'default' => ''],
                    ['key' => 'duration', 'label' => 'Duration (s)',  'type' => 'number', 'default' => 12, 'min' => 4, 'max' => 60],
                ],
            ],
            [
                'id'                 => 'dot-grid',
                'label'              => 'Dot Grid',
                'implementationType' => 'css',
                'requiresJs'         => false,
                'supportedParams'    => [
                    ['key' => 'spacing',  'label' => 'Spacing (px)',  'type' => 'number', 'default' => 24, 'min' => 10, 'max' => 60],
                    ['key' => 'dotColor', 'label' => 'Dot color (hex)', 'type' => 'string', 'default' => ''],
                    ['key' => 'opacity',  'label' => 'Opacity (0–1)',  'type' => 'number', 'default' => 0.15, 'min' => 0.02, 'max' => 0.5, 'step' => 0.01],
                ],
            ],
            [
                'id'                 => 'noise-overlay',
                'label'              => 'Noise Overlay',
                'implementationType' => 'svg',
                'requiresJs'         => false,
                'supportedParams'    => [
                    ['key' => 'opacity',   'label' => 'Opacity (0–1)',      'type' => 'number', 'default' => 0.04, 'min' => 0.01, 'max' => 0.12, 'step' => 0.01],
                    ['key' => 'frequency', 'label' => 'Noise frequency',    'type' => 'number', 'default' => 0.65, 'min' => 0.1,  'max' => 2.0,  'step' => 0.05],
                ],
            ],
            [
                'id'                 => 'canvas-particles',
                'label'              => 'Particle Field',
                'implementationType' => 'canvas',
                'requiresJs'         => true,
                'supportedParams'    => [
                    ['key' => 'count',   'label' => 'Particle count', 'type' => 'number', 'default' => 40, 'min' => 10, 'max' => 60],
                    ['key' => 'color',   'label' => 'Color (hex)',     'type' => 'string', 'default' => ''],
                    ['key' => 'speed',   'label' => 'Speed (0.1–2)',   'type' => 'number', 'default' => 0.5, 'min' => 0.1, 'max' => 2.0, 'step' => 0.1],
                ],
            ],
        ];

        return self::$scenes;
    }

    /**
     * @return array<string, mixed>|null
     */
    public function find(string $id): ?array
    {
        $id = trim($id);
        foreach ($this->list() as $scene) {
            if ((string) ($scene['id'] ?? '') === $id) {
                return $scene;
            }
        }

        return null;
    }

    /**
     * @return list<string>
     */
    public function ids(): array
    {
        return array_values(array_map(static fn (array $s): string => (string) $s['id'], $this->list()));
    }
}
