<?php

/**
 * LolaCore — Hub Fleet Abilities Registrar
 *
 * @package LolaCore
 * @license GPL-2.0-or-later
 */

declare(strict_types=1);

namespace LolaCore\Hub;

// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

/**
 * Registers fleet-facing abilities for sprint C3/C4 (health, provisioning, memory reconcile).
 */
final class HubFleetAbilitiesRegistrar
{
    public function register(): void
    {
        add_action('wp_abilities_api_init', [$this, 'registerAbilities']);
    }

    public function registerAbilities(): void
    {
        if (! function_exists('wp_register_ability')) {
            return;
        }

        $this->registerGetSiteHealth();
        $this->registerApplyAgencyProfile();
        $this->registerSetProvider();
        $this->registerReceiveMemoryReconcile();
        $this->registerReadSiteMemory();
    }

    private function registerGetSiteHealth(): void
    {
        wp_register_ability('lolacore/get-site-health', [
            'label'               => __('Get Site Health', 'lolacore'),
            'description'         => __('Aggregated health snapshot for LolaHub fleet queries, including a maintenance and security posture block (SSL, backups detected, pending updates, PHP support).', 'lolacore'),
            'category'            => 'lolacore',
            'input_schema'        => [
                'type'       => 'object',
                'properties' => [
                    'force_refresh'         => [
                        'type'        => 'boolean',
                        'description' => 'Bypass the cached health snapshot.',
                        'default'     => false,
                    ],
                    'recent_actions_limit'  => [
                        'type'        => 'integer',
                        'description' => 'Number of recent actions to include (1-50).',
                        'default'     => 10,
                        'minimum'     => 1,
                        'maximum'     => 50,
                    ],
                ],
            ],
            'output_schema'       => [
                'type'       => 'object',
                'properties' => [
                    'wp_version'       => ['type' => 'string'],
                    'lolacore_version' => ['type' => 'string'],
                    'addons'           => ['type' => 'array'],
                    'pending_updates'  => ['type' => 'object'],
                    'maintenance'      => ['type' => 'object'],
                    'recent_actions'   => ['type' => 'array'],
                    'scan_summary'     => ['type' => 'object'],
                ],
            ],
            'permission_callback' => static fn() => current_user_can('manage_options'),
            'execute_callback'    => [$this, 'executeGetSiteHealth'],
            'meta'                => $this->metaBlock(true, false, true),
        ]);
    }

    private function registerApplyAgencyProfile(): void
    {
        wp_register_ability('lolacore/apply-agency-profile', [
            'label'               => __('Apply Agency Profile', 'lolacore'),
            'description'         => __('Receive playbooks, skills, and agency preferences from the LolaHub master.', 'lolacore'),
            'category'            => 'lolacore',
            'input_schema'        => [
                'type'       => 'object',
                'properties' => [
                    'playbooks'   => [
                        'type'  => 'array',
                        'items' => [
                            'type'       => 'object',
                            'properties' => [
                                'slug'     => ['type' => 'string'],
                                'content'  => ['type' => 'string'],
                                'activate' => ['type' => 'boolean'],
                            ],
                            'required'   => ['slug', 'content'],
                        ],
                    ],
                    'skills'      => [
                        'type'  => 'array',
                        'items' => [
                            'type'       => 'object',
                            'properties' => [
                                'skill_name' => ['type' => 'string'],
                                'content'    => ['type' => 'string'],
                                'activate'   => ['type' => 'boolean'],
                            ],
                            'required'   => ['skill_name', 'content'],
                        ],
                    ],
                    'preferences' => [
                        'type'                 => 'object',
                        'additionalProperties' => true,
                    ],
                ],
            ],
            'output_schema'       => [
                'type'       => 'object',
                'properties' => [
                    'applied' => ['type' => 'object'],
                    'updated' => ['type' => 'object'],
                    'omitted' => ['type' => 'object'],
                ],
            ],
            'permission_callback' => static fn() => current_user_can('manage_options'),
            'execute_callback'    => [$this, 'executeApplyAgencyProfile'],
            'meta'                => $this->metaBlock(false, false, false),
        ]);
    }

    private function registerSetProvider(): void
    {
        wp_register_ability('lolacore/set-provider', [
            'label'               => __('Set AI Provider', 'lolacore'),
            'description'         => __('Configure the Connectors provider/model for local Lola chat when applicable.', 'lolacore'),
            'category'            => 'lolacore',
            'input_schema'        => [
                'type'       => 'object',
                'properties' => [
                    'provider' => [
                        'type'        => 'string',
                        'description' => 'Connectors provider slug.',
                        'minLength'   => 1,
                    ],
                    'model'    => [
                        'type'        => 'string',
                        'description' => 'Provider model id.',
                        'minLength'   => 1,
                    ],
                ],
                'required'   => ['provider', 'model'],
            ],
            'output_schema'       => [
                'type'       => 'object',
                'properties' => [
                    'applied'  => ['type' => 'boolean'],
                    'noop'     => ['type' => 'boolean'],
                    'provider' => ['type' => 'string'],
                    'model'    => ['type' => 'string'],
                ],
            ],
            'permission_callback' => static fn() => current_user_can('manage_options'),
            'execute_callback'    => [$this, 'executeSetProvider'],
            'meta'                => $this->metaBlock(false, false, true),
        ]);
    }

