<?php

namespace App\Services\Ai;

/**
 * Per-deck enrichment plan: which "house-style" embellishments (device backdrop,
 * decorative orbs/sparkles) a generated set uses, and in what variant. Driven by
 * the chosen STYLE (each style leans a certain way — editorial is restrained,
 * modern/friendly are richer) plus the SEED (rolls within the style's allowed
 * options) so two decks of the same style still differ, and re-rolling the seed
 * (/ai/shuffle) produces a visibly different treatment.
 *
 *   panel: 'block' | 'soft' | 'duotone' | 'glow' | 'spotlight' | 'none'  device backdrop
 *   orbs / sparkles: bool                                                decoration accents
 *
 * No feature-glyph badge — a generic icon tile reads templated; every style now
 * leads with headline + device and leans on palette + device panel + decoration
 * + layout rhythm for variety instead.
 */
class EnrichmentPlan
{
    /**
     * @return array{panel: string, orbs: bool, sparkles: bool}
     */
    public static function for(string $styleKey, int $seed): array
    {
        // Decorrelate from the decoration RNG (which seeds on $seed directly) so
        // the enrichment roll isn't lock-stepped to the blob placement.
        $rng = new SeededRandom($seed * 31 + 7);

        return match ($styleKey) {
            // Lookbook: the premium template carries its own signal (emphasis
            // headline + trust badge); a soft device backdrop + gentle shine.
            'lookbook' => [
                'panel'    => self::weighted($rng, ['soft' => 55, 'glow' => 45]),
                'orbs'     => $rng->bool(0.35),
                'sparkles' => true,
            ],
            // Editorial: calm + premium, "almost no decoration" — the oversized
            // serif headline + whitespace carry it.
            'editorial' => [
                'panel'    => self::weighted($rng, ['none' => 60, 'soft' => 40]),
                'orbs'     => false,
                'sparkles' => $rng->bool(0.2),
            ],
            // Friendly: consumer + playful — richer, livelier backdrops.
            'friendly' => [
                'panel'    => self::weighted($rng, ['block' => 18, 'glow' => 16, 'duotone' => 16, 'soft' => 14, 'spotlight' => 14, 'none' => 8]),
                'orbs'     => $rng->bool(0.7),
                'sparkles' => $rng->bool(0.7),
            ],
            // Modern (default): tech + confident — varied device panel + deco.
            default => [
                'panel'    => self::weighted($rng, ['glow' => 20, 'spotlight' => 18, 'block' => 15, 'duotone' => 15, 'soft' => 14, 'none' => 8]),
                'orbs'     => $rng->bool(0.4),
                'sparkles' => $rng->bool(0.5),
            ],
        };
    }

    /** Fallback when no plan was threaded (the house default). */
    public static function default(): array
    {
        return ['panel' => 'block', 'orbs' => true, 'sparkles' => true];
    }

    /**
     * Weighted pick from `[$key => $weight]` using one RNG draw.
     *
     * @param  array<string, int>  $weights
     */
    private static function weighted(SeededRandom $rng, array $weights): string
    {
        $total = array_sum($weights);
        $roll  = $rng->next() * $total;
        $acc   = 0.0;
        foreach ($weights as $key => $w) {
            $acc += $w;
            if ($roll < $acc) {
                return (string) $key;
            }
        }

        return (string) array_key_last($weights);
    }
}
