<?php

namespace GriffinForms\Frontend\Html\Forms\Fields;

final class InputCheckbox extends \GriffinForms\Frontend\Html\Forms\Fields\Format
{
    protected function setGetValue()
    {
        $value = $this->item->getProp('default_value');

        if (isset($value['get_value']) and $value['get_value']) {
            if (isset($_GET[$value['get_name']])) {
                $this->value = sanitize_text_field(wp_unslash($_GET[$value['get_name']]));
            }
        }
    }
    
    protected function formControl($iteration = 0)
    {   
        $disabled = $this->disabledAttr();
        $html = '<div class="griffinforms-optiongroups-container d-flex justify-content-start mt-1 mb-3">';
        $i = 0;
        $readonly = ($this->isReadonly()) ? ' disabled' : '';

        foreach ($this->field_options as $option_group) {
            
            if (!is_array($option_group)) {return;}

            $html .= '<div class="griffinforms-optiongroup-container d-col me-2">';
            
            foreach ($option_group as $text => $value) {
                $id = $this->html_ids['formcontrol'] . '_' . $iteration . '_' . $i++;
                
                $html .= '<div class="form-check mb-1">';
                
                $html .= '<input class="griffinforms-frontend-checkbox-input ' . esc_attr($this->html_ids['formcontrol']) . '-checkbox align-middle me-2"';
                $html .= ' type="checkbox" value="' . esc_attr($value) . '"';
                $html .= ' id="' . esc_attr($id) . '"';
                $html .= $this->checkedAttr($value);
                $html .= $disabled;
                $html .= $readonly;
                $html .= '>';
                
                $html .= '<label class="form-check-label" for="' . esc_attr($id) . '" data-gf-element="checkbox-label">';
                $html .= esc_html($text);

                $html .= '</label>';
                $html .= '</div>';
            }
            $html .= '</div>';
        }
        
        $html .= '</div>';
        $html .= '<input class="' . $this->html_ids['formcontrol'] . '" type="hidden"';
        $html .= ' data-gf-formpage="' . absint($this->data['formpage']) . '">';
        return $html;
    }
    
    protected function checkedAttr($value)
    {
        $selected_values = $this->getSelectedValues();
        if (empty($selected_values)) {
            return '';
        }

        if (in_array((string) $value, $selected_values, true)) {
            return ' checked="checked"';
        }

        return '';
    }

    protected function getSelectedValues(): array
    {
        $value = $this->value;

        if (is_array($value)) {
            return array_values(array_filter(array_map(static function ($item) {
                return is_scalar($item) ? trim((string) $item) : '';
            }, $value), static function ($item) {
                return $item !== '';
            }));
        }

        if (is_string($value) && $value !== '') {
            $decoded = json_decode($value, true);
            if (json_last_error() === JSON_ERROR_NONE && is_array($decoded)) {
                return array_values(array_filter(array_map(static function ($item) {
                    return is_scalar($item) ? trim((string) $item) : '';
                }, $decoded), static function ($item) {
                    return $item !== '';
                }));
            }

            return array_values(array_filter(array_map('trim', explode(',', $value)), static function ($item) {
                return $item !== '';
            }));
        }

        return array();
    }
    
    protected function disabledAttr()
    {
        if ($this->isDisabled()) {
            return ' disabled';
        }
        return '';
    }
    
    protected function subItemJs()
    {
        echo '
            let cbClass = ".' . esc_attr($this->html_ids['formcontrol']) . '-checkbox";
            let hiddenInputClass = ".' . esc_attr($this->html_ids['formcontrol']) . '";
    
            $(cbClass).each(updateHiddenField);
            $(document).on("change", cbClass, updateHiddenField);
    
            function updateHiddenField() {
                let selectedValues = [];
                let container = $(this).closest(".griffinforms-formcontrol-container");
                
                $(container).find(cbClass).each(function(){
                    if ($(this).is(":checked")) {
                        selectedValues.push($(this).val());
                    }
                });
    
                // Store as a proper JSON array (not a stringified string)
                let hiddenInput = $(container).find(hiddenInputClass);
                hiddenInput.val(JSON.stringify(selectedValues));

                if (typeof triggerFieldChanged === "function") {
                    triggerFieldChanged({ element: this, reason: "option_changed" });
                }
            }
        ';
    }
    
    protected function setErrors()
    {
        $this->errors = array(
            'required',
            'minchecks',
            'maxchecks',
            'unique',
            'dbValidate'
        );
    }
    
    protected function isMinChecks()
    {
        if (key_exists('min_checks', $this->validations) and is_numeric($this->validations['min_checks'])) {
            return true;
        } else {
            return false;
        }
    }
    
    protected function isMaxChecks()
    {
        if (key_exists('max_checks', $this->validations) and is_numeric($this->validations['max_checks'])) {
            return true;
        } else {
            return false;
        }
    }
    
    protected function requiredJs($error)
    {
        echo '
            $(actionBtn).hover(function(){
                $(formControl).each(checkRequired);
            });

            $(document).on("change", cbClass, function(){
                $(formControl).each(checkRequired);
            });

            function checkRequired() {
                let val = JSON.parse($(this).val());
                if(val.length === 0) {
                    addAlert($(this), "' . esc_js($error) . '");
                } else {
                    removeAlert($(this), "' . esc_js($error) . '");
                }
            }
        ';
    }

    protected function minChecksJs($error)
    {
        echo '
            $(actionBtn).hover(function(){
                $(formControl).each(checkMinChecks);
            });

            $(document).on("change", cbClass, function(){
                $(formControl).each(checkMinChecks);
            });

            function checkMinChecks() {
                let val = JSON.parse($(this).val());

                if(val.length === 0) {
                    removeAlert($(this), "' . esc_js($error) . '");
                    return;
                }

                if(val.length < ' . absint($this->validations['min_checks']) . ') {
                    $(this).siblings(".griffinforms-alert-minchecks").children("span").text(val.length);
                    addAlert($(this), "' . esc_js($error) . '");
                } else {
                    removeAlert($(this), "' . esc_js($error) . '");
                }
            }
        ';
    }
    
    protected function maxChecksJs($error)
    {
        echo '
            $(actionBtn).hover(function(){
                $(formControl).each(checkMaxChecks);
            });

            $(document).on("change", cbClass, function(){
                $(formControl).each(checkMaxChecks);
            });

            function checkMaxChecks() {
                let val = JSON.parse($(this).val());
                if(val.length > ' . absint($this->validations['max_checks']) . ') {
                    $(this).siblings(".griffinforms-alert-maxchecks").children("span").text(val.length);
                    addAlert($(this), "' . esc_js($error) . '");
                } else {
                    removeAlert($(this), "' . esc_js($error) . '");
                }
            }
        ';
    }
}
