<?php

declare(strict_types=1);

namespace App\Support\ProductKnowledge;

use App\Support\Links\RequiredPermissionsLinks;
use InvalidArgumentException;

final class ContextualHelpCatalog
{
    public const string ADMIN_CONSENT_REQUIRED = 'admin-consent-required';

    public const string REQUIRED_PERMISSIONS_MISSING = 'required-permissions-missing';

    public const string CONNECTION_UNHEALTHY = 'connection-unhealthy';

    public const string VERIFICATION_STALE = 'verification-stale';

    public const string VERIFICATION_FAILED = 'verification-failed';

    public const string DIAGNOSTIC_EVIDENCE_INCOMPLETE = 'diagnostic-evidence-incomplete';

    public const string RETRYABLE_PROVIDER_FAILURE = 'retryable-provider-failure';

    public const string MANUAL_HANDOFF_REQUIRED = 'manual-handoff-required';

    public const string LINK_RESOLVER_ADMIN_CONSENT_PRIMARY = 'admin_consent_primary';

    public const string LINK_RESOLVER_REQUIRED_PERMISSIONS = 'required_permissions';

    /**
     * @return list<string>
     */
    public function keys(): array
    {
        return array_keys($this->definitions());
    }

    /**
     * @return array<string, array{
     *     topic_key: string,
     *     surface_families: list<string>,
     *     headline: string,
     *     short_explanation: string,
     *     troubleshooting_steps: list<string>,
     *     safe_next_action: string,
     *     glossary_terms: list<string>,
     *     docs_links: list<array{
     *         label: string,
     *         kind: string,
     *         url?: string,
     *         resolver?: string
     *     }>
     * }>
     */
    public function definitions(): array
    {
        return [
            self::ADMIN_CONSENT_REQUIRED => [
                'topic_key' => self::ADMIN_CONSENT_REQUIRED,
                'surface_families' => ['onboarding', 'support_diagnostics'],
                'headline' => 'Admin consent required',
                'short_explanation' => 'This workflow is blocked until admin consent is granted for the current provider connection.',
                'troubleshooting_steps' => [
                    'Grant admin consent for the current provider connection.',
                    'Re-run verification or reopen support diagnostics after consent completes.',
                ],
                'safe_next_action' => 'Grant admin consent and re-run verification.',
                'glossary_terms' => ['tenant', 'workspace', 'provider connection'],
                'docs_links' => [
                    [
                        'label' => 'Grant admin consent',
                        'kind' => 'action',
                        'resolver' => self::LINK_RESOLVER_ADMIN_CONSENT_PRIMARY,
                    ],
                    [
                        'label' => 'Admin consent guide',
                        'kind' => 'docs',
                        'url' => RequiredPermissionsLinks::adminConsentGuideUrl(),
                    ],
                ],
            ],
            self::REQUIRED_PERMISSIONS_MISSING => [
                'topic_key' => self::REQUIRED_PERMISSIONS_MISSING,
                'surface_families' => ['onboarding', 'support_diagnostics'],
                'headline' => 'Required permissions missing',
                'short_explanation' => 'The provider app is missing one or more required permissions for the current workflow.',
                'troubleshooting_steps' => [
                    'Review the required permissions matrix for the current tenant.',
                    'Refresh verification after the missing permissions are granted.',
                ],
                'safe_next_action' => 'Open required permissions and confirm the missing grants.',
                'glossary_terms' => ['tenant', 'workspace', 'provider connection'],
                'docs_links' => [
                    [
                        'label' => 'Open required permissions',
                        'kind' => 'action',
                        'resolver' => self::LINK_RESOLVER_REQUIRED_PERMISSIONS,
                    ],
                ],
            ],
            self::CONNECTION_UNHEALTHY => [
                'topic_key' => self::CONNECTION_UNHEALTHY,
                'surface_families' => ['onboarding', 'support_diagnostics'],
                'headline' => 'Provider connection needs review',
                'short_explanation' => 'The provider connection is degraded or unavailable, so the current result cannot be treated as healthy.',
                'troubleshooting_steps' => [
                    'Review the latest provider connection health signal.',
                    'Retry the workflow after the provider connection is healthy again.',
                ],
                'safe_next_action' => 'Review the provider connection before retrying.',
                'glossary_terms' => ['tenant', 'workspace', 'provider connection'],
                'docs_links' => [],
            ],
            self::VERIFICATION_STALE => [
                'topic_key' => self::VERIFICATION_STALE,
                'surface_families' => ['onboarding'],
                'headline' => 'Verification result is stale',
                'short_explanation' => 'The most recent verification result is too old or mismatched to trust for the current onboarding decision.',
                'troubleshooting_steps' => [
                    'Run verification again for the currently selected provider connection.',
                    'Use the refreshed result before continuing onboarding.',
                ],
                'safe_next_action' => 'Refresh verification before continuing onboarding.',
                'glossary_terms' => ['tenant', 'workspace', 'verification'],
                'docs_links' => [],
            ],
            self::VERIFICATION_FAILED => [
                'topic_key' => self::VERIFICATION_FAILED,
                'surface_families' => ['onboarding', 'support_diagnostics'],
                'headline' => 'Verification failed',
                'short_explanation' => 'The latest verification run did not produce a decision-grade result for the current tenant context.',
                'troubleshooting_steps' => [
                    'Review the blocking reason before retrying verification.',
                    'Confirm the prerequisite is fixed, then run verification again.',
                ],
                'safe_next_action' => 'Review the blocking reason and retry verification.',
                'glossary_terms' => ['tenant', 'workspace', 'verification'],
                'docs_links' => [],
            ],
            self::DIAGNOSTIC_EVIDENCE_INCOMPLETE => [
                'topic_key' => self::DIAGNOSTIC_EVIDENCE_INCOMPLETE,
                'surface_families' => ['support_diagnostics'],
                'headline' => 'Diagnostic evidence is incomplete',
                'short_explanation' => 'Support diagnostics can summarize the issue, but the available evidence is not complete enough for a final conclusion.',
                'troubleshooting_steps' => [
                    'Review the available evidence and supporting references in the current support context.',
                    'Collect a fresh verification or operation result before making a final decision.',
                ],
                'safe_next_action' => 'Collect a fresher or more complete diagnostic signal.',
                'glossary_terms' => ['support diagnostics', 'evidence', 'workspace'],
                'docs_links' => [],
            ],
            self::RETRYABLE_PROVIDER_FAILURE => [
                'topic_key' => self::RETRYABLE_PROVIDER_FAILURE,
                'surface_families' => ['support_diagnostics'],
                'headline' => 'Provider failure looks retryable',
                'short_explanation' => 'The current provider issue appears temporary, so the next safe step is to retry once the dependency recovers.',
                'troubleshooting_steps' => [
                    'Confirm the provider dependency has recovered.',
                    'Retry the workflow after the provider-side issue clears.',
                ],
                'safe_next_action' => 'Retry after the provider dependency recovers.',
                'glossary_terms' => ['support diagnostics', 'provider connection', 'workspace'],
                'docs_links' => [],
            ],
            self::MANUAL_HANDOFF_REQUIRED => [
                'topic_key' => self::MANUAL_HANDOFF_REQUIRED,
                'surface_families' => ['support_diagnostics'],
                'headline' => 'Manual support handoff required',
                'short_explanation' => 'TenantPilot can summarize the current issue, but a human support handoff is still required for the next step.',
                'troubleshooting_steps' => [
                    'Review the current references before handing off the case.',
                    'Capture the safe next step and the supporting evidence for the receiving operator.',
                ],
                'safe_next_action' => 'Hand off the case with the current diagnostic summary and supporting references.',
                'glossary_terms' => ['support diagnostics', 'tenant', 'workspace'],
                'docs_links' => [],
            ],
        ];
    }

