<?php

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

use GriffinForms\Items\FormTheme;

class FormPage extends \GriffinForms\Admin\App\Html\Widgets\PresentationArea\FormElements\Format
{
    /**
     * Bootstrap fallback classes applied when no theme is set.
     * These provide basic styling when a form page has no custom theme assigned.
     */
    protected $bs_formpage_container_classes = '';
    protected $bs_formpage_classes = 'bg-white border';
    protected $bs_formpage_heading_classes = 'h4 fw-bold mb-0';
    protected $bs_formpage_description_classes = 'form-text text-muted mb-0';
    protected $bs_formpage_prev_button_classes = 'btn btn-secondary';
    protected $bs_formpage_next_button_classes = 'btn btn-success';
    protected $bs_formpage_submit_button_classes = 'btn btn-primary';
    protected $name;
    protected $heading;
    protected $step_data;

    /**
     * Holds the position context for the page.
     *
     * @var array
     */
    private $position_context = [];

    /**
     * Sets the position context for the page.
     *
     * @param array $position
     */
    public function setPositionContext(array $position = [])
    {
        $this->position_context = $position;
    }

    protected function setStepData()
    {
        $this->step_data = array(
            'step_name' => '',
            'step_icon' => '',
        );
    }

    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_formpage_container_classes) ? ' ' . esc_attr($this->bs_formpage_container_classes) : '';

        $page_signature = $this->getAiPageSignature();
        $step_data = $this->item->getProp('step_data');
        $step_name = is_array($step_data) ? trim((string) ($step_data['step_name'] ?? '')) : '';
        $step_icon = is_array($step_data) ? trim((string) ($step_data['step_icon'] ?? '')) : '';
        echo '<div id="' . esc_attr($this->getHtmlId('container-' . $this->item_id)) . '" class="' . esc_attr('griffinforms-app-formlayout-formpage-container' . $theme_class . $additional_classes) . '" data-gf-itemid="' . absint($this->item_id) . '" data-gf-step-name="' . esc_attr($step_name) . '">';

        // Only get page styles if theme is set
        $css = $is_theme_set ? $this->form_theme->getPageStyleCss() : '';
        $formpage_classes = !$is_theme_set && !empty($this->bs_formpage_classes) ? ' ' . esc_attr($this->bs_formpage_classes) : '';
        echo '<div id="' . esc_attr($this->getHtmlId($this->item_id)) . '" class="' . esc_attr('griffinforms-app-formlayout-formpage p-3' . $theme_class . $formpage_classes) . '" ';
        $this->dataAttrs();
        echo 'data-gf-fe="true" data-gf-itemtype="formpage" data-gf-itemid="' . absint($this->item_id) . '" ';
        echo 'data-gf-ai-signature="' . esc_attr($page_signature) . '" ';
        echo 'data-gf-step-name="' . esc_attr($step_name) . '" ';
        echo 'data-gf-step-icon="' . esc_attr($step_icon) . '" ';
        echo 'style="' . esc_attr($css) . '" ';
        echo '>';

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

        echo '<div class="gf-builder-page-meta-shell">';
        // $this->pageName();
        $this->pageHeading();
        $this->pageDescription();
        echo '</div>';

        echo '<div class="griffinforms-app-formlayout-formpage-rows-container p-2" data-gf-itemid="' . absint($this->item_id) . '" style="min-height:24px">';
        $this->pageRows();
        echo '</div>';

        $this->addPageRowBtns();
        $this->pageNavigationBtns();

        echo '</div>';

        $this->addFormPageBtns();

        echo '</div>';
    }

    private function getAiPageSignature(): string
    {
        $page_name = $this->normalizeAiText((string) $this->item->getProp('name'));
        if ($page_name !== '') {
            return 'page:' . $page_name;
        }

        $page_index = absint($this->position_context['index'] ?? 0);
        return 'page_index:' . $page_index;
    }

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

    /**
     * Outputs an edit button icon for the page.
     * The button links to the dedicated page edit screen.
     *
     * @return void
     */
    private function getContextActions()
    {
        $form_id = isset($_GET['form_id']) ? absint($_GET['form_id']) : 0;
        $editUrl = admin_url('admin.php?page=griffinforms-formpage&id=' . $this->item_id . '&return=1');
        if ($form_id > 0) {
            $editUrl .= '&form_id=' . $form_id;
        }

        return array(
            array(
                'id'      => 'drag',
                'label'   => __('Drag Page', 'griffinforms-form-builder'),
                'icon'    => 'drag_indicator',
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/drag.svg',
                'class'   => 'gf-fe-drag-btn griffinforms-app-formlayout-formpage-drag-handle',
                'action'  => 'drag',
                'context_type' => 'page',
            ),
            array(
                'id'      => 'edit',
                'label'   => __('Edit Page', 'griffinforms-form-builder'),
                'icon'    => 'edit',
                'icon_svg_file' => 'admin/images/toolbar-icons/builder/edit.svg',
                'href'    => $editUrl,
                'class'   => 'gf-edit-icon-btn',
                'action'  => 'edit',
                'context_type' => 'page',
            ),
            $this->getEmptyMetadataToggleAction(),
            array(
                'id'       => 'move-vertical',
                'label'    => __('Move page', 'griffinforms-form-builder'),
                'class'    => 'gf-fe-action-composite--vertical',
                'children' => array(
                    array(
                        'id'           => 'move-up',
                        'label'        => __('Move page up', 'griffinforms-form-builder'),
                        'icon'         => 'expand_less',
                        'icon_svg_file' => 'admin/images/toolbar-icons/builder/up.svg',
                        'class'        => 'gf-page-move-btn gf-page-move-up',
                        'action'       => 'move-page-up',
                        'context_type' => 'page',
                    ),
                    array(
                        'id'           => 'move-down',
                        'label'        => __('Move page down', 'griffinforms-form-builder'),
                        'icon'         => 'expand_more',
                        'icon_svg_file' => 'admin/images/toolbar-icons/builder/down.svg',
                        'class'        => 'gf-page-move-btn gf-page-move-down',
                        'action'       => 'move-page-down',
                        'context_type' => 'page',
                    ),
                ),
            ),
            $this->getDeleteMenuAction(
                'page',
                sprintf(__('Delete %s', 'griffinforms-form-builder'), $this->config->getFriendlyName('formpage'))
            )
        );
    }

    private function getEmptyMetadataToggleAction()
    {
        return array(
            'id'           => 'toggle-empty-metadata',
            'label'        => __('Show or hide optional metadata', 'griffinforms-form-builder'),
            'icon'         => 'short_text',
            'icon_svg_file' => 'admin/images/toolbar-icons/builder/add-heading-description.svg',
            'class'        => 'gf-edit-icon-btn gf-toggle-empty-metadata-btn',
            'action'       => 'toggle-empty-metadata',
            'context_type' => 'page',
        );
    }

    private function pageName()
    {
        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 pageHeading()
    {
        $is_theme_set = $this->isThemeSet();
        $css = $is_theme_set ? $this->form_theme->getPageHeadingCss() : '';
        $heading_classes = '';

        if (!$is_theme_set && !empty($this->bs_formpage_heading_classes)) {
            $heading_classes = $this->bs_formpage_heading_classes;
        }

        $this->optionalMetadataField(
            'heading',
            array(
                'ghost_label'     => __('Add heading', 'griffinforms-form-builder'),
                'wrapper_id'      => $this->getHtmlId('heading-' . $this->item_id),
                'wrapper_classes' => 'gf-hide-in-compact',
                'field_classes'   => $heading_classes,
                'attrs'           => array(
                    'placeholder' => __('Optional heading', 'griffinforms-form-builder'),
                    'data-gf-metadata-editor' => 'true',
                ),
                'style'           => array($css),
            )
        );
    }

    private function pageDescription()
    {
        // Only get page heading styles if theme is set
        $is_theme_set = $this->isThemeSet();
        $css = $is_theme_set ? $this->form_theme->getPageHeadingCss() : '';
        $description_classes = '';

        if (!$is_theme_set && !empty($this->bs_formpage_description_classes)) {
            $description_classes = $this->bs_formpage_description_classes;
        }

        $this->optionalMetadataField(
            'description',
            array(
                'mode'            => 'textarea',
                'ghost_label'     => __('Add description', 'griffinforms-form-builder'),
                'wrapper_id'      => $this->getHtmlId('description-' . $this->item_id),
                'wrapper_classes' => 'gf-hide-in-compact',
                'field_classes'   => $description_classes,
                'attrs'           => array(
                    'placeholder' => __('Optional description', 'griffinforms-form-builder'),
                    'rows' => '2',
                    'data-gf-metadata-editor' => 'true',
                ),
                'style'           => array($css),
            )
        );
    }

    private function pageRows()
    {
        $row_ids = $this->item->getProp('pagerows');
        
        if (empty($row_ids) or !is_array($row_ids)) {
            return;
        }

        foreach ($row_ids as $row_id) {
            $row = new PageRow($row_id, $this->item_id, $this, $this->form_theme);
            $row->getHtml();
        }
    }

    /** 
     * Adds buttons beneath each page in a form allowing users to create and insert a new page next to it.
     * @see class PresentationArea::addFormPageBtnJs()
     */
    private function addFormPageBtns()
    {
        echo '<div class="griffinforms-app-formlayout-addpage_btns d-flex justify-content-center align-items-center py-3 rounded-3">';
        $this->buttons->inserterBtn([
            'data' => [
                'data-gf-formid=' . absint($this->parent_id),
                'data-gf-prevpage=' . absint($this->item_id),
                'data-gf-action=insert_new_page'
            ]
        ]);
        echo '</div>';
    }

    /**
     * Adds buttons inside each page allowing users to create and insert a new row inside it.
     *
     * It is hidden by default through formlayout CSS
     * @see class PresentationArea::addPageRowBtnJs()
     */
    private function addPageRowBtns()
    {
        echo '<div class="griffinforms-app-formlayout-addrow_btns d-flex justify-content-center align-items-center py-3 rounded-3">';
        $this->buttons->inserterBtn([
            'data' => [
                'data-gf-pageid=' . absint($this->item_id),
                'data-gf-action=append_new_row'
            ]
        ]);
        echo '</div>';
    }
    
    /**
     * Renders the Previous, Next, and Submit buttons for page navigation.
     * Layout is adjusted for single or multiple buttons.
     */
    private function pageNavigationBtns()
    {
        echo '<div class="griffinforms-app-formlayout-pagenav-btns d-flex justify-content-between mt-4 p-2">';

        // Left (Prev Button)
        echo '<div>';
        $this->renderPrevButton();
        echo '</div>';

        // Right (Next and Submit Buttons)
        echo '<div>';
        $this->renderNextButton();
        $this->renderSubmitButton();
        echo '</div>';

        echo '</div>';
    }

    /**
     * Renders the Previous button.
     * Only renders button styles when a custom theme is assigned.
     */
    private function renderPrevButton()
    {
        $button_id = 'gf-prev-btn-' . $this->item_id;
        $is_theme_set = $this->isThemeSet();

        // Only render button styles if theme is set
        if ($is_theme_set) {
            $default_css = $this->form_theme->getPreviousButtonCss('default');
            $hover_css = $this->form_theme->getPreviousButtonCss('hover');
            $active_css = $this->form_theme->getPreviousButtonCss('active');

            $rules = array();
            if (!empty($default_css)) {
                $rules[] = '#' . esc_attr($button_id) . ' { ' . $default_css . ' }';
            }
            if (!empty($hover_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':hover { ' . $hover_css . ' }';
            }
            if (!empty($active_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':active { ' . $active_css . ' }';
            }

            $css_output = FormTheme::prepareStyleTagContent(implode('', $rules));
            if ($css_output !== '') {
                echo '<style>' . $css_output . '</style>';
            }
        }

        // Apply Bootstrap fallback classes when no theme is set
        $button_classes = 'gf-page-prev-btn me-2';
        if (!$is_theme_set && !empty($this->bs_formpage_prev_button_classes)) {
            $button_classes .= ' ' . esc_attr($this->bs_formpage_prev_button_classes);
        }

        $label = $this->item->getProp('previous_label') ?: __('Previous', 'griffinforms-form-builder');
        echo '<button id="' . esc_attr($button_id) . '" class="' . esc_attr($button_classes) . '">';
        echo '<span contenteditable="true" spellcheck="false"';
        echo ' data-gf-nav-type="previous"';
        echo ' data-gf-nav-prev-value="' . esc_attr($label) . '"';
        echo ' data-gf-nav-page-id="' . absint($this->item_id) . '">';
        echo esc_html($label);
        echo '</span>';
        echo '</button>';
    }

    /**
     * Renders the Next button.
     * Only renders button styles when a custom theme is assigned.
     */
    private function renderNextButton()
    {
        $button_id = 'gf-next-btn-' . $this->item_id;
        $is_theme_set = $this->isThemeSet();

        // Only render button styles if theme is set
        if ($is_theme_set) {
            $default_css = $this->form_theme->getNextButtonCss('default');
            $hover_css = $this->form_theme->getNextButtonCss('hover');
            $active_css = $this->form_theme->getNextButtonCss('active');

            $rules = array();
            if (!empty($default_css)) {
                $rules[] = '#' . esc_attr($button_id) . ' { ' . $default_css . ' }';
            }
            if (!empty($hover_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':hover { ' . $hover_css . ' }';
            }
            if (!empty($active_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':active { ' . $active_css . ' }';
            }

            $css_output = FormTheme::prepareStyleTagContent(implode('', $rules));
            if ($css_output !== '') {
                echo '<style>' . $css_output . '</style>';
            }
        }

        // Apply Bootstrap fallback classes when no theme is set
        $button_classes = 'gf-page-next-btn';
        if (!$is_theme_set && !empty($this->bs_formpage_next_button_classes)) {
            $button_classes .= ' ' . esc_attr($this->bs_formpage_next_button_classes);
        }

        $label = $this->item->getProp('next_label') ?: __('Next', 'griffinforms-form-builder');
        echo '<button id="' . esc_attr($button_id) . '" class="' . esc_attr($button_classes) . '">';
        echo '<span contenteditable="true" spellcheck="false"';
        echo ' data-gf-nav-type="next"';
        echo ' data-gf-nav-prev-value="' . esc_attr($label) . '"';
        echo ' data-gf-nav-page-id="' . absint($this->item_id) . '">';
        echo esc_html($label);
        echo '</span>';
        echo '</button>';
    }

    /**
     * Renders the Submit button.
     * Only renders button styles when a custom theme is assigned.
     */
    private function renderSubmitButton()
    {
        $button_id = 'gf-submit-btn-' . $this->item_id;
        $is_theme_set = $this->isThemeSet();

        // Only render button styles if theme is set
        if ($is_theme_set) {
            $default_css = $this->form_theme->getSubmitButtonCss('default');
            $hover_css = $this->form_theme->getSubmitButtonCss('hover');
            $active_css = $this->form_theme->getSubmitButtonCss('active');

            $rules = array();
            if (!empty($default_css)) {
                $rules[] = '#' . esc_attr($button_id) . ' { ' . $default_css . ' }';
            }
            if (!empty($hover_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':hover { ' . $hover_css . ' }';
            }
            if (!empty($active_css)) {
                $rules[] = '#' . esc_attr($button_id) . ':active { ' . $active_css . ' }';
            }

            $css_output = FormTheme::prepareStyleTagContent(implode('', $rules));
            if ($css_output !== '') {
                echo '<style>' . $css_output . '</style>';
            }
        }

        // Apply Bootstrap fallback classes when no theme is set
        $button_classes = 'gf-page-submit-btn me-2';
        if (!$is_theme_set && !empty($this->bs_formpage_submit_button_classes)) {
            $button_classes .= ' ' . esc_attr($this->bs_formpage_submit_button_classes);
        }

        $label = (string) $this->sql->getItemValue($this->parent_id, 'submit_label', 'form');
        if ($label === '') {
            $label = __('Submit', 'griffinforms-form-builder');
        }
        echo '<button id="' . esc_attr($button_id) . '" class="' . esc_attr($button_classes) . '">';
        echo '<span contenteditable="true" spellcheck="false"';
        echo ' data-gf-nav-type="submit"';
        echo ' data-gf-nav-prev-value="' . esc_attr($label) . '"';
        echo ' data-gf-nav-form-id="' . absint($this->parent_id) . '">';
        echo esc_html($label);
        echo '</span>';
        echo '</button>';
    }
}
