<?php

declare(strict_types=1);

namespace PpPhp\Plugins;

use PpPhp\Core\PluginSupport;
use PpPhp\Core\ViewPlugin;

/**
 * Renders a field value as a QR image.
 *
 * PRIVACY NOTE: by default this uses an EXTERNAL QR service, which means the
 * field value is sent to that third party and the image breaks with no internet.
 * `referrerpolicy=no-referrer` keeps the app's own URL out of the request, but
 * the encoded value still leaves the server. For a fully local/offline QR, a
 * bundled generator is needed (tracked as a follow-up).
 */
class QRCode implements ViewPlugin
{
    use PluginSupport;

    private const DEFAULT_PROVIDER = 'https://api.qrserver.com/v1/create-qr-code/?size={s}x{s}&data={d}';

    public static function id(): string { return 'QRCode'; }
    public static function label(): string { return 'QR Code'; }
    public static function version(): string { return '1.1.0'; }
    public static function description(): string { return 'Renders a value as a QR image via an external service (data leaves the server — see settings).'; }

    public static function render(mixed $value, array $settings): string
    {
        $data = (string) ($value ?? '');
        if (trim($data) === '') return '';

        $size = (int) ($settings['size'] ?? 150);
        if ($size < 40) $size = 40;
        if ($size > 1000) $size = 1000;

        $provider = trim((string) ($settings['provider'] ?? '')) ?: self::DEFAULT_PROVIDER;
        // Only allow an https provider template; otherwise fall back to the default.
        if (\PpPhp\Core\Html\Sanitizer::url($provider, true) === null || stripos($provider, 'https://') !== 0) {
            $provider = self::DEFAULT_PROVIDER;
        }
        $url = str_replace(['{s}', '{d}'], [(string) $size, rawurlencode($data)], $provider);

        return '<img src="' . self::e($url) . '" width="' . $size . '" height="' . $size . '"'
            . ' loading="lazy" decoding="async" referrerpolicy="no-referrer"'
            . ' alt="QR code for ' . self::e($data) . '"'
            . ' onerror="this.replaceWith(document.createTextNode(this.alt))">';
    }

    public static function settingsSchema(): array
    {
        return [
            ['key' => 'size', 'type' => 'number', 'label' => 'Size (px)', 'default' => 150],
            ['key' => 'provider', 'type' => 'text', 'label' => 'QR service URL', 'default' => '',
             'hint' => 'Advanced: an https template with {s} (size) and {d} (url-encoded data). Blank = default service. Note: the value is sent to this service.'],
        ];
    }

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