class CoolFormSFFEF extends elementorModules.frontend.handlers.Base {
    getDefaultSettings() {
        return {
            selectors: {
                signatureElement: '.signature-pad',
                clearButton: '.coolform-signature-clear',
                undoButton: '.coolform-signature-undo',
                redoButton: '.coolform-signature-redo',
                submitButton: '.cool-form__submit-group button.cool-form-submit-button[type="submit"]',
                inputField: '.is-field-type-signature input.cool-form__field'
            },
        };
    }
   

    getDefaultElements() {
        const selectors = this.getSettings('selectors');
        return {
            $signatureElement: this.$element.find(selectors.signatureElement),
            $clearButton: this.$element.find(selectors.clearButton),
            $undoButton: this.$element.find(selectors.undoButton),
            $redoButton: this.$element.find(selectors.redoButton),
            $submitButton: this.$element.find(selectors.submitButton),
            $inputField: this.$element.find(selectors.inputField),
        };
    }
    

    bindEvents() {
        this.drawHistory = [];
        this.redoHistory = [];
        this.signaturePad = [];
        this.$element;

        const signatureEleArr = this.elements.$signatureElement;

        signatureEleArr.each((index, element) => {
            this.signatureHandler(index, element);
        });

        this.resetFormData();
        this.resizeCanvas();
        window.addEventListener("resize", () => {
            this.resizeCanvas();
        });

        this.elements.$undoButton.each((index, btn) => {
            btn.addEventListener('click', (e) => {
                jQuery(btn).closest('.wrapper').attr('data-draw','true')
                e.preventDefault();
                this.undoStroke(index);
            });
        });

        this.elements.$redoButton.each((index, btn) => {
            btn.addEventListener('click', (e) => {
                jQuery(btn).closest('.wrapper').attr('data-draw','true')
                e.preventDefault();
                this.redoStroke(index);
            });
        });

        this.submitHandler();
    }

    signatureHandler(index, element) {
        const canvasElement = jQuery(element);
        const color = '' === canvasElement.data('color') ? '#ffffff' : canvasElement.data('color');
        const bgColor = '' === canvasElement.data('bgColor') ? '#000000' : canvasElement.data('bgColor');
        const penwidth = canvasElement.data('penWidth');
    
        this.signaturePad[index] = new SignaturePad(element, {
            backgroundColor: bgColor,
            penColor: color,
            minWidth: penwidth,
            maxWidth: penwidth,
        });        
        
        this.drawHistory[index] = [];
        this.redoHistory[index] = [];

        // Pen color picker integration
        const signaturePlaceholder = canvasElement.closest('.wrapper').find('.signature-placeholder')
        signaturePlaceholder.css({
            'color':color,
        })
        const actionButtons = canvasElement.closest('.wrapper').find('.action-buttons .action-button')
        actionButtons.css({
            'color':color,
        })
        const canvasWrapper = canvasElement.closest('.signature-pad-wrapper');
        const colorPicker = canvasWrapper.find('.signature-color-picker');
        colorPicker.on('input', (e) => {
            this.signaturePad[index].penColor = e.target.value;
        });

        this.addClearButtonListener(index, element);
        this.updateInputValue(index, this.signaturePad[index]);
        this.updateUndoRedoVisibility(index);
    }   

    addClearButtonListener(index, element) {
        const clearButton = this.elements.$clearButton[index];
        const inputField = this.elements.$inputField[index];

        let PrevWrapper = jQuery(inputField).prev('.signature-pad-wrapper').find('.wrapper');
        if (clearButton) {
            clearButton.addEventListener('click', (e) => {
                e.preventDefault();
                PrevWrapper.attr('data-draw','false')
                inputField.value='';
                jQuery(inputField).trigger("change");
                this.signaturePad[index].clear();
                
                this.drawHistory[index] = [];
                this.redoHistory[index] = [];
                this.updateUndoRedoVisibility(index);
            });
        }
    }

