<?php

namespace GriffinForms\Admin\Html\Elements;

use GriffinForms\Traits\Singleton;

class Buttons extends \GriffinForms\Admin\Html\Format
{
    use Singleton;

    private function normalizeAttributeString($attribute)
    {
        $attribute = trim((string) $attribute);
        if ($attribute === '') {
            return '';
        }

        $parts = explode('=', $attribute, 2);
        $name = trim($parts[0]);

        if ($name === '') {
            return '';
        }

        if (count($parts) === 1) {
            return esc_attr($name);
        }

        $value = trim($parts[1]);
        $value = trim($value, "\"'");

        return esc_attr($name) . '="' . esc_attr($value) . '"';
    }
    
    /**
     * Outputs or returns a Bootstrap-styled button or link with customizable options.
     *
     * @param array $options {
     *     Optional. Configuration options for the button or link.
     *
     *     @type string $class   Button CSS classes. Default 'btn-primary'.
     *     @type string $id      Button ID attribute. Default ''.
     *     @type string $label   Button label text. Default ''.
     *     @type bool   $spinner Whether to include a spinner. Default false.
     *     @type array  $data    Additional data-* attributes as array of raw strings. Default [].
     *     @type array  $style   Inline CSS styles as associative array. Default [].
     *     @type array  $aria    ARIA attributes as associative array. Default [].
     *     @type string $icon    Optional icon name (SVG file in button-icons/ directory). Default ''.
     *     @type string $link    Optional URL for anchor tag instead of button. Default ''.
     * }
     * @param bool $echo Optional. Whether to echo the button. Default true.
     * @return void|string HTML markup if $echo is false, otherwise nothing.
     */
    public function bsBtn(array $options = [], $echo = true)
    {
        // Define default options
        $defaults = [
            'class' => 'gf-btn-primary',
            'id' => '',
            'label' => '',
            'spinner' => false,
            'data' => [],
            'style' => [],
            'aria' => [],
            'icon' => '',
            'link' => ''
        ];

        $options = array_merge($defaults, $options);

        // Map legacy bootstrap class to griffinforms custom class
        if ($options['class'] === 'btn-primary') {
            $options['class'] = 'gf-btn-primary';
        }

        // Prepare base attributes
        $attributes = [
            $options['link'] ? '' : 'type="button"',
            $options['id'] ? 'id="' . esc_attr($options['id']) . '"' : '',
            'class="' . esc_attr('gf-btn ' . $options['class']) . '"'
        ];

        // Add data-* attributes (escaped)
        if (!empty($options['data'])) {
            foreach ($options['data'] as $attr) {
                $normalized_attr = $this->normalizeAttributeString($attr);
                if ($normalized_attr !== '') {
                    $attributes[] = $normalized_attr;
                }
            }
        }

        // Add ARIA attributes (escaped)
        if (!empty($options['aria'])) {
            foreach ($options['aria'] as $name => $value) {
                $attributes[] = esc_attr($name) . '="' . esc_attr($value) . '"';
            }
        }

        // Add inline styles (escaped)
        if (!empty($options['style'])) {
            $style = implode(' ', array_map(fn($p, $v) => "$p:$v !important;", array_keys($options['style']), $options['style']));
            $attributes[] = 'style="' . esc_attr(trim($style)) . '"';
        }

        // Determine tag type and add link href if needed (escaped)
        $tag = !empty($options['link']) ? 'a' : 'button';
        if (!empty($options['link'])) {
            $attributes[] = 'href="' . esc_url($options['link']) . '"';
        }

        // Build opening tag
        $output = '<' . $tag . ' ' . implode(' ', array_filter($attributes)) . '>';

        // Add icon if specified (escaped URL)
        if (!empty($options['icon'])) {
            $icon_url = $this->config->getRootUrl() . 'admin/images/button-icons/' . $options['icon'] . '.svg';
            $output .= '<img height="16" src="' . esc_url($icon_url) . '" alt="" class="gf-btn-icon me-1" />';
        }

        // Add button label (escaped text)
        $output .= '<span class="gf-btn-label">' . esc_html($options['label']) . '</span>';

        // Add spinner if enabled
        if ($options['spinner']) {
            $output .= '<span class="gf-btn-spinner spinner-border spinner-border-sm mx-2 visually-hidden" aria-hidden="true"></span>';
        }

        // Close tag
        $output .= '</' . $tag . '>';

        // Output or return the button/link
        if ($echo) {
            echo wp_kses_post($output);
        } else {
            return $output;
        }
    }

