<?php
declare(strict_types=1);

namespace App\Support;

/**
 * Stable extension contract for filesystem plugins.
 *
 * Plugins should reference these constants rather than inventing hook names.
 * The catalog is intentionally small: Quaeriva is not a general-purpose CMS
 * and every public extension point becomes a compatibility promise.
 */
final class CoreHooks
{
    public const USER_REGISTERED = 'user.registered';
    public const QUESTION_CREATED = 'question.created';
    public const QUESTION_PUBLISHED = 'question.published';
    public const ANSWER_CREATED = 'answer.created';
    public const ANSWER_PUBLISHED = 'answer.published';
    public const ANSWER_ACCEPTED = 'answer.accepted';
    public const COMMENT_CREATED = 'comment.created';
    public const TOPIC_CREATED = 'topic.created';
    public const TOPIC_PUBLISHED = 'topic.published';
    public const TOPIC_UPDATED = 'topic.updated';
    public const TOPIC_COMMENT_CREATED = 'topic.comment_created';
    public const TOPIC_LOCKED = 'topic.locked';
    public const TOPIC_UNLOCKED = 'topic.unlocked';

    public const SEO_META = 'seo.meta';
    public const SEO_STRUCTURED_DATA = 'seo.structured_data';
    public const SITEMAP_ENTRIES = 'sitemap.entries';
    public const SPAM_ASSESSMENT = 'spam.assessment';
    public const WIDGETS_REGISTER = 'widgets.register';
    public const MENU_ITEMS = 'menu.items';
    public const NOTIFICATION_CHANNELS = 'notification.channels';

    /** @return array<string,array{type:'action'|'filter',since:string,description:string}> */
    public static function catalog(): array
    {
        return [
            self::USER_REGISTERED => self::action('0.8.0', 'A member registration was committed.'),
            self::QUESTION_CREATED => self::action('0.8.0', 'A question was created, including pending questions.'),
            self::QUESTION_PUBLISHED => self::action('0.8.0', 'A question became publicly visible.'),
            self::ANSWER_CREATED => self::action('0.8.0', 'An answer was created, including pending answers.'),
            self::ANSWER_PUBLISHED => self::action('0.8.2', 'An answer became publicly visible.'),
            self::ANSWER_ACCEPTED => self::action('0.8.0', 'An answer was accepted for a question.'),
            self::COMMENT_CREATED => self::action('0.8.2', 'A question, answer, or topic comment was created.'),
            self::TOPIC_CREATED => self::action('0.8.1', 'A discussion topic was created, including pending topics.'),
            self::TOPIC_PUBLISHED => self::action('0.8.1', 'A discussion topic became publicly visible.'),
            self::TOPIC_UPDATED => self::action('0.8.1', 'A discussion topic changed.'),
            self::TOPIC_COMMENT_CREATED => self::action('0.8.2', 'A published comment was added to a topic.'),
            self::TOPIC_LOCKED => self::action('0.8.1', 'A topic was locked.'),
            self::TOPIC_UNLOCKED => self::action('0.8.1', 'A topic was unlocked.'),
            self::SEO_META => self::filter('0.8.3', 'Filter safe public meta values before rendering.'),
            self::SEO_STRUCTURED_DATA => self::filter('0.8.3', 'Filter JSON-LD data before rendering.'),
            self::SITEMAP_ENTRIES => self::filter('0.8.3', 'Filter a generated sitemap entry list.'),
            self::SPAM_ASSESSMENT => self::filter('0.8.3', 'Adjust a SpamAssessment after core scoring.'),
            self::WIDGETS_REGISTER => self::filter('0.8.3', 'Extend the public widget registry.'),
            self::MENU_ITEMS => self::filter('0.8.3', 'Filter visible managed menu items.'),
            self::NOTIFICATION_CHANNELS => self::filter('0.8.3', 'Extend the notification channel registry.'),
        ];
    }

    /** @return array{type:'action',since:string,description:string} */
    private static function action(string $since, string $description): array
    {
        return ['type' => 'action', 'since' => $since, 'description' => $description];
    }

    /** @return array{type:'filter',since:string,description:string} */
    private static function filter(string $since, string $description): array
    {
        return ['type' => 'filter', 'since' => $since, 'description' => $description];
    }
}
