<?php

namespace GriffinForms\Admin\Html\Pages\Single;

use GriffinForms\Admin\Html\Pages\Single\FetchFields;

abstract class Format extends \GriffinForms\Admin\Html\Pages\Format
{
    use FetchFields;
    
    protected $meta;
    protected $config;
    protected $lang;
    protected $sql;
    protected $item_id;
    protected $item;
    protected $action;
    protected $required_fields;
    protected $prop;
    protected $value;
    protected $fields = array();
    protected $js_data;
    protected $js;
    protected $js_object;
    protected $form_id = 0;
    
    abstract function itemOptions();
    
    protected function setItemId()
    {
        if($this->item_id !== -1 and is_numeric($this->item_id)) {
            return;
        }
        
        if(isset($_GET['id']) and is_numeric($_GET['id'])) {
            $this->item_id = absint($_GET['id']);
        }
    }

    protected function setItem()
    {
        $item_class = '\GriffinForms\Items\\' . $this->meta;
        $this->item = new $item_class();
        
        if($this->item_id !== -1 and $this->sql->itemExists($this->meta, $this->item_id)) {
            $this->item->loadItem($this->item_id);
            $this->action = 'edit';
            return;
        }
           
/*         if(isset($_GET['action']) and $_GET['action'] == 'trash') {
            $this->checkDeleteNonce();
            $this->deleteItem();
            return;
        } */
        
        $this->action = 'create';
        // $this->item->loadItemDefaults();
    }
    
    protected function setRequiredFields()
    {
        $this->required_fields = array();
        if ($this->action != 'defaults') {
            $fields = $this->sql->getColumns();
            foreach ($fields as $field) {
                if ($field['Null'] == 'NO') {
                    array_push($this->required_fields, $field['Field']);
                }
            }
        }
    }
    
    protected function setJsData()
    {
        $this->js_data = array(
            'item_type' => strtolower($this->meta), 
            'item_id' => $this->item_id,
            'form_id' => $this->form_id,
            'referer' => $this->referer,
            'fields' => array()
        );
    }

    protected function setFormId()
    {
        if (!empty($_GET['form_id'])) {
            $this->form_id = absint($_GET['form_id']);
        }
    }
    
    protected function setJs()
    {
    }
    
    public function getJs()
    {
        $this->js;
    }
    
    protected function itemHistory()
    {
        if ($this->action == 'edit') {
            $history = new \GriffinForms\Admin\Html\Elements\itemHistory($this->lang, $this->item);
            $history->html();
        }
    }    
    
    protected function itemLocation()
    {
        if ($this->action == 'edit') {
            echo '<div class="row mt-1"><div class="col fw-semibold small">Location: ';
            echo '<span class="fw-normal text-secondary">database/' . esc_html($this->config->getTable($this->meta)) . '/' . absint($this->item_id) . '</span>';
            echo '</div></div>';
            
        }
    }
    
    public function getOption($prop, $wide = false)
    {
        $label_class = 'col-md-3 ps-3';
        $input_class = 'col-md-9';

        if ($wide) {
            $label_class = 'col-md-12 ps-3 mb-3';
            $input_class = 'col-md-12 ps-3';
        }

        $this->prop = $prop;
        array_push($this->fields, $prop);
        $this->value = $this->item->getProp($prop);
        $is_required = $this->isRequiredOption($prop);
        $input_method = $this->purgeString($prop);
        echo '<div class="row mb-3" id="griffinforms-' . esc_attr($prop) . '-row">';
        
        echo '<div class="' . esc_attr($label_class) . '">';
        $this->label($is_required);
        echo '</div>';
        
        echo '<div class="' . esc_attr($input_class) . '">';
        $this->$input_method();
        $this->optionDescription();
        echo '</div></div>';
        
    }
    
    protected function isRequiredOption($prop)
    {
        if (strtolower((string) $this->meta) === 'form') {
            $optional = array(
                'compliance_mode',
                'compliance_profile',
                'compliance_flags'
            );
            if (in_array($prop, $optional, true)) {
                return false;
            }
        }

        if (in_array($prop, $this->required_fields)) {
            return true;
        } else {
            return false;
        }
    }
    
    protected function label($is_required)
    {
        if($is_required == true) {
            $label_suffix = $this->lang->getText('required');
        } else {
            $label_suffix = '';
        }
        
        echo '<label class="fw-bold">' . wp_kses_post($this->lang->getText($this->prop, 'label') . ' ' . $label_suffix) . '</label>';
    }
    
    protected function optionDescription()
    {
        echo '<p id="' . esc_attr($this->prop) . '-description" class="mt-1 text-secondary small">'. wp_kses_post($this->lang->getText($this->prop, 'description')) . '</p>';
    }
    
    protected function nonceField()
    {
        wp_nonce_field($this->getNonceAction($this->action), 'mg_nonce');
    }
    
