<?php

namespace Storeplugin\PDFInvoice\Framework\Fields;

defined('ABSPATH') || exit;

use Storeplugin\PDFInvoice\Framework\Abstracts\AbstractFieldRenderer;
use Storeplugin\PDFInvoice\Config;

class FieldRenderer extends AbstractFieldRenderer
{
    /**
     * Resolve the renderer to use when app-specific fields are available.
     *
     * @return class-string<\Storeplugin\PDFInvoice\Framework\Abstracts\AbstractFieldRenderer>
     */
    private static function resolveRendererClass(): string
    {
        $app_renderer = Config::appFieldRenderer();

        if (class_exists($app_renderer) && is_subclass_of($app_renderer, AbstractFieldRenderer::class)) {
            return $app_renderer;
        }

        return self::class;
    }

    /**
     * Register a field type handler.
     *
     * @param string $type  Field type identifier.
     * @param string $class Fully-qualified class name implementing FieldInterface.
     * @return void
     */
    public static function register(string $type, string $class): void
    {
        $renderer = self::resolveRendererClass();

        if ($renderer !== self::class) {
            $renderer::register($type, $class);
            return;
        }

        parent::register($type, $class);
    }

    /**
     * Render a field's HTML
     *
     * @param array  $field       Field definition
     * @param mixed  $value       Current value
     * @param string $name_prefix Prefix for the input name attribute
     * @param bool   $wrapped     Whether to wrap the field with label and container
     * @param bool   $echo        Whether to echo the output immediately
     * @return string Escaped HTML output (safe to use without additional escaping)
     */
    public static function render($field, $value = null, string $name_prefix = '', $wrapped = true, $echo = true)
    {
        $renderer = self::resolveRendererClass();

        if ($renderer !== self::class) {
            return $renderer::render($field, $value, $name_prefix, $wrapped, $echo);
        }

        return parent::render($field, $value, $name_prefix, $wrapped, $echo);
    }

    /**
     * Render a sub-field inside a compound field (e.g., repeater).
     *
     * @param array  $field     Sub-field definition.
     * @param mixed  $value     Current value.
     * @param string $rawPrefix Unsanitized name prefix (may contain brackets).
     * @return string HTML output.
     */
    public static function renderSubField(array $field, $value, string $rawPrefix): string
    {
        $renderer = self::resolveRendererClass();

        if ($renderer !== self::class) {
            return $renderer::renderSubField($field, $value, $rawPrefix);
        }

        return parent::renderSubField($field, $value, $rawPrefix);
    }

    /**
     * Define the field type map for the framework renderer.
     *
     * @return array<string, class-string<\Storeplugin\PDFInvoice\Framework\Contracts\FieldInterface>>
     */
    protected static function getFieldTypes(): array
    {
        return parent::getBaseFieldTypes();
    }
}
