<?php
namespace PpPhp\Plugins;
use PpPhp\Core\ViewPlugin;

/**
 * Badge / button view — display a field value as a styled badge or button.
 * Variant (solid/light/outline), shape, size, optional icon, and a
 * per-value color map (e.g. active=success, pending=warning, default=…)
 * so status columns render as meaningful colored chips. Optionally a link
 * whose href is a template with {value} substituted.
 */
class Badge implements ViewPlugin
{
    private const COLORS = ['primary', 'info', 'success', 'warning', 'danger', 'secondary', 'dark'];

    public static function id(): string { return 'Badge'; }
    public static function label(): string { return 'Badge / Button'; }
    public static function version(): string { return '1.0.0'; }
    public static function description(): string { return 'Displays a value as a coloured pill/badge.'; }

    public static function render(mixed $value, array $settings): string
    {
        $val = (string) ($value ?? '');
        if ($val === '') return '<span class="pp-muted">—</span>';

        $variant = (string) ($settings['variant'] ?? 'solid');
        $size = (string) ($settings['size'] ?? 'md'); if (!in_array($size, ['sm','md','lg'], true)) $size = 'md';
        $rounded = ($settings['shape'] ?? 'rounded') === 'rounded';
        $dot = in_array(strtolower((string) ($settings['dot'] ?? '')), ['1', 'yes', 'true', 'on'], true);
        $shape = ($variant === 'button') ? 'pp-b2' : 'pp-bdg';

        // per-value color map: "active:success, pending:warning, *:secondary"
        $color = self::colorFor($val, $settings);

        $cls = $shape . ' pp-bc-' . $color . ' pp-bz-' . $size
            . ($variant === 'outline' ? ' is-outline' : ($variant === 'light' ? ' is-light' : ''))
            . ($rounded ? ' is-rounded' : '') . ($dot && $shape === 'pp-bdg' ? ' is-dot' : '');

        $icon = trim((string) ($settings['icon'] ?? ''));
        $iconHtml = $icon !== '' ? '<i class="bi ' . htmlspecialchars($icon) . '"></i>' : '';

        // optional label remap (value:Label pairs) — else show the raw value
        $label = self::labelFor($val, $settings);
        $inner = $iconHtml . htmlspecialchars($label);

        $href = trim((string) ($settings['link'] ?? ''));
        if ($href !== '') {
            $url = str_replace('{value}', rawurlencode($val), $href);
            return '<a class="' . $cls . '" href="' . htmlspecialchars($url) . '">' . $inner . '</a>';
        }

        return '<span class="' . $cls . '">' . $inner . '</span>';
    }

    private static function colorFor(string $val, array $settings): string
    {
        $default = (string) ($settings['color'] ?? 'primary'); if (!in_array($default, self::COLORS, true)) $default = 'primary';
        foreach (explode(',', (string) ($settings['colorMap'] ?? '')) as $pair) {
            $pair = trim($pair);
            if (!str_contains($pair, ':')) continue;
            [$k, $c] = array_map('trim', explode(':', $pair, 2));
            if (!in_array($c, self::COLORS, true)) continue;
            if ($k === '*' ) $default = $c;
            if (strcasecmp($k, $val) === 0) return $c;
        }
        return $default;
    }

    private static function labelFor(string $val, array $settings): string
    {
        foreach (explode(',', (string) ($settings['labelMap'] ?? '')) as $pair) {
            $pair = trim($pair);
            if (!str_contains($pair, ':')) continue;
            [$k, $l] = array_map('trim', explode(':', $pair, 2));
            if (strcasecmp($k, $val) === 0) return $l;
        }
        return $val;
    }

    public static function settingsSchema(): array
    {
        return [
            ['key' => 'variant', 'label' => 'Style', 'type' => 'select', 'options' => ['solid', 'light', 'outline', 'button'], 'default' => 'solid'],
            ['key' => 'color', 'label' => 'Default color', 'type' => 'select', 'options' => self::COLORS, 'default' => 'primary'],
            ['key' => 'colorMap', 'label' => 'Color by value', 'type' => 'text', 'default' => '', 'hint' => "value:color pairs. Example: active:success, pending:warning, closed:danger, *:secondary"],
            ['key' => 'labelMap', 'label' => 'Label by value', 'type' => 'text', 'default' => '', 'hint' => "value:Label pairs. Example: 1:Active, 0:Inactive"],
            ['key' => 'shape', 'label' => 'Shape', 'type' => 'select', 'options' => ['rounded', 'square'], 'default' => 'rounded'],
            ['key' => 'size', 'label' => 'Size', 'type' => 'select', 'options' => ['sm', 'md', 'lg'], 'default' => 'md'],
            ['key' => 'dot', 'label' => 'Leading dot', 'type' => 'bool', 'default' => 'no'],
            ['key' => 'icon', 'label' => 'Icon (bi-…)', 'type' => 'text', 'default' => ''],
            ['key' => 'link', 'label' => 'Link URL ({value})', 'type' => 'text', 'default' => '', 'hint' => 'Optional. {value} is replaced with the field value.'],
        ];
    }

    public static function assets(): array { return ['js' => [], 'css' => []]; }
}