    protected function name()
    {
        $field = new \GriffinForms\Admin\Html\FormControls\InputText($this->prop, $this->value);
        $field->html();
    }    
    
    protected function heading()
    {
        $field = new \GriffinForms\Admin\Html\FormControls\InputText($this->prop, $this->value);
        $field->html();
    }
    
    protected function description()
    {
        $field = new \GriffinForms\Admin\Html\FormControls\TextArea($this->prop, $this->value);
        $field->html();
    }
    
    protected function folder()
    {   
        $data = array('item_type' => 'folder');
        $field = new \GriffinForms\Admin\Html\FormControls\Form\SelectItem($this->prop, $this->value, $data);
        $field->html(); 
    }
    
    protected function headingText()
    {
        return $this->lang->getText('heading', $this->action . $this->meta);
    }   
    
    protected function headingSubtext()
    {
        if($this->item_id != -1) {
            return $this->item_id;
        }
    }

    protected function useSectionNavigation()
    {
        return false;
    }

    protected function getMinimumSectionNavCount()
    {
        return 4;
    }

    protected function getSections()
    {
        return array();
    }

    protected function normalizeSection($section)
    {
        if (!is_array($section)) {
            return null;
        }

        $defaults = array(
            'id' => '',
            'label' => '',
            'nav_label' => '',
            'description' => '',
            'enabled' => true,
            'callback' => '',
        );

        $section = wp_parse_args($section, $defaults);
        $section['id'] = sanitize_html_class((string) $section['id']);
        $section['label'] = (string) $section['label'];
        $section['nav_label'] = (string) $section['nav_label'];
        $section['description'] = (string) $section['description'];
        $section['enabled'] = (bool) $section['enabled'];
        $section['callback'] = (string) $section['callback'];

        if ($section['id'] === '' || $section['label'] === '' || $section['callback'] === '') {
            return null;
        }

        if (!method_exists($this, $section['callback'])) {
            return null;
        }

        if ($section['nav_label'] === '') {
            $section['nav_label'] = $section['label'];
        }

        return $section;
    }

    protected function getEnabledSections()
    {
        $enabled = array();
        foreach ($this->getSections() as $section) {
            $section = $this->normalizeSection($section);
            if ($section === null || !$section['enabled']) {
                continue;
            }
            $enabled[] = $section;
        }

        return $enabled;
    }

    protected function hasStructuredSections()
    {
        return !empty($this->getEnabledSections());
    }

    protected function shouldRenderSectionNavigation()
    {
        $sections = $this->getEnabledSections();
        return $this->useSectionNavigation() && count($sections) >= $this->getMinimumSectionNavCount();
    }

    protected function captureOutput($callback)
    {
        ob_start();
        call_user_func($callback);
        return trim((string) ob_get_clean());
    }

    protected function sectionAnchorId($id)
    {
        return 'gf-section-' . sanitize_html_class((string) $id);
    }

    protected function renderSectionShell($section)
    {
        $anchor_id = $this->sectionAnchorId($section['id']);

        echo '<section class="gf-single-section" id="' . esc_attr($anchor_id) . '">';
        echo '<div class="gf-single-section__header">';
        echo '<h2 class="gf-single-section__title">' . esc_html($section['label']) . '</h2>';
        if ($section['description'] !== '') {
            echo '<p class="gf-single-section__description">' . esc_html($section['description']) . '</p>';
        }
        echo '</div>';
        echo '<div class="gf-single-section__body">';
        call_user_func(array($this, $section['callback']));
        echo '</div>';
        echo '</section>';
    }

    protected function renderStructuredSections()
    {
        foreach ($this->getEnabledSections() as $section) {
            $this->renderSectionShell($section);
        }
    }

    protected function renderSectionNavigation()
    {
        $sections = $this->getEnabledSections();
        if (empty($sections)) {
            return;
        }

        echo '<nav class="gf-single-page__nav" aria-label="' . esc_attr__('Page sections', 'griffinforms-form-builder') . '">';
        echo '<div class="gf-single-page__nav-card">';
        echo '<div class="gf-single-page__nav-heading">' . esc_html__('Sections', 'griffinforms-form-builder') . '</div>';
        echo '<ul class="gf-single-page__nav-list">';
        foreach ($sections as $section) {
            echo '<li class="gf-single-page__nav-item">';
            echo '<a class="gf-single-page__nav-link" href="#' . esc_attr($this->sectionAnchorId($section['id'])) . '">';
            echo esc_html($section['nav_label']);
            echo '</a>';
            echo '</li>';
        }
        echo '</ul>';
        echo '</div>';
        echo '</nav>';
    }

    protected function renderLegacyContent()
    {
        $this->nameOptions();
        $this->itemOptions();
    }

    protected function renderMainContent()
    {
        if ($this->hasStructuredSections()) {
            $this->renderStructuredSections();
            return;
        }

        $this->renderLegacyContent();
    }
    
