<?php

declare(strict_types=1);

final class MyronBranchingFormService
{
    /**
     * @param array<string, mixed> $definition
     * @param array<string, string> $answers
     * @return array<string, mixed>
     */
    public function resolve(array $definition, array $answers): array
    {
        $questions = is_array($definition['questions'] ?? null) ? $definition['questions'] : [];
        if ($questions === []) {
            throw new InvalidArgumentException('A branching form requires questions.');
        }

        $nodes = [];
        foreach ($questions as $question) {
            if (!is_array($question)) {
                continue;
            }
            $key = myronNormalizeSlug((string) ($question['key'] ?? ''));
            if ($key !== '') {
                $nodes[$key] = $question;
            }
        }

        $currentKey = myronNormalizeSlug((string) ($definition['start'] ?? array_key_first($nodes)));
        $visited = [];
        $path = [];
        $destination = '';

        while ($currentKey !== '') {
            if (isset($visited[$currentKey])) {
                throw new RuntimeException('Branching form contains a cycle at `' . $currentKey . '`.');
            }
            if (!isset($nodes[$currentKey])) {
                throw new RuntimeException('Branching form references unknown question `' . $currentKey . '`.');
            }

            $visited[$currentKey] = true;
            $question = $nodes[$currentKey];
            $answer = myronNormalizeSlug((string) ($answers[$currentKey] ?? ''));
            $path[] = ['question' => $currentKey, 'answer' => $answer];

            $next = '';
            foreach (is_array($question['answers'] ?? null) ? $question['answers'] : [] as $option) {
                if (!is_array($option)) {
                    continue;
                }
                if (myronNormalizeSlug((string) ($option['value'] ?? '')) !== $answer) {
                    continue;
                }
                $destination = trim((string) ($option['destinationTemplateId'] ?? $option['destination_template_id'] ?? ''));
                $next = myronNormalizeSlug((string) ($option['nextQuestionId'] ?? $option['next_question_id'] ?? ''));
                break;
            }

            if ($destination !== '' || $next === '') {
                break;
            }

            $currentKey = $next;
        }

        return [
            'destinationTemplateId' => $destination,
            'path' => $path,
            'complete' => $destination !== '',
        ];
    }
}
