<?php

namespace Formatrica\Submission\Pipeline;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Edition pipeline-extension holder (Phase 6, plan §6.8 / Phase-5 exit
 * criteria: "Free submission pipeline is statically Free-only; Pro stages
 * register only from the Pro provider").
 *
 * The Free Submission_Service builds its stage list keyed by stable slugs;
 * the Pro service provider registers an extension that inserts its stages
 * (draft claim/finalize, payment gate) relative to those keys. Free ships no
 * Pro stage names, imports, or class_exists probes.
 */
final class Pipeline_Extensions
{
    /** @var array<int, callable(array<string, Submission_Stage>):array<string, Submission_Stage>> */
    private static array $extensions = [];

    /**
     * @param callable(array<string, Submission_Stage>):array<string, Submission_Stage> $extension
     *        Receives the keyed stage map, returns the (re)keyed map.
     */
    public static function add(callable $extension): void
    {
        self::$extensions[] = $extension;
    }

    /**
     * Run every registered extension over the keyed stage map.
     *
     * @param array<string, Submission_Stage> $stages
     * @return array<string, Submission_Stage>
     */
    public static function apply(array $stages): array
    {
        foreach (self::$extensions as $extension) {
            $result = $extension($stages);
            if (is_array($result)) {
                $stages = $result;
            }
        }

        return $stages;
    }

    /**
     * Insert $new after $after_key (or append when the key is absent) —
     * shared helper so extensions keep ordering logic declarative.
     *
     * @param array<string, Submission_Stage> $stages
     * @param array<string, Submission_Stage> $new
     * @return array<string, Submission_Stage>
     */
    public static function insert_after(array $stages, string $after_key, array $new): array
    {
        if (!array_key_exists($after_key, $stages)) {
            return array_merge($stages, $new);
        }

        $out = [];
        foreach ($stages as $key => $stage) {
            $out[$key] = $stage;
            if ($key === $after_key) {
                foreach ($new as $new_key => $new_stage) {
                    $out[$new_key] = $new_stage;
                }
            }
        }

        return $out;
    }
}
