<?php
/**
 * Door 3 registration helpers for B3 governance abilities.
 *
 * @package LolaCoreForBricks
 */

declare(strict_types=1);

namespace LolaCoreForBricks;

use LolaCoreForBricks\Handlers\GovernanceHandler;
use LolaCoreForBricks\Support\AbilityI18n;

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

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

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeFindUnusedClasses(array $input): array
    {
        return (new GovernanceHandler())->findUnusedClasses($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeFindDuplicateClasses(array $input): array
    {
        return (new GovernanceHandler())->findDuplicateClasses($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeFindUnusedVariables(array $input): array
    {
        return (new GovernanceHandler())->findUnusedVariables($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeFindOrphanComponents(array $input): array
    {
        return (new GovernanceHandler())->findOrphanComponents($input);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeFindThemeStyleConflicts(array $input): array
    {
        return (new GovernanceHandler())->findThemeStyleConflicts($input);
    }

    private function callbackMethod(string $actionId): string
    {
        return match ($actionId) {
            'find_unused_classes'        => 'executeFindUnusedClasses',
            'find_duplicate_classes'       => 'executeFindDuplicateClasses',
            'find_unused_variables'        => 'executeFindUnusedVariables',
            'find_orphan_components'       => 'executeFindOrphanComponents',
            'find_theme_style_conflicts'   => 'executeFindThemeStyleConflicts',
            default                        => 'executeFindUnusedClasses',
        };
    }

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

        return match ($actionId) {
            'find_unused_classes' => array_merge($pagination, [
                'include_trash' => ['type' => 'boolean'],
            ]),
            'find_duplicate_classes' => array_merge($pagination, [
                'threshold' => ['type' => 'number'],
            ]),
            default => $pagination,
        };
    }

    /**
     * @return array<string, array<string, string>>
     */
    private function outputSchema(): array
    {
        return [
            'success'          => ['type' => 'boolean'],
            'message'          => ['type' => 'string'],
            'coverage'         => ['type' => 'object'],
            'coverage_notice'  => ['type' => 'string'],
            'total'            => ['type' => 'integer'],
            'truncated'        => ['type' => 'boolean'],
        ];
    }
}