    public function nameOptions()
    {
        echo '<div class="container border-bottom griffinforms-item-options w-75 mt-3 pt-3">';
        $this->optionsHeader('general');
        $this->getOption('name');
        $this->getOption('heading');
        $this->getOption('description');
        echo '</div>';
        
    }
    
    protected function optionsHeader($text)
    {
        echo '<h5 class="mb-5">' . esc_html($this->lang->getText($text)) . '</h5>';
        
    }
    
    protected function fieldErrors()
    {
        echo '<div class="gf-single-page__feedback-notice" id="griffinforms-item-errors-wrap">';
        echo '<div class="notice notice-error is-dismissible p-3 m-0" id="griffinforms-item-errors">';
        echo '<ul class="list-unstyled" id="griffinforms-item-errors-list"></ul>';
        echo '</div></div>';
    }
    
    protected function submitBtn()
    {
        if ($this->form_id > 0) {
            echo '<input type="hidden" id="griffinforms-form-id" value="' . esc_attr($this->form_id) . '">';
        }

        $this->buttons->wpBtn([
            'id'       => 'griffinforms-' . esc_attr($this->action) . '-item',
            'class'    => 'griffinforms-submit-btn button-primary',
            'label'    => $this->lang->getText($this->action . '_item'),
            'data'     => [
                'data-item-type=' . esc_attr(strtolower($this->meta)) . '',
                'data-item-action=' . esc_attr($this->action) . '',
                'data-item-id=' . esc_attr($this->item_id) . '',
                'data-form-id=' . esc_attr($this->form_id) . ''
            ],
            'spinner'  => true
        ]);
    }

    protected function topNav()
    {
        if ($this->action === 'edit') {
            echo '<div class="d-flex justify-content-between">';
            $this->backToListBtn();
            echo '</div>';
        }
    }
    
    /**
     * Render the default back button using the referrer as link.
     * Label changes to "Back to form builder" if referrer is the layout editor.
     * Skips rendering if no referrer is available.
     */
    protected function backToListBtn()
    {
        $referer = wp_get_referer();
        if (empty($referer)) {
            return;
        }

        $from_layout_editor = strpos($referer, 'page=griffinforms-app') !== false;
        $label = $from_layout_editor
            ? $this->lang->getText('Back to form builder')
            : $this->lang->getText('Back to list');

        $this->buttons->bsBtn([
            'class' => 'gf-back-to-forms-btn gf-btn-light me-2',
            'label' => $label,
            'link'  => $referer,
            'icon'  => 'back'
        ]);
    }
    
    public function html()
    {
        $top_nav = $this->captureOutput(array($this, 'topNav'));
        $header_meta = $this->captureOutput(function () {
            $this->itemHistory();
            $this->itemLocation();
        });
        $feedback = $this->captureOutput(array($this, 'fieldErrors'));
        $has_nav = $this->hasStructuredSections() && $this->shouldRenderSectionNavigation();

        echo '<div class="griffinforms-toast">';
        $this->toastAlert();
        echo '</div>';
        $this->setSnackBar();
        $this->spinnerOverlay();

        echo '<div class="gf-single-page gf-single-page--' . esc_attr(strtolower($this->meta)) . '">';
        echo '<div class="gf-single-page__shell">';

        if ($top_nav !== '') {
            echo '<div class="gf-single-page__topnav">' . $top_nav . '</div>';
        }

        echo '<header class="gf-single-page__header">';
        $this->pageHeading($this->headingText(), $this->headingSubtext());
        if ($header_meta !== '') {
            echo '<div class="gf-single-page__header-meta">' . $header_meta . '</div>';
        }
        echo '</header>';

        if ($feedback !== '') {
            echo '<div class="gf-single-page__feedback">' . $feedback . '</div>';
        }

        echo '<div class="gf-single-page__body' . ($has_nav ? ' gf-single-page__body--with-nav' : '') . '">';
        if ($has_nav) {
            $this->renderSectionNavigation();
        }
        echo '<div class="gf-single-page__content">';
        $this->renderMainContent();
        echo '</div>';
        echo '</div>';

        echo '<div class="gf-single-page__footer' . ($has_nav ? ' gf-single-page__footer--with-nav' : '') . '">';
        if ($has_nav) {
            echo '<div class="gf-single-page__footer-spacer" aria-hidden="true"></div>';
            echo '<div class="gf-single-page__footer-main">';
        }
        $this->submitBtn();
        if ($has_nav) {
            echo '</div>';
        }
        echo '</div>';
        echo '</div>';
        echo '</div>';
        $this->setFooterJs();
    }
    
    protected function setFooterJs()
    {
        $this->setJsData();
        $js_class = '\GriffinForms\Admin\Js\Local\\' . $this->meta;
        $this->js_object = new $js_class($this->js_data);
        $this->js_object->setFieldNames($this->fields);
        $this->js = $this->js_object->js();
    }
    
    public function __construct($id = -1)
    {
        $this->item_id = $id;
        $this->setAll();
    }
}