    /**
     * Outputs or returns a WordPress-styled button or link with customizable options.
     *
     * @param array $options Same structure as bsBtn().
     * @param bool  $echo    Whether to echo the button. Default true.
     * @return void|string   HTML markup if $echo is false, otherwise nothing.
     */
    public function wpBtn(array $options = [], $echo = true)
    {
        $defaults = [
            'class' => 'button button-primary',
            'id' => '',
            'label' => '',
            'spinner' => false,
            'data' => [],
            'style' => [],
            'aria' => [],
            'icon' => '',
            'link' => ''
        ];

        $options = array_merge($defaults, $options);

        $attributes = [
            $options['link'] ? '' : 'type="button"',
            $options['id'] ? 'id="' . esc_attr($options['id']) . '"' : '',
            'class="' . esc_attr($options['class']) . '"'
        ];

        foreach ($options['data'] as $attr) {
            $normalized_attr = $this->normalizeAttributeString($attr);
            if ($normalized_attr !== '') {
                $attributes[] = $normalized_attr;
            }
        }

        foreach ($options['aria'] as $name => $value) {
            $attributes[] = esc_attr($name) . '="' . esc_attr($value) . '"';
        }

        if (!empty($options['style'])) {
            $style = implode(' ', array_map(fn($p, $v) => "$p:$v !important;", array_keys($options['style']), $options['style']));
            $attributes[] = 'style="' . esc_attr(trim($style)) . '"';
        }

        $tag = !empty($options['link']) ? 'a' : 'button';
        if (!empty($options['link'])) {
            $attributes[] = 'href="' . esc_url($options['link']) . '"';
        }

        $output = '<' . $tag . ' ' . implode(' ', array_filter($attributes)) . '>';

        if (!empty($options['icon'])) {
            $icon_url = $this->config->getRootUrl() . 'admin/images/button-icons/' . $options['icon'] . '.svg';
            $output .= '<img height="16" src="' . esc_url($icon_url) . '" alt="" class="gf-btn-icon me-1" />';
        }

        $output .= '<span>' . esc_html($options['label']) . '</span>';

        $output .= '</' . $tag . '>';

        if ($options['spinner']) {
            $output .= '<span class="spinner griffinforms-spinner" aria-hidden="true"></span>';
        }

        if ($echo) {
            echo wp_kses_post($output);
        } else {
            return $output;
        }
    }

    public function inserterBtn(array $options = [], $echo = true)
    {
        $defaults = [
            'id' => '',
            'class' => '',
            'data' => [],
            'style' => [],
            'aria' => [],
        ];
        $options = array_merge($defaults, $options);

        $bar_class = 'gf-inserter-bar';
        $btn_class = 'gf-inserter-btn';
        $attributes = [
            $options['id'] ? 'id="' . esc_attr($options['id']) . '"' : '',
            'class="' . esc_attr($btn_class . ' ' . $options['class']) . '"'
        ];

        foreach ($options['data'] as $attr) {
            $normalized_attr = $this->normalizeAttributeString($attr);
            if ($normalized_attr !== '') {
                $attributes[] = $normalized_attr;
            }
        }

        foreach ($options['aria'] as $name => $value) {
            $attributes[] = esc_attr($name) . '="' . esc_attr($value) . '"';
        }

        if (!empty($options['style'])) {
            $style = implode(' ', array_map(fn($p, $v) => "$p:$v !important;", array_keys($options['style']), $options['style']));
            $attributes[] = 'style="' . esc_attr(trim($style)) . '"';
        }

        $output = '<div class="' . esc_attr($bar_class) . ' w-100">';
        $output .= '<button type="button" ' . implode(' ', array_filter($attributes)) . '>';
        $output .= '<img width="24" src="' . $this->getImg('add_white', 'icon', 'url') . '" alt="" class="gf-inserter-icon" />';
        $output .= '</button>';
        $output .= '</div>';

        if ($echo) {
            echo wp_kses_post($output);
        } else {
            return $output;
        }
    }

    public function staticInserterBtn(array $options = [], $echo = true)
    {
        $defaults = [
            'id' => '',
            'class' => '',
            'data' => [],
            'style' => [],
            'aria' => [],
        ];
        $options = array_merge($defaults, $options);

        $btn_class = 'gf-inserter-static-btn';
        $attributes = [
            $options['id'] ? 'id="' . esc_attr($options['id']) . '"' : '',
            'class="' . esc_attr($btn_class . ' ' . $options['class']) . '"'
        ];

        foreach ($options['data'] as $attr) {
            $normalized_attr = $this->normalizeAttributeString($attr);
            if ($normalized_attr !== '') {
                $attributes[] = $normalized_attr;
            }
        }

        foreach ($options['aria'] as $name => $value) {
            $attributes[] = esc_attr($name) . '="' . esc_attr($value) . '"';
        }

        if (!empty($options['style'])) {
            $style = implode(' ', array_map(fn($p, $v) => "$p:$v !important;", array_keys($options['style']), $options['style']));
            $attributes[] = 'style="' . esc_attr(trim($style)) . '"';
        }

        $output = '<button type="button" ' . implode(' ', array_filter($attributes)) . '>';
        $output .= '<img width="24" src="' . $this->getImg('add_white', 'icon', 'url') . '" alt="" class="gf-inserter-icon" />';
        $output .= '</button>';

        if ($echo) {
            echo wp_kses_post($output);
        } else {
            return $output;
        }
    }
}
