<?php

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

class Field extends \GriffinForms\Admin\App\Html\Widgets\PresentationArea\FormElements\Format
{
    /**
     * Bootstrap fallback classes applied when no theme is set.
     * These provide basic styling when a field has no custom theme assigned.
     */
    protected $bs_field_container_classes = '';
    protected $bs_field_label_classes = 'form-label h6 mb-0';
    protected $bs_field_description_classes = 'small form-text text-muted mt-1';
    protected $field_type_available = null;

    public function getHtml()
    {
        if ($this->item === false) {
            return;
        }

        // Determine if theme is set for conditional class application
        $is_theme_set = $this->isThemeSet();
        $theme_class = !$is_theme_set ? ' gf-no-theme' : '';
        $additional_classes = !$is_theme_set && !empty($this->bs_field_container_classes) ? ' ' . esc_attr($this->bs_field_container_classes) : '';

        $field_type_slug = strtolower($this->item->getProp('field_type'));
        $field_friendly = $this->config->getFriendlyName($field_type_slug);
        $availability_class = $this->fieldTypeAvailable() ? '' : ' gf-field-unavailable';
        $field_signature = $this->getAiFieldSignature();

        echo '<div id="' . esc_attr($this->getHtmlId($this->item_id)) . '" class="griffinforms-app-formlayout-field d-flex align-items-start py-2 pe-2 m-2' . $theme_class . $additional_classes . $availability_class . '" data-gf-fe="true" data-gf-itemtype="field" data-gf-itemid="' . absint($this->item_id) . '" data-gf-fieldtype="' . esc_attr($field_type_slug) . '" data-gf-fieldfriendly="' . esc_attr($field_friendly) . '" data-gf-fieldavailable="' . esc_attr($this->fieldTypeAvailable() ? '1' : '0') . '" data-gf-ai-signature="' . esc_attr($field_signature) . '">';

        $this->renderActionCluster($this->getContextActions(), array(
            'id'             => 'gf-field-icons-wrap',
            'label'          => __('Field actions', 'griffinforms-form-builder'),
            'meta_container' => true,
        ));

        echo '<div class="flex-fill">';

        // $this->fieldName();
        $this->fieldLabel();
        
        echo '<div class="' . esc_attr($this->getHtmlId('form_control')) . '">';
        $this->formControls();
        echo '</div>';
        
        $this->fieldDescription();
        
        echo '</div>';
        echo '</div>';
    }

    /**
     * Outputs an edit field button as an icon linking to the edit field page.
     *
     * This button is styled according to GriffinForms conventions and uses the
     * configuration's getFriendlyName() if needed.
     *
     * @return void
     */
    private function getContextActions()
    {
        $form_id = isset($_GET['form_id']) ? absint($_GET['form_id']) : 0;
        $edit_url = admin_url('admin.php?page=griffinforms-field&id=' . $this->item_id . '&return=1&field-type=' . urlencode($this->item->getProp('field_type')));
        if ($form_id > 0) {
            $edit_url .= '&form_id=' . $form_id;
        }

        $actions = array(
            array(
                'id'      => 'drag',
                'label'   => __('Drag Field', 'griffinforms-form-builder'),
                'icon'    => 'drag_indicator',
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/drag.svg',
                'class'   => 'gf-fe-drag-btn griffinforms-app-formlayout-field-drag-handle',
                'action'  => 'drag',
                'context_type' => 'field',
            ),
            array(
                'id'      => 'edit',
                'label'   => $this->fieldTypeAvailable() ? __('Edit Field', 'griffinforms-form-builder') : __('Field editor unavailable', 'griffinforms-form-builder'),
                'icon'    => 'edit',
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/edit.svg',
                'href'    => $this->fieldTypeAvailable() ? $edit_url : '',
                'class'   => 'gf-edit-icon-btn' . ($this->fieldTypeAvailable() ? '' : ' disabled'),
                'action'  => 'edit',
                'context_type' => 'field',
                'disabled' => !$this->fieldTypeAvailable(),
            ),
            array(
                'id'      => 'select-parent',
                'label'   => __('Select parent row', 'griffinforms-form-builder'),
                'icon'    => 'select_all',
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/parent.svg',
                'href'    => '#',
                'class'   => 'gf-edit-icon-btn gf-select-parent-row-btn',
                'action'  => 'select-parent-row',
                'context_type' => 'field',
            )
        );

        if ($this->item->getProp('field_type') === 'payment') {
            $payment_layout = 'cards';
            $payment_settings = $this->item->getProp('field_settings');
            if (is_array($payment_settings) && !empty($payment_settings['layout'])) {
                $payment_layout = sanitize_key($payment_settings['layout']);
            }
            $payment_layout = in_array($payment_layout, array('cards', 'list'), true) ? $payment_layout : 'cards';
            $change_view_label = $payment_layout === 'cards'
                ? __('Switch to list view', 'griffinforms-form-builder')
                : __('Switch to card view', 'griffinforms-form-builder');

            $actions[] = array(
                'id'            => 'add-product',
                'label'         => __('Add Product', 'griffinforms-form-builder'),
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/add-product.svg',
                'class'         => 'gf-edit-icon-btn gf-payment-add-product-btn',
                'action'        => 'add-product',
                'context_type'  => 'field',
            );
            // action encodes the target layout: change-view-cards or change-view-list
            $target_layout = ($payment_layout === 'cards') ? 'list' : 'cards';
            $actions[] = array(
                'id'           => 'change-view-' . $target_layout,
                'label'        => $change_view_label,
                'action'       => 'change-view-' . $target_layout,
                'placement'    => 'menu',
                'context_type' => 'field',
            );
        }

        if ($this->item->getProp('is_reusable')) {
            $actions[] = $this->getRemoveFieldMenuAction(
                sprintf(__('Remove %s', 'griffinforms-form-builder'), $this->config->getFriendlyName('field'))
            );
        } else {
            $actions[] = $this->getDeleteMenuAction(
                'field',
                sprintf(__('Delete %s', 'griffinforms-form-builder'), $this->config->getFriendlyName('field'))
            );
        }

        return $actions;
    }

