<?php

declare(strict_types=1);

namespace Numinix\SeekmodoWordPress\WPBakery;

use Numinix\SeekmodoWordPress\Blocks\AttributeSchema;

/**
 * Sprint 11 PR 3 — `vc_map()` registration so the four Seekmodo
 * shortcodes appear in the Visual Composer "Add Element" picker.
 *
 * Only fires when WPBakery is active. The shortcode handlers
 * registered by {@see Shortcodes} stay armed regardless, so a
 * site author who later deactivates WPBakery still keeps the
 * ability to embed Seekmodo elements via raw shortcode.
 */
final class VcMap
{
    public const CATEGORY = 'Seekmodo';

    /**
     * @var array<string, array<int, array{element: string, title: string, icon: string, description: string}>>
     */
    private const ELEMENT_DESCRIPTORS = [
        'rows' => [
            ['element' => 'search',    'title' => 'Seekmodo Search Box',     'icon' => 'icon-wpb-ui-search', 'description' => 'AI-powered search input.'],
            ['element' => 'recommend', 'title' => 'Seekmodo Recommendations', 'icon' => 'icon-wpb-grid',     'description' => 'Related / popular product strip.'],
            ['element' => 'chat',      'title' => 'Seekmodo Chat',           'icon' => 'icon-wpb-message',   'description' => 'Conversational AI shopping assistant.'],
            ['element' => 'ask',       'title' => 'Seekmodo Ask AI',         'icon' => 'icon-wpb-lightbulb', 'description' => 'Single-turn Ask AI Q&A widget.'],
            ['element' => 'quiz',      'title' => 'Seekmodo Quiz',           'icon' => 'icon-wpb-form',      'description' => 'AI shopping quiz / product finder.'],
        ],
    ];

    public static function register(): void
    {
        if (!function_exists('vc_map')) {
            return;
        }

        foreach (self::ELEMENT_DESCRIPTORS['rows'] as $row) {
            vc_map(self::descriptorFor($row['element'], $row['title'], $row['icon'], $row['description']));
        }
    }

    /**
     * Build the `vc_map()` argument for one element. Public for
     * unit tests.
     *
     * @return array<string, mixed>
     */
    public static function descriptorFor(string $element, string $title, string $icon, string $description): array
    {
        $tag = Shortcodes::tagFor($element) ?? '';

        return [
            'name'        => $title,
            'base'        => $tag,
            'category'    => self::CATEGORY,
            'icon'        => $icon,
            'description' => $description,
            'params'      => self::paramsFor($element),
        ];
    }

    /**
     * Map the AttributeSchema for an element to a list of
     * `vc_map()` `params` entries.
     *
     * Type mapping mirrors the AbstractSeekmodoWidget control map:
     *   string  -> textfield (or textarea for long-form attrs)
     *   number  -> textfield (visual-composer has no native
     *              number input; the shortcode renderer coerces)
     *   boolean -> checkbox  (value="1" if checked)
     *
     * @return list<array<string, mixed>>
     */
    public static function paramsFor(string $element): array
    {
        $params = [];
        foreach (AttributeSchema::attributesFor($element) as $attr) {
            $param = [
                'param_name'  => Shortcodes::camelToSnake($attr['key']),
                'heading'     => $attr['label'],
                'description' => $attr['description'],
            ];

            switch ($attr['type']) {
                case 'boolean':
                    $param['type']    = 'checkbox';
                    $param['value']   = ['Enabled' => '1'];
                    $param['std']     = $attr['default'] ? '1' : '';
                    break;
                case 'number':
                    $param['type'] = 'textfield';
                    $param['std']  = (string) ($attr['default'] ?? '');
                    break;
                case 'string':
                default:
                    if (in_array($attr['key'], ['intro', 'inlineDefinition'], true)) {
                        $param['type'] = 'textarea';
                    } else {
                        $param['type'] = 'textfield';
                    }
                    $param['std'] = (string) ($attr['default'] ?? '');
                    break;
            }

            $params[] = $param;
        }

        return $params;
    }
}