    /**
     * @return array{
     *     topic_key: string,
     *     surface_families: list<string>,
     *     headline: string,
     *     short_explanation: string,
     *     troubleshooting_steps: list<string>,
     *     safe_next_action: string,
     *     glossary_terms: list<string>,
     *     docs_links: list<array{
     *         label: string,
     *         kind: string,
     *         url?: string,
     *         resolver?: string
     *     }>
     * }
     */
    public function definition(string $topicKey): array
    {
        $definition = $this->definitions()[trim($topicKey)] ?? null;

        if (! is_array($definition)) {
            throw new InvalidArgumentException('Unknown contextual help topic');
        }

        return $definition;
    }

    /**
     * @return array{
     *     version: int,
     *     topic_count: int,
     *     topics: list<array{
     *         topic_key: string,
     *         surface_families: list<string>,
     *         headline: string,
     *         short_explanation: string,
     *         troubleshooting_steps: list<string>,
     *         safe_next_action: string,
     *         glossary_terms: list<string>,
     *         docs_links: list<array{
     *             label: string,
     *             kind: string,
     *             url: ?string,
     *             resolver: ?string
     *         }>
     *     }>
     * }
     */
    public function knowledgeSource(): array
    {
        $topics = array_values(array_map(
            fn (array $definition): array => [
                'topic_key' => $definition['topic_key'],
                'surface_families' => $definition['surface_families'],
                'headline' => $definition['headline'],
                'short_explanation' => $definition['short_explanation'],
                'troubleshooting_steps' => $definition['troubleshooting_steps'],
                'safe_next_action' => $definition['safe_next_action'],
                'glossary_terms' => $definition['glossary_terms'],
                'docs_links' => array_values(array_map(
                    static fn (array $link): array => [
                        'label' => (string) $link['label'],
                        'kind' => (string) ($link['kind'] ?? 'url'),
                        'url' => isset($link['url']) && is_string($link['url']) ? $link['url'] : null,
                        'resolver' => isset($link['resolver']) && is_string($link['resolver']) ? $link['resolver'] : null,
                    ],
                    $definition['docs_links'],
                )),
            ],
            $this->definitions(),
        ));

        return [
            'version' => 1,
            'topic_count' => count($topics),
            'topics' => $topics,
        ];
    }
}