    private function fieldName()
    {
        echo '<div id="' . esc_attr($this->getHtmlId('name') . '-' . $this->item_id) . '">';

        $this->textUpdateField(
            'name',
            array('placeholder' => __('Name cannot be empty', 'griffinforms-form-builder'), 'required' => 'required'),
            array('font-size' => '10px')
        );
        
        echo '</div>';
    }

    private function fieldLabel()
    {
        $is_theme_set = $this->isThemeSet();
        $css = $is_theme_set ? $this->form_theme->getFieldLabelCss() : '';
        $label_classes = '';

        if (!$is_theme_set && !empty($this->bs_field_label_classes)) {
            $label_classes = $this->bs_field_label_classes;
        }

        echo '<div id="' . esc_attr($this->getHtmlId('heading-' . $this->item_id)) . '" class="d-flex align-items-baseline mb-2">';

        if (!$this->fieldTypeAvailable()) {
            echo '<div class="' . esc_attr($label_classes) . '">' . esc_html($this->item->getProp('heading')) . '</div>';
            echo '</div>';
            return;
        }

        $indicator_text = '';
        if ($this->item->getProp('is_required')) {
            $settings = \GriffinForms\Settings::getInstance();
            $mode     = (string) $settings->getOption('required_indicator_mode', 'asterisk');
            $indicator_text = $mode === 'asterisk' ? '*' : (string) $settings->getOption('required_indicator_custom_text', '');
            if ($indicator_text === 'none') { $indicator_text = ''; }
        }

        if ($indicator_text !== '') {
            // contenteditable naturally sizes to content — no width fight with Bootstrap form-control
            $heading_value = (string) $this->item->getProp('heading');
            $label_css = $this->addImportantToCss($css);
            $font_size_css = $this->getHeadingFontSizeCss($label_classes);
            $combined_css = $label_css . $font_size_css;
            echo '<span contenteditable="true" ';
            echo 'class="griffinforms-app-text_update_field griffinforms-app-heading-ce ' . esc_attr($label_classes) . '" ';
            echo 'data-gf-itemtype="' . esc_attr(strtolower($this->meta)) . '" ';
            echo 'data-gf-itemid="' . esc_attr($this->item_id) . '" ';
            echo 'data-gf-fieldname="heading" ';
            echo 'data-gf-fieldvalue="' . esc_attr($heading_value) . '" ';
            echo 'data-placeholder="' . esc_attr(__('Add label', 'griffinforms-form-builder')) . '" ';
            if ($combined_css !== '') {
                echo 'style="' . esc_attr($combined_css) . '" ';
            }
            echo 'role="textbox" aria-label="' . esc_attr(__('Field label', 'griffinforms-form-builder')) . '">';
            echo esc_html($heading_value);
            echo '</span>';
            echo '<span class="gf-builder-required-indicator" style="color:#d9534f;margin-left:3px;flex-shrink:0;" aria-hidden="true">' . esc_html($indicator_text) . '</span>';
        } else {
            $this->textUpdateField(
                'heading',
                array('placeholder' => __('Add label', 'griffinforms-form-builder')),
                array($css),
                $label_classes
            );
        }

        echo '</div>';
    }

