<?php

namespace GriffinForms\Admin\App\Html\Widgets\PresentationArea\FormControls;

use GriffinForms\Items\FormTheme;

class Format extends \GriffinForms\Admin\App\Html\Widgets\PresentationArea\Format
{
    protected $item_id;
    protected $item;
    protected $form_theme;
    protected $printed_field_styles = array();
    private $is_theme_set = null;

    public function __construct(int $id, object $item, object $form_theme)
    {
        $this->item_id = $id;
        $this->item = $item;
        $this->form_theme = $form_theme;
        $this->setAll();
    }

    /**
     * Outputs scoped inline CSS for the provided field style types
     * using the current field as a namespace.
     * Only renders styles when a custom theme is assigned.
     *
     * @param array $style_types Array of field style keys (text_input, textarea, etc.)
     */
    protected function renderFieldStyles(array $style_types)
    {
        // Skip rendering if no theme is set (use Bootstrap fallback only)
        if (!$this->isThemeSet()) {
            return;
        }

        if (empty($style_types)) {
            return;
        }

        $style_types = array_unique(array_filter($style_types));
        $group_id = $this->getFieldStyleGroupId();
        $css_rules = '';

        foreach ($style_types as $style_type) {
            $style_key = sanitize_key($style_type);
            if (isset($this->printed_field_styles[$style_key])) {
                continue;
            }

            $group_css = sanitize_key($group_id);
            $selector = '[data-gf-style-group="' . $group_css . '"][data-gf-style-type="' . $style_key . '"]';

            $default_css = $this->form_theme->getFieldStyleCss($style_type, 'default');
            if ($default_css !== '') {
                $css_rules .= $selector . ' { ' . $default_css . ' }' . PHP_EOL;
            }

            $hover_css = $this->form_theme->getFieldStyleCss($style_type, 'hover');
            if ($hover_css !== '') {
                $css_rules .= $selector . ':hover { ' . $hover_css . ' }' . PHP_EOL;
            }

            $focus_css = $this->form_theme->getFieldStyleCss($style_type, 'focus');
            if ($focus_css !== '') {
                $css_rules .= $selector . ':focus, ' . $selector . ':focus-visible { ' . $focus_css . ' }' . PHP_EOL;
            }

            $this->printed_field_styles[$style_key] = true;
        }

        if ($css_rules !== '') {
            $css_rules = FormTheme::prepareStyleTagContent($css_rules);
            if ($css_rules !== '') {
                echo '<style>' . $css_rules . '</style>';
            } else {
                $this->log->add(
                    'notice',
                    'formtheme',
                    $this->item_id,
                    get_current_user_id(),
                    sprintf('Skipped empty field style output for group %s', $group_id),
                    'theme_preview'
                );
            }
        } elseif ($this->isThemeSet()) {
            $this->log->add(
                'info',
                'formtheme',
                $this->item_id,
                get_current_user_id(),
                sprintf('No CSS produced for style types (%s) in admin preview.', implode(', ', $style_types)),
                'theme_preview'
            );
        }
    }

    /**
     * Returns the data attributes required for a control element to
     * inherit the scoped field styles.
     *
     * @param string $style_type
     * @return string
     */
    protected function getFieldStyleAttributes($style_type)
    {
        return sprintf(
            ' data-gf-style-group="%s" data-gf-style-type="%s"',
            esc_attr($this->getFieldStyleGroupId()),
            esc_attr($style_type)
        );
    }

    /**
     * Returns the configured placeholder for this field, if any.
     *
     * @return string
     */
    protected function getFieldPlaceholder()
    {
        $placeholder = $this->item->getProp('placeholder');
        if (!is_scalar($placeholder)) {
            return '';
        }

        return trim((string) $placeholder);
    }

    /**
     * Generates a stable DOM id for a control element.
     *
     * @param string $suffix Optional suffix to make the id unique per element.
     * @return string
     */
    protected function getFieldControlId($suffix = '')
    {
        $base = 'gf-field-control-' . $this->item_id;
        if ($suffix !== '') {
            $base .= '-' . sanitize_key($suffix);
        }

        return $base;
    }

    /**
     * Returns the style group identifier for this field.
     *
     * @return string
     */
    protected function getFieldStyleGroupId()
    {
        return 'field-' . $this->item_id;
    }

    /**
     * Outputs scoped CSS for checkbox, radio, and terms condition labels
     * to apply the field label color for proper contrast and visual consistency.
     */
    protected function renderOptionLabelStyles()
    {
        // Get label color from the theme
        $label_color = $this->form_theme->getLabelColor();

        if (empty($label_color)) {
            return;
        }

        $group_id = sanitize_key($this->getFieldStyleGroupId());
        $selector = '[data-gf-style-group="' . $group_id . '"] label';
        $css_rules = $selector . ' { color: ' . esc_attr($label_color) . ' !important; }';
        $css_rules = FormTheme::prepareStyleTagContent($css_rules);
        if ($css_rules !== '') {
            echo '<style>' . $css_rules . '</style>';
        }
    }

    /**
     * Inlines an SVG from admin/images/toolbar-icons/builder/ with currentColor
     * normalisation and the gf-fe-action-svg class applied.
     */
    protected function echoToolbarSvg(string $filename)
    {
        $path = \GriffinForms\Config::getInstance()->getRootPath() . 'admin/images/toolbar-icons/builder/' . $filename;
        if (!file_exists($path)) {
            return;
        }
        $svg = file_get_contents($path);
        if ($svg === false || trim($svg) === '') {
            return;
        }
        $svg = preg_replace('/<svg\b([^>]*)>/i', '<svg$1 class="gf-fe-action-svg" aria-hidden="true" focusable="false">', $svg, 1);
        $svg = preg_replace('/\sfill="(?!none)([^"]*)"/i', ' fill="currentColor"', $svg);
        $svg = preg_replace('/\sstroke="(?!none)([^"]*)"/i', ' stroke="currentColor"', $svg);
        echo $svg; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
    }

    /**
     * Renders a horizontal sub-toolbar group: a .gf-sub-toolbar-composite--horizontal
     * wrapper containing the given buttons with no divider between them but one
     * divider before the group (provided by the standard .gf-sub-toolbar > * + * rule).
     *
     * $buttons is an array of arrays, each with:
     *   'class'    => string   semantic button class(es)
     *   'icon'     => string   filename in admin/images/toolbar-icons/builder/
     *   'label'    => string   aria-label value
     *   'disabled' => bool     optional, renders disabled attribute when true
     *
     * @param array $buttons
     */
    protected function renderSubToolbarGroup(array $buttons)
    {
        echo '<div class="gf-sub-toolbar-composite gf-sub-toolbar-composite--horizontal">';
        foreach ($buttons as $btn) {
            $disabled = !empty($btn['disabled']) ? ' disabled' : '';
            echo '<button type="button" class="gf-sub-toolbar-btn ' . esc_attr($btn['class']) . '"' . $disabled . ' aria-label="' . esc_attr($btn['label']) . '">';
            $this->echoToolbarSvg($btn['icon']);
            echo '</button>';
        }
        echo '</div>';
    }

    /**
     * Checks if a form theme is set and available.
     * Uses lazy evaluation with caching for minimal overhead.
     * Delegates evaluation to shared evaluateThemeSet() method.
     *
     * @return bool True if theme is set and valid, false otherwise.
     */
    public function isThemeSet()
    {
        if ($this->is_theme_set === null) {
            $this->is_theme_set = $this->evaluateThemeSet($this->form_theme);
        }
        return $this->is_theme_set;
    }
}