    private function registerReceiveMemoryReconcile(): void
    {
        wp_register_ability('lolacore/receive-memory-reconcile', [
            'label'               => __('Receive Memory Reconcile', 'lolacore'),
            'description'         => __('Batch push of fleet-authored memory facts into the child site (merge + dedupe).', 'lolacore'),
            'category'            => 'lolacore',
            'input_schema'        => [
                'type'       => 'object',
                'properties' => [
                    'facts' => [
                        'type'  => 'array',
                        'items' => [
                            'type'       => 'object',
                            'properties' => [
                                'fact_type'  => ['type' => 'string'],
                                'content'    => ['type' => 'string'],
                                'fact_hash'  => ['type' => 'string'],
                                'importance' => ['type' => 'integer', 'minimum' => 1, 'maximum' => 10],
                            ],
                            'required'   => ['fact_type', 'content'],
                        ],
                    ],
                ],
                'required'   => ['facts'],
            ],
            'output_schema'       => [
                'type'       => 'object',
                'properties' => [
                    'received'           => ['type' => 'integer'],
                    'inserted'           => ['type' => 'integer'],
                    'skipped_duplicates' => ['type' => 'integer'],
                    'watermark'          => ['type' => 'object'],
                ],
            ],
            'permission_callback' => static fn() => current_user_can('manage_options'),
            'execute_callback'    => [$this, 'executeReceiveMemoryReconcile'],
            'meta'                => $this->metaBlock(false, false, true),
        ]);
    }

    private function registerReadSiteMemory(): void
    {
        wp_register_ability('lolacore/read-site-memory', [
            'label'               => __('Read Site Memory', 'lolacore'),
            'description'         => __('Export owner memory facts for LolaHub seed/adoption (pull reconcile).', 'lolacore'),
            'category'            => 'lolacore',
            'input_schema'        => [
                'type'       => 'object',
                'properties' => [
                    'types' => [
                        'type'  => 'array',
                        'items' => ['type' => 'string'],
                    ],
                    'include_business_context' => [
                        'type'    => 'boolean',
                        'default' => false,
                    ],
                    'limit' => [
                        'type'    => 'integer',
                        'minimum' => 1,
                        'maximum' => 500,
                        'default' => 100,
                    ],
                ],
            ],
            'output_schema'       => [
                'type'       => 'object',
                'properties' => [
                    'facts'     => ['type' => 'array'],
                    'watermark' => ['type' => 'object'],
                    'types'     => ['type' => 'array'],
                ],
            ],
            'permission_callback' => static fn() => current_user_can('manage_options'),
            'execute_callback'    => [$this, 'executeReadSiteMemory'],
            'meta'                => $this->metaBlock(true, false, true),
        ]);
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>|\WP_Error
     */
    public function executeGetSiteHealth(array $input)
    {
        do_action('lolacore_ability_invoked', 'lolacore/get-site-health', $input, 'rest');

        $payload = (new HubSiteHealth())->get($input);

        return apply_filters('lolacore_ability_output', $payload, 'lolacore/get-site-health');
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>|\WP_Error
     */
    public function executeApplyAgencyProfile(array $input)
    {
        do_action('lolacore_ability_invoked', 'lolacore/apply-agency-profile', $input, 'rest');

        $result = (new HubAgencyProfileService())->apply($input);

        return apply_filters('lolacore_ability_output', $result, 'lolacore/apply-agency-profile');
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>|\WP_Error
     */
    public function executeSetProvider(array $input)
    {
        do_action('lolacore_ability_invoked', 'lolacore/set-provider', $input, 'rest');

        $result = (new HubProviderService())->apply($input);

        return apply_filters('lolacore_ability_output', $result, 'lolacore/set-provider');
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>|\WP_Error
     */
    public function executeReceiveMemoryReconcile(array $input)
    {
        do_action('lolacore_ability_invoked', 'lolacore/receive-memory-reconcile', $input, 'rest');

        $result = (new HubMemoryReconcileService())->receive($input);

        return apply_filters('lolacore_ability_output', $result, 'lolacore/receive-memory-reconcile');
    }

    /**
     * @param array<string, mixed> $input
     * @return array<string, mixed>
     */
    public function executeReadSiteMemory(array $input)
    {
        do_action('lolacore_ability_invoked', 'lolacore/read-site-memory', $input, 'rest');

        $result = (new HubMemoryReconcileService())->readForPull($input);

        return apply_filters('lolacore_ability_output', $result, 'lolacore/read-site-memory');
    }

    /**
     * @return array<string, mixed>
     */
    private function metaBlock(bool $readonly, bool $destructive, bool $idempotent): array
    {
        return [
            'show_in_rest' => true,
            'mcp'          => [
                'public' => true,
                'type'   => 'tool',
            ],
            'annotations'  => [
                'readonly'    => $readonly,
                'destructive' => $destructive,
                'idempotent'  => $idempotent,
            ],
        ];
    }
}
