<?php

namespace IMATHUZH\Qfq\Core\Renderer\FormElement\Bootstrap3;

use IMATHUZH\Qfq\Core\Form\FormElement\AbstractFormElement;
use IMATHUZH\Qfq\Core\Form\FormElement\NoteFormElement;
use IMATHUZH\Qfq\Core\Helper\Support;
use IMATHUZH\Qfq\Core\Renderer\BaseRenderer;
use IMATHUZH\Qfq\Core\Renderer\FormElement\Base\TemplateGroupRenderer;

class Bootstrap3TemplateGroupRenderer extends TemplateGroupRenderer {

    private string $htmlDelete = "";

    /**
     * @param AbstractFormElement $fe
     * @param string $renderMode
     * @return string
     * @throws \CodeException
     * @throws \DbException
     * @throws \DownloadException
     * @throws \PhpOffice\PhpSpreadsheet\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception
     * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception
     * @throws \Twig\Error\LoaderError
     * @throws \Twig\Error\RuntimeError
     * @throws \Twig\Error\SyntaxError
     * @throws \UserFormException
     * @throws \UserReportException
     */
    public function renderHtml(AbstractFormElement $fe, string $renderMode = RENDER_MODE_HTML): string {

        if (count($fe->formElements) === 0) {
            return '';
        }

        $removeDisabled = ($fe->attributes[FE_MODE] == FE_MODE_READONLY) ? "disabled='disabled'" : '';
        $addDisabled = ($fe->attributes[FE_MODE] == FE_MODE_READONLY || count($fe->initialElementGroups) == $fe->attributes[FE_MAX_LENGTH]) ? "disabled='disabled'" : '';
        $addButtonId = $fe->addButtonId;
        $addClass = $fe->attributes[FE_TEMPLATE_GROUP_ADD_CLASS];
        $addText = $fe->attributes[FE_TEMPLATE_GROUP_ADD_TEXT];
        $removeClass = $fe->attributes[FE_TEMPLATE_GROUP_REMOVE_CLASS];
        $removeText = $fe->attributes[FE_TEMPLATE_GROUP_REMOVE_TEXT];
        $classCustom = $fe->attributes[FE_TEMPLATE_GROUP_CLASS];
        $qfqFieldsName = $fe->qfqFieldsName;
        $templateName = $fe->templateName;
        $targetName = $fe->targetName;
        $max = $fe->attributes[FE_MAX_LENGTH];


        $codeJs = <<<EOT
                    <script type="text/javascript">
                        $(function () {
                            $(".$qfqFieldsName").each(
                                function () {
                                    QfqNS.initializeFields(this);
                                }
                            );
                        });
                    </script>
                    EOT;

        $htmlAdd = <<<EOT
                    <button type="button" id="$addButtonId" class="$addClass" $addDisabled onclick="QfqNS.addFields('#$templateName', '#$targetName', $max)">$addText</button>
                    EOT;

        $htmlDelete = <<<EOT
                    <div class="qfq-note-no-padding">
                        <button type="button"  class="$removeClass" $removeDisabled onclick="QfqNS.removeFields(this)">$removeText</button>
                    </div>
                    EOT;
        $this->htmlDelete = $htmlDelete; // Make accessible for other function which renders existing FEs

        // If there are already elements filled, take them.
        $html = $this->renderInitialElementGroups($fe);

        //$html = $this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_START] . $html . $this->wrap[WRAP_SETUP_IN_TEMPLATE_GROUP][WRAP_SETUP_END];

        // Element where the effective FormElements will be copied to. The BS 'col-md-* Classes are inside the template, not here. This here should be pure data without wrapping.
        $html = Support::wrapTag("<div " . Support::arrayToXMLAttributes($fe->htmlAttributes) . ">", $html, false);

        // Use an ad hoc Note FE to display the Add Button
        $tmpAttributes = $fe->attributes;
        $tmpAttributes[FE_NAME] = '_add';
        $tmpAttributes[FE_LABEL] = '';
        $tmpAttributes[FE_NOTE] = '';
        $tmpAttributes[FE_VALUE] = $htmlAdd;
        $noteFE = new NoteFormElement($tmpAttributes, $fe->form);
        $html .= BaseRenderer::getInstance()->renderFormElementHtml($noteFE);

        // Prepare the Template
        $template = "";
        $fe->formElements[count($fe->formElements) - 1]->attributes[FE_NOTE] .= $htmlDelete; // Append the 'Remove' Button at the end of the last element's Note
        foreach ($fe->formElements as $childFE) {
            $template .= BaseRenderer::getInstance()->renderFormElementHtml($childFE);
        }
        $attribute = Support::doAttribute('class', ['qfq-line', $classCustom]);
        $template = Support::wrapTag("<div $attribute>", $template);
        $template = Support::wrapTag('<script id="' . $templateName . '" type="text/' . $templateName . '">', $template);

        return $html . $template . $codeJs;
    }

    /**
     * Renders each group of FEs that belong together in a div.
     * @param $fe
     * @return string The HTML containing all form elements to be rendered on load.
     *
     * @return string
     * @throws \CodeException
     * @throws \DbException
     * @throws \UserFormException
     * @throws \UserReportException
     */
    private function renderInitialElementGroups($fe): string {
        if (!is_array($fe->initialElementGroups)) return "";

        $html = "";
        // Loop through the groups
        for ($i = 0; $i < count($fe->initialElementGroups); $i++) {
            if (is_array($fe->initialElementGroups[$i])) {
                $html .= '<div class="qfq-line">';

                // Loop through the form elements of a group
                for ($ii = 0; $ii < count($fe->initialElementGroups[$i]); $ii++) {
                    // Append the delete button to the note of the last element of the group
                    if ($ii == count($fe->initialElementGroups[$i]) - 1) {
                        $fe->initialElementGroups[$i][$ii]->attributes[FE_NOTE] .= $this->htmlDelete;
                    }

                    // Render the element
                    $html .= BaseRenderer::getInstance()->renderFormElementHtml($fe->initialElementGroups[$i][$ii]);
                }

                $html .= '</div>';
            }
        }
        return $html;
    }
}