    updateInputValue(index, signObj) {
        signObj.addEventListener('beginStroke',()=>{
            let canvasEl = jQuery(signObj.canvas)
            canvasEl.closest('.wrapper').attr('data-draw','true')
        })

        const inputField = this.elements.$inputField;
        signObj.addEventListener("endStroke", () => {
            const allStrokes = signObj.toData();
            const newStroke = allStrokes[allStrokes.length - 1]; 
            this.drawHistory[index].push(newStroke); 
            this.redoHistory[index] = [];

            // Update undo/redo button visibility
            this.updateUndoRedoVisibility(index);

            const url = signObj.toDataURL();
            if (!signObj.isEmpty()) {
                inputField[index].value = url;
                jQuery(inputField[index]).trigger("change");
            }
        });
    }
    
    undoStroke(index) {
        if (!this.drawHistory[index].length) return;

        const inputField = this.elements.$inputField[index];
        const signPad = this.signaturePad[index];
        const lastStroke = this.drawHistory[index].pop();
        this.redoHistory[index].push(lastStroke);

        signPad.clear();
        signPad.fromData(this.drawHistory[index]);
        jQuery(inputField).trigger("change");

        this.updateUndoRedoVisibility(index);
    }

    redoStroke(index) {
        if (!this.redoHistory[index].length) return;

        const inputField = this.elements.$inputField[index];
        const signPad = this.signaturePad[index];
        const redoStroke = this.redoHistory[index].pop();

        this.drawHistory[index].push(redoStroke);

        signPad.clear();
        signPad.fromData(this.drawHistory[index]);
        jQuery(inputField).trigger("change");

        this.updateUndoRedoVisibility(index);
    }

    updateUndoRedoVisibility(index) {
        const undoButton = jQuery(this.elements.$undoButton[index]);
        const redoButton = jQuery(this.elements.$redoButton[index]);

        const hasUndo = this.drawHistory[index]?.length > 0;
        const hasRedo = this.redoHistory[index]?.length > 0;

        if (hasUndo) {
            undoButton.addClass('active');
        } else {
            undoButton.removeClass('active');
        }

        if (hasRedo) {
            redoButton.addClass('active');
        } else {
            redoButton.removeClass('active');
        }
    }


    submitHandler() {
        setTimeout(()=>{
            this.$element.find('.elementor-field-type-next button').on('click',(e)=>{
                this.handleSubmissionOnClick(e);
            })
        },100)

        const submitButton = this.elements.$submitButton;
        submitButton.on('click', (e) => {
            this.handleSubmissionOnClick(e);
        });
    }


    handleSubmissionOnClick(e){
        let errorVisible=false;
        // e.preventDefault();
        this.signaturePad.forEach(signatureObj => {
            const parentWrp = signatureObj.canvas.closest('.is-field-type-signature');
            const inputField = jQuery(parentWrp).find('input[type="signature"]');
            jQuery(parentWrp).find('span.sf-sugnature-error-span').remove();
            if (inputField[0].required && signatureObj.isEmpty() && !errorVisible) {
                errorVisible=true;
                jQuery(inputField).after('<span class="elementor-message elementor-message-danger elementor-help-inline elementor-form-help-inline sf-sugnature-error-span">Signature is required.</span>');
                e.preventDefault();
            }
        })
    }

    resizeCanvas() {
        this.signaturePad.forEach(signatureObj => {
            const canvas = signatureObj.canvas;
            const ratio = Math.max(window.devicePixelRatio || 1, 1);
            canvas.width = canvas.offsetWidth * ratio;
            canvas.height = canvas.offsetHeight * ratio;
            canvas.getContext("2d").scale(ratio, ratio);
            signatureObj.clear();
        })

    }

    resetFormData() {
        // Update form filed hidden status after form submit
        const currentForm = this.$element.data('id');
        const element = this.elements.$element;
        jQuery(document).on('submit_success', (e, data) => {
            const submitFormId = jQuery(e.target).closest('.elementor-element.elementor-widget.elementor-widget-cool-form').data('id');
            if (submitFormId === currentForm) {
                this.signaturePad.forEach((signatureObj,index) => {
                    signatureObj.clear();
                        this.drawHistory[index] = [];
                        this.redoHistory[index] = [];
                });
            }
        });
    }


}


jQuery(window).on('elementor/frontend/init', () => {
    const addHandler = ($element) => {
        elementorFrontend.elementsHandler.addHandler(CoolFormSFFEF, {
            $element,
        });
    };
    elementorFrontend.hooks.addAction('frontend/element_ready/cool-form.default', addHandler);
});