    private function fieldDescription()
    {
        $is_theme_set = $this->isThemeSet();
        $css = $is_theme_set ? $this->form_theme->getFieldDescriptionCss() : '';

        // Apply Bootstrap fallback classes when no theme is set
        $description_wrapper_classes = 'mt-1 gf-hide-in-compact';
        $textarea_classes = '';

        if (!$is_theme_set && !empty($this->bs_field_description_classes)) {
            $textarea_classes = $this->bs_field_description_classes;
        }

        echo '<div id="' . esc_attr($this->getHtmlId('description-' . $this->item_id)) . '" class="' . esc_attr($description_wrapper_classes) . '">';

        if (!$this->fieldTypeAvailable()) {
            $description = trim((string) $this->item->getProp('description'));
            if ($description !== '') {
                echo '<div class="' . esc_attr($textarea_classes) . '">' . esc_html($description) . '</div>';
            }
            echo '</div>';
            return;
        }

        $this->textAreaUpdateField(
            'description',
            array('placeholder' => __('Add description', 'griffinforms-form-builder')),
            array($css),
            $textarea_classes
        );

        echo '</div>';
    }

    private function formControls()
    {
        if (!$this->fieldTypeAvailable()) {
            $this->unavailableFieldPlaceholderHtml();
            return;
        }

        $formcontrol_class = 'GriffinForms\Admin\App\Html\Widgets\PresentationArea\Formcontrols\\' . $this->item->getProp('field_type');
        $formcontrol = new $formcontrol_class($this->item_id, $this->item, $this->form_theme);
        $formcontrol->getHtml();
    }

    protected function unavailableFieldPlaceholderHtml()
    {
        $field_type   = strtolower((string) $this->item->getProp('field_type'));
        $extension    = $this->config->getFieldExtension($field_type);
        $ext_name     = isset($extension['name']) && $extension['name'] !== ''
            ? $extension['name']
            : __('an add-on', 'griffinforms-form-builder');
        $purchase_url = isset($extension['buy_url']) ? esc_url($extension['buy_url']) : '';
        $badge_url    = isset($extension['badge_url']) ? esc_url($extension['badge_url']) : '';
        $badge        = new \GriffinForms\Admin\Html\Elements\ExtensionBadge($ext_name, $badge_url);

        $icon_path = $this->config->getRootPath() . 'admin/images/griffinforms-icon.svg';
        $icon_svg  = is_readable($icon_path) ? file_get_contents($icon_path) : '';

        echo '<div class="gf-ext-unavailable-notice">';

        if ($icon_svg !== '') {
            echo '<div class="gf-ext-unavailable-notice__icon" aria-hidden="true">' . $icon_svg . '</div>';
        }

        echo '<div class="gf-ext-unavailable-notice__body">';
        echo '<div class="gf-ext-unavailable-notice__badge">';
        $badge->html();
        echo '</div>';
        echo '<div class="gf-ext-unavailable-notice__title">' . esc_html($ext_name) . '</div>';
        echo '<div class="gf-ext-unavailable-notice__text">'
            . esc_html__('This field is not available — activate the add-on to restore it.', 'griffinforms-form-builder')
            . '</div>';
        if ($purchase_url !== '') {
            echo '<a href="' . $purchase_url . '" class="gf-ext-unavailable-notice__link" target="_blank" rel="noopener noreferrer">'
                . esc_html__('Learn more', 'griffinforms-form-builder') . '</a>';
        }
        echo '</div>';

        echo '</div>';
    }

    protected function fieldTypeAvailable(): bool
    {
        if ($this->field_type_available !== null) {
            return $this->field_type_available;
        }

        $field_type = strtolower((string) $this->item->getProp('field_type'));
        $is_registered = $this->config->isRegisteredFieldType($field_type);
        $formcontrol_class = 'GriffinForms\Admin\App\Html\Widgets\PresentationArea\Formcontrols\\' . $field_type;

        $this->field_type_available = $is_registered && class_exists($formcontrol_class);
        return $this->field_type_available;
    }

    protected function getAiFieldSignature(): string
    {
        $field_type = sanitize_key((string) $this->item->getProp('field_type'));
        $label = $this->normalizeAiText((string) ($this->item->getProp('heading') ?: $this->item->getProp('name')));

        if ($label !== '') {
            return $field_type . '|' . $label;
        }

        $placeholder = $this->normalizeAiText((string) $this->item->getProp('placeholder'));
        if ($placeholder !== '') {
            return $field_type . '|placeholder:' . $placeholder;
        }

        return $field_type . '|item:' . absint($this->item_id);
    }

    protected function normalizeAiText(string $value): string
    {
        $value = wp_strip_all_tags($value);
        $value = preg_replace('/\s+/', ' ', $value);
        return strtolower(trim((string) $value));
    }
}
