<?php
/**
 * Tools UI schema provider.
 *
 * @package NimblyMail\SMTP
 */

namespace NimblyMail\SMTP;

defined( 'ABSPATH' ) || exit;

/**
 * Class ToolsProvider
 *
 * Provides the structured schema for the Vue frontend tools tabs.
 * Mirrors SettingsProvider but for the Tools admin page. Built-in tools
 * use custom renderers (existing Vue components). Third-party tools declared
 * via the nimblymail_get_tools filter are rendered generically.
 *
 * @since 1.0.0
 */
class ToolsProvider {

    /**
     * Singleton instance.
     *
     * @var self|null
     */
    private static ?self $instance = null;

    /**
     * Get the singleton instance.
     *
     * @since 1.0.0
     *
     * @return self
     */
    public static function get_instance(): self {
        if ( null === self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    /**
     * Get the registered tools array.
     *
     * Returns the two built-in tools (email-tester, import) plus any tools
     * registered via the nimblymail_get_tools filter. Every tool is passed
     * through normalize_tool() before being returned so consumers can rely
     * on a consistent shape.
     *
     * @since 1.0.0
     *
     * @return array<int, array<string, mixed>> Normalized tool descriptors.
     */
    public function get_tools(): array {
        $tools = array(
            array(
                'id'       => 'email-test',
                'label'    => __( 'Email Tester', 'nimblymail-smtp' ),
                'icon'     => 'SendOutlined',
                'renderer' => 'email-tester',
            ),
            array(
                'id'       => 'import',
                'label'    => __( 'Import', 'nimblymail-smtp' ),
                'icon'     => 'ImportOutlined',
                'renderer' => 'import',
            ),
        );

        /**
         * Filter the list of tools shown on the Tools admin page.
         *
         * Each tool is a PHP associative array. Built-in tools use a
         * `renderer` key that maps to a registered Vue custom renderer.
         * Third-party tools omit `renderer` and are rendered generically
         * by GenericTool.vue using the `fields` and `actions` keys.
         *
         * @since 1.0.0
         *
         * @param array<int, array<string, mixed>> $tools Tool descriptor array.
         */
        $tools = apply_filters( 'nimblymail_get_tools', $tools );

        return array_map( array( $this, 'normalize_tool' ), $tools );
    }

    /**
     * Fill in missing keys on a tool descriptor with safe defaults.
     *
     * Ensures the Vue layer always receives a consistent shape regardless
     * of how much a third-party author omitted from their descriptor.
     *
     * @since 1.0.0
     *
     * @param array<string, mixed> $tool Raw tool descriptor from the filter.
     *
     * @return array<string, mixed> Normalized tool descriptor.
     */
    private function normalize_tool( array $tool ): array {
        return array_merge(
            array(
                'description' => '',
                'fields'      => array(),
                'actions'     => array(),
                'renderer'    => null,
                'icon'        => '',
            ),
            $tool
        );
    }
}
