<?php

namespace GriffinForms\Admin\Js\Local;

use GriffinForms\Admin\Js\Local\InputValidations;

class Single extends \GriffinForms\Admin\Js\Local\Format
{
    use InputValidations;

    protected $fields;
    protected $list_page;

    protected function localJs()
    {
        $js = '';
        $js .= $this->reloadItemHistory() . PHP_EOL;
        $js .= $this->handleAjaxState() . PHP_EOL;
        $js .= $this->createItem() . PHP_EOL;
        $js .= $this->updateItem() . PHP_EOL;
        $js .= $this->itemValidations() . PHP_EOL;
        $js .= $this->toggleCheckBox() . PHP_EOL;
        $js .= $this->checkItemDataFunctions() . PHP_EOL;
        $js .= $this->itemData() . PHP_EOL;
        $js .= $this->allValidations() . PHP_EOL;
        $js .= $this->createdSnackbar() . PHP_EOL;

        return $js;
    }

    public function setFieldNames($names)
    {
        $this->fields = $names;
    }

    protected function setListPage()
    {
        $this->list_page = array(
            'field' => 'fields',
            'form' => 'forms',
            'folder' => 'folders',
            'template' => 'templates',
            'message' => 'messages'
        );
    }

    public function reloadItemHistory()
    {
        $nonce = wp_create_nonce('reload_history');
        return 'function griffinformsReloadItemHistory(itemType, itemId) {
            var data = {
                "action": "reloadItemHistory",
                "item_type": itemType,
                "item_id": itemId,
                "nonce": "' . esc_js($nonce) . '"
            };

            $.post(ajaxurl, data, function(response) {
                $("#griffinforms-item-edit-history").text(response);
            });
        };';
    }

    public function createItem()
    {
        $nonce = wp_create_nonce('create_item');
        return '$("#griffinforms-create-item").click(function(){
            resetItemErrors();
            griffinformsHandleAjaxState("waiting");

            checkItemDataFunctions();
            const itemData = getItemData();

            if (griffinformsErrors) {
                $("#griffinforms-item-errors-wrap").show();
                $("html, body").animate({scrollTop: $("#wpbody-content").offset().top}, 200);
                griffinformsHandleAjaxState("done");
                return;
            }

            var itemType = $(this).attr("data-item-type");
            const jsonData = JSON.stringify(itemData);

            var data = {
                "action": "createItem",
                "item_type": itemType,
                "item_data": jsonData,
                "nonce": "' . esc_js($nonce) . '"
            };

            $.ajax({
                type: "POST",
                url: ajaxurl,
                data: data,
                success: function(response) {
                    try {
                        var json = typeof response === "object" ? response : JSON.parse(response);

                        if (json.success && json.data) {
                            location.replace("' . esc_url_raw($this->editUrl()) . '&id=" + json.data + "&created=1");
                        } else {
                            var text = json.msg || "' . esc_js(__('Failed to create item.', 'griffinforms-form-builder')) . '";
                            griffinformsSnackBar(text, json.time || "");
                        }
                    } catch (e) {
                        griffinformsSnackBar("' . esc_js(__('An unexpected error occurred while creating the item.', 'griffinforms-form-builder')) . '");
                    }

                    griffinformsHandleAjaxState("done");
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    griffinformsSnackBar("' . esc_js(__('Network or server error while creating the item.', 'griffinforms-form-builder')) . '");
                    griffinformsHandleAjaxState("done");
                }
            });
        });';
    }

    protected function editUrl()
    {
        $field_type = '';

        if ($this->data['item_type'] == 'field') {
            $field_type = isset($_GET['field-type']) ? '&field-type=' . esc_attr(sanitize_text_field(wp_unslash($_GET['field-type']))) : '&field-type=';
        }

        $url = '?page=griffinforms-' . $this->data['item_type'] . $field_type;
        return $url;
    }

    public function updateItem()
    {
        if (!isset($this->data['field_type'])) {
            $this->data['field_type'] = '';
        }

        $nonce = wp_create_nonce('update_item');
        return '$("#griffinforms-edit-item").click(function(){
            resetItemErrors();
            checkItemDataFunctions();
            const itemData = getItemData();

            if (griffinformsErrors) {
                $("#griffinforms-item-errors-wrap").show();
                $("html, body").animate({scrollTop: $("#wpbody-content").offset().top}, 200);
                return;
            }

            griffinformsHandleAjaxState("waiting");

            var itemId = ' . absint($this->data['item_id']) . ';
            var itemType = $(this).attr("data-item-type");
            var fieldType = "' . esc_js($this->data['field_type']) . '";
            var formId = ' . absint($this->data['form_id'] ?? 0) . ';

            const jsonData = JSON.stringify(itemData);

            var data = {
                "action": "updateItem",
                "item_id": itemId,
                "item_type": itemType,
                "field_type": fieldType,
                "form_id": formId,
                "item_data": jsonData,
                "nonce": "' . esc_js($nonce) . '"
            };

            $.ajax({
                type: "POST",
                url: ajaxurl,
                data: data,
                success: function(response) {
                    try {
                        var json = typeof response === "object" ? response : JSON.parse(response);

                        if (json.success) {
                            var text = json.msg || "' . esc_js($this->lang->getText('item_updated')) . '";
                            ' . $this->refererJs() . '
                            griffinformsSnackBar(text, json.time || "");
                            griffinformsReloadItemHistory(itemType, itemId);
                        } else {
                            var text = json.msg || "' . esc_js(__('Failed to update item.', 'griffinforms-form-builder')) . '";
                            griffinformsSnackBar(text, json.time || "");
                        }
                    } catch (e) {
                        alert("' . esc_js($this->lang->getText('network_error_message')) . '");
                    }

                    griffinformsHandleAjaxState("done");
                },
                error: function(jqXHR, textStatus, errorThrown) {
                    alert("Network or server error: " + textStatus);
                    griffinformsHandleAjaxState("done");
                }
            });
        });';
    }

    /**
     * Output JS function to manage UI state during AJAX operations.
     */
    public function handleAjaxState()
    {
        return 'function griffinformsHandleAjaxState(state) {
            var btn = $(".griffinforms-submit-btn");
            var spinner = btn.next(".spinner");
            if (state === "waiting") {
                $("#griffinforms-item-action-status").removeClass("visually-hidden");
                $("#griffinforms-create-item, #griffinforms-edit-item").prop("disabled", true);
                btn.prop("disabled", true);
                spinner.css("visibility", "visible");
            } else if (state === "done") {
                $("#griffinforms-item-action-status").addClass("visually-hidden");
                $("#griffinforms-create-item, #griffinforms-edit-item").prop("disabled", false);
                btn.prop("disabled", false);
                spinner.css("visibility", "hidden");
            }
        }';
    }

    public function getName()
    {
        return 'function getName() {
            var fieldValue = $("#griffinforms-name-inputtext").val();
            $("#griffinforms-name-inputtext").removeClass("border-danger");
            fieldValue = $.trim(fieldValue);

            if (fieldValue == "") {
                $("#griffinforms-name-inputtext").val("");
                $("#griffinforms-name-inputtext").addClass("border-danger");
                showItemError("' . esc_js($this->lang->getText('name_required')) . '");
            } else {
                return fieldValue;
            }
        }';
    }

    public function getHeading()
    {
        return 'function getHeading() {
            var fieldValue = $("#griffinforms-heading-inputtext").val();
            $("#griffinforms-heading-inputtext").removeClass("border-danger");
            fieldValue = $.trim(fieldValue);

            if (fieldValue.length > 1000) {
                $("#griffinforms-heading-inputtext").addClass("border-danger");
                showItemError("' . esc_js($this->lang->getText('heading_too_long')) . '");
            } else {
                return fieldValue;
            }
        }';
    }

    public function getDescription()
    {
        return 'function getDescription() {
            var fieldValue = $("#griffinforms-description-textarea").val();
            $("#griffinforms-description-textarea").removeClass("border-danger");
            fieldValue = $.trim(fieldValue);

            if (fieldValue.length > 2000) {
                $("#griffinforms-description-textarea").addClass("border-danger");
                showItemError("' . esc_js($this->lang->getText('description_too_long')) . '");
            } else {
                return fieldValue;
            }
        }';
    }

    public function getFolder()
    {
        return 'function getFolder() {
            var fieldValue = $("#griffinforms-current-folder-name").attr("data-item-id");
            if ($.isNumeric(fieldValue)) {
                return fieldValue;
            } else {
                showItemError("' . esc_js($this->lang->getText('invalid_folder')) . '");
            }
        }';
    }

    public function getFormStyle()
    {
        return 'function getFormstyle() {
            var formStyleId = $("#griffinforms-current-formstyle-name").attr("data-item-id");
            if ($.isNumeric(formStyleId)) {
                return formStyleId;
            } else {
                showItemError("' . esc_js($this->lang->getText('invalid_form_style')) . '");
            }
        }';
    }

    public function toggleCheckBox()
    {
        return 'function getToggleCheckBox(field) {
            var checkbox = "input[id=\"" + field + "\"]";
            var status = $(checkbox).is(":checked");
            return status ? 1 : 0;
        }';
    }

    public function itemValidations()
    {
        $js = '';
    
        if (is_array($this->fields) && !empty($this->fields)) {
            foreach ($this->fields as $field) {
                $method = 'get' . $this->purgeString($field);
                if (method_exists($this, $method)) {
                    $js .= $this->$method() . PHP_EOL;
                }
            }
        }
    
        return $js;
    }

    public function checkItemDataFunctions()
    {
        $js = 'function checkItemDataFunctions() {';
    
        // Check if $this->fields is an array and not empty
        if (is_array($this->fields) && !empty($this->fields)) {
            foreach ($this->fields as $field) {
                $function_name = 'get' . ucfirst($this->purgeString($field));
                $js .= 'if (typeof ' . esc_html($function_name) . ' !== "function") {
                    alert("Missing JS for ' . esc_js($function_name) . '");
                }' . PHP_EOL;
            }
        }
    
        $js .= '};';
        return $js;
    }

    public function itemData()
    {
        $js = 'function getItemData() {
            const itemData = {};';
    
        // Check if $this->fields is an array and not empty
        if (is_array($this->fields) && !empty($this->fields)) {
            foreach ($this->fields as $field) {
                $js .= 'itemData["' . esc_js($field) . '"] = get' . esc_js(ucfirst($this->purgeString($field))) . '();' . PHP_EOL;
            }
        }
    
        $js .= 'return itemData;
        };';
    
        return $js;
    }

    public function createdSnackbar()
    {
        $list_page = isset($this->list_page[$this->data['item_type']]) ? $this->list_page[$this->data['item_type']] : $this->data['item_type'];
        $list_url = '?page=griffinforms-' . $list_page;

        $item_name = $this->config->getFriendlyName($this->data['item_type']);
        /* translators: %s is the item type name (e.g., Form, Template, Message) */
        $message = esc_js(sprintf(__('%s created successfully. You can keep editing or', 'griffinforms-form-builder'), $item_name));
        $link = '<a href=\'' . esc_url($list_url) . '\' class="text-light"> ' . esc_html__('go back to the list view', 'griffinforms-form-builder') . '</a>';

        return '
        jQuery(function($) {
            const params = new URLSearchParams(window.location.search);
            if (params.get("created") === "1") {
                griffinformsSnackBar(' . json_encode(wp_kses($message . ' ' . $link, array('a' => array('href' => true, 'class' => true)))) . ');

                // Remove the "created" param from the URL
                params.delete("created");
                const newUrl = window.location.pathname + "?" + params.toString();
                window.history.replaceState({}, "", newUrl);
            }
        });';
    }
}
