<?php
/**
 * Door 3 registration helpers for B2 knowledge abilities.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks;

use LolaCoreForBricks\Handlers\KnowledgeHandler;
use LolaCoreForBricks\Support\AbilityI18n;

/**
 * Registers knowledge read abilities on the WordPress Abilities API.
 */
final class KnowledgeWpRegistrar
{
    public function registerAbilities(WPAbilitiesRegistrar $registrar): void
    {
        if (!function_exists('wp_register_ability')) {
            return;
        }

        foreach (KnowledgeAbilityMap::entries() as $actionId => $entry) {
            $callback = $this->callbackMethod($actionId);
            $registrar->registerKnowledgeReadAbility(
                $entry['slug'],
                AbilityI18n::label($actionId),
                AbilityI18n::description($actionId),
                $this->inputSchema($actionId),
                $this->outputSchema($actionId),
                [$this, $callback]
            );
        }
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetGlobalClasses(array $input): array
    {
        return (new KnowledgeHandler())->getGlobalClasses($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetClassUsage(array $input): array
    {
        return (new KnowledgeHandler())->getClassUsage($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetGlobalVariables(array $input): array
    {
        return (new KnowledgeHandler())->getGlobalVariables($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetVariableUsage(array $input): array
    {
        return (new KnowledgeHandler())->getVariableUsage($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetThemeStyles(array $input): array
    {
        return (new KnowledgeHandler())->getThemeStyles($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetComponents(array $input): array
    {
        return (new KnowledgeHandler())->getComponents($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetComponentUsage(array $input): array
    {
        return (new KnowledgeHandler())->getComponentUsage($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetTemplates(array $input): array
    {
        return (new KnowledgeHandler())->getTemplates($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeResolveTemplateForPage(array $input): array
    {
        return (new KnowledgeHandler())->resolveTemplateForPage($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeDescribeElementControls(array $input): array
    {
        return (new KnowledgeHandler())->describeElementControls($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeGetBricksOperatingGuide(array $input): array
    {
        return (new KnowledgeHandler())->getBricksOperatingGuide($input);
    }

    private function callbackMethod(string $actionId): string
    {
        return match ($actionId) {
            'get_global_classes'          => 'executeGetGlobalClasses',
            'get_class_usage'             => 'executeGetClassUsage',
            'get_global_variables'        => 'executeGetGlobalVariables',
            'get_variable_usage'          => 'executeGetVariableUsage',
            'get_theme_styles'            => 'executeGetThemeStyles',
            'get_components'              => 'executeGetComponents',
            'get_component_usage'         => 'executeGetComponentUsage',
            'get_templates'               => 'executeGetTemplates',
            'resolve_template_for_page'   => 'executeResolveTemplateForPage',
            'describe_element_controls'   => 'executeDescribeElementControls',
            'get_bricks_operating_guide'  => 'executeGetBricksOperatingGuide',
            default                       => 'executeGetGlobalClasses',
        };
    }

    /**
     * @return array<string, array<string, string>>
     */
    private function inputSchema(string $actionId): array
    {
        $pagination = [
            'limit'  => ['type' => 'integer'],
            'offset' => ['type' => 'integer'],
        ];

        return match ($actionId) {
            'get_global_classes' => array_merge($pagination, [
                'category'      => ['type' => 'string'],
                'include_trash' => ['type' => 'boolean'],
            ]),
            'get_class_usage' => array_merge($pagination, [
                'class' => ['type' => 'string'],
            ]),
            'get_global_variables' => array_merge($pagination, [
                'category' => ['type' => 'string'],
            ]),
            'get_variable_usage' => array_merge($pagination, [
                'variable' => ['type' => 'string'],
            ]),
            'get_theme_styles', 'get_components' => $pagination,
            'get_templates' => array_merge($pagination, [
                'type' => ['type' => 'string'],
            ]),
            'get_component_usage' => array_merge($pagination, [
                'component' => ['type' => 'string'],
            ]),
            'resolve_template_for_page' => [
                'post_id' => ['type' => 'integer'],
            ],
            'describe_element_controls' => [
                'element_name' => ['type' => 'string'],
                'group'        => ['type' => 'string'],
            ],
            'get_bricks_operating_guide' => [
                'topic' => ['type' => 'string'],
            ],
            default => [],
        };
    }

    /**
     * @return array<string, array<string, string>>
     */
    private function outputSchema(string $actionId): array
    {
        $base = [
            'success' => ['type' => 'boolean'],
            'message' => ['type' => 'string'],
        ];

        $withCoverage = array_merge($base, ['coverage' => ['type' => 'object']]);
        $withPagination = array_merge($base, [
            'total'     => ['type' => 'integer'],
            'truncated' => ['type' => 'boolean'],
        ]);

        return match ($actionId) {
            'get_class_usage', 'get_variable_usage', 'get_component_usage', 'get_components' => $withCoverage,
            'get_global_classes', 'get_global_variables', 'get_theme_styles', 'get_templates' => $withPagination,
            default => $base,
        };
    }
}
