<?php

declare(strict_types=1);

/**
 * APO-210 Card 2 — Canonical motion profile catalog.
 *
 * Defines the built-in motion profiles available in the creative layer.
 * The renderer reads these ids, the admin creative panel lists them, and the
 * creative runtime JS dispatches on them via data-mc-motion attributes.
 */
final class MyronMotionProfileCatalog
{
    /** @var list<array<string, mixed>>|null */
    private static ?array $profiles = null;

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

        self::$profiles = [
            [
                'id'              => 'fade-up',
                'label'           => 'Fade Up',
                'cssClass'        => 'mc-motion--fade-up',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 600, 'min' => 100, 'max' => 2000],
                    ['key' => 'delay',    'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,   'min' => 0,   'max' => 2000],
                    ['key' => 'distance', 'label' => 'Distance (px)', 'type' => 'number', 'default' => 40,  'min' => 10,  'max' => 120],
                ],
            ],
            [
                'id'              => 'slide-in',
                'label'           => 'Slide In',
                'cssClass'        => 'mc-motion--slide-in',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration',  'label' => 'Duration (ms)',  'type' => 'number', 'default' => 500, 'min' => 100, 'max' => 2000],
                    ['key' => 'delay',     'label' => 'Delay (ms)',     'type' => 'number', 'default' => 0,   'min' => 0,   'max' => 2000],
                    ['key' => 'distance',  'label' => 'Distance (px)',  'type' => 'number', 'default' => 60,  'min' => 10,  'max' => 200],
                    ['key' => 'direction', 'label' => 'Direction',      'type' => 'select', 'default' => 'left', 'options' => ['left', 'right']],
                ],
            ],
            [
                'id'              => 'stagger',
                'label'           => 'Stagger Children',
                'cssClass'        => 'mc-motion--stagger',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 500, 'min' => 100, 'max' => 2000],
                    ['key' => 'delay',    'label' => 'Initial Delay (ms)', 'type' => 'number', 'default' => 0, 'min' => 0, 'max' => 1000],
                    ['key' => 'stagger',  'label' => 'Stagger Step (ms)',  'type' => 'number', 'default' => 120, 'min' => 30, 'max' => 500],
                ],
            ],
            [
                'id'              => 'zoom-in',
                'label'           => 'Zoom In',
                'cssClass'        => 'mc-motion--zoom-in',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 500, 'min' => 100, 'max' => 2000],
                    ['key' => 'delay',    'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,   'min' => 0,   'max' => 2000],
                ],
            ],
            [
                'id'              => 'blur-in',
                'label'           => 'Blur In',
                'cssClass'        => 'mc-motion--blur-in',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 600, 'min' => 200, 'max' => 1500],
                    ['key' => 'delay',    'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,   'min' => 0,   'max' => 2000],
                ],
            ],
            [
                'id'              => 'flip-up',
                'label'           => 'Flip Up',
                'cssClass'        => 'mc-motion--flip-up',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 700, 'min' => 300, 'max' => 1500],
                    ['key' => 'delay',    'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,   'min' => 0,   'max' => 2000],
                    ['key' => 'angle',    'label' => 'Angle (deg)',   'type' => 'number', 'default' => 15,  'min' => 5,   'max' => 30],
                ],
            ],
            [
                'id'              => 'scale-pop',
                'label'           => 'Scale Pop',
                'cssClass'        => 'mc-motion--scale-pop',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'duration',   'label' => 'Duration (ms)', 'type' => 'number', 'default' => 500,  'min' => 200, 'max' => 1200],
                    ['key' => 'delay',      'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,    'min' => 0,   'max' => 2000],
                    ['key' => 'startScale', 'label' => 'Start scale',   'type' => 'number', 'default' => 0.85, 'min' => 0.6, 'max' => 0.95, 'step' => 0.01],
                ],
            ],
            [
                'id'              => 'count-up',
                'label'           => 'Count Up',
                'cssClass'        => 'mc-motion--count-up',
                'requiresJs'      => true,
                'reducedMotion'   => 'target',
                'supportedParams' => [
                    ['key' => 'duration', 'label' => 'Duration (ms)', 'type' => 'number', 'default' => 1800, 'min' => 500, 'max' => 4000],
                    ['key' => 'delay',    'label' => 'Delay (ms)',    'type' => 'number', 'default' => 0,    'min' => 0,   'max' => 2000],
                ],
            ],
            [
                'id'              => 'parallax-bg',
                'label'           => 'Parallax Background',
                'cssClass'        => 'mc-motion--parallax-bg',
                'requiresJs'      => true,
                'reducedMotion'   => 'skip',
                'supportedParams' => [
                    ['key' => 'intensity', 'label' => 'Intensity', 'type' => 'number', 'default' => 0.2, 'min' => 0.05, 'max' => 0.5, 'step' => 0.05],
                ],
            ],
        ];

        return self::$profiles;
    }

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

        return null;
    }

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