<?php

declare(strict_types=1);

final class MyronPublicHeroImagePolicy
{
    public const SPLIT_RENDITION = 'preview';
    public const FULL_BLEED_RENDITION = 'hero';
    public const SPLIT_SIZES = '(max-width: 900px) 100vw, 50vw';
    public const FULL_BLEED_SIZES = '100vw';

    /**
     * @var array<string, int>
     */
    public const SRCSET_RENDITIONS = [
        'card' => 400,
        'card-lg' => 960,
        'preview' => 1280,
        'hero' => 1920,
        'xl' => 2560,
    ];

    /**
     * @return array{rendition:string,sizes:string,srcset:array<string,int>,layout:string}
     */
    public static function forSection(string $componentId, string $variant, ?string $mediaLayout = null): array
    {
        $componentId = self::normalizeSlug($componentId);
        $mediaLayout = self::normalizeMediaLayout($mediaLayout);
        $isFullBleed = match ($mediaLayout) {
            'full-bleed', 'full-width' => true,
            'split' => false,
            default => self::isFullBleedVariant($componentId, $variant),
        };

        return [
            'rendition' => $isFullBleed ? self::FULL_BLEED_RENDITION : self::SPLIT_RENDITION,
            'sizes' => $isFullBleed ? self::FULL_BLEED_SIZES : self::SPLIT_SIZES,
            'srcset' => self::SRCSET_RENDITIONS,
            'layout' => $isFullBleed ? 'full-bleed' : 'split',
        ];
    }

    public static function isFullBleedVariant(string $componentId, string $variant): bool
    {
        $componentId = self::normalizeSlug($componentId);
        if (!in_array($componentId, ['hero-simple', 'hero-with-cta'], true)) {
            return false;
        }

        $variant = self::normalizeSlug($variant);
        if ($variant === '') {
            return false;
        }

        return str_contains($variant, 'full-bleed') || str_contains($variant, 'full-width');
    }

    /**
     * @param array<string, mixed> $section
     */
    public static function mediaLayoutForSection(array $section): string
    {
        $mediaLayout = self::normalizeMediaLayout($section['mediaLayout'] ?? null);
        if ($mediaLayout !== 'auto') {
            return $mediaLayout;
        }

        $design = is_array($section['design'] ?? null) ? $section['design'] : [];
        return self::normalizeMediaLayout($design['mediaLayout'] ?? null);
    }

    public static function normalizeMediaLayout(mixed $value): string
    {
        $layout = self::normalizeSlug((string) $value);
        return match ($layout) {
            'full-bleed', 'full-width', 'split' => $layout,
            default => 'auto',
        };
    }

    public static function renditionWidth(?string $rendition): ?int
    {
        $rendition = self::normalizeSlug((string) $rendition);
        if ($rendition === '') {
            return null;
        }

        return self::SRCSET_RENDITIONS[$rendition] ?? match ($rendition) {
            'thumb' => 320,
            default => null,
        };
    }

    private static function normalizeSlug(string $value): string
    {
        $value = strtolower(trim($value));
        $value = preg_replace('/[^a-z0-9]+/', '-', $value) ?? '';

        return trim($value, '-');
    }
}
