/**
 * PDF Invoice Editor - Admin JavaScript
 */

(function($) {
    'use strict';

    var PREVIEW_FALLBACK_WIDTH = 794;
    var PREVIEW_FALLBACK_HEIGHT = 1123;

    var currentScale = 1.0;
    var isGenerating = false;
    var previewBaseWidth = PREVIEW_FALLBACK_WIDTH;
    var previewBaseHeight = PREVIEW_FALLBACK_HEIGHT;
    var previewLoadToken = 0;

    /**
     * Initialize the editor.
     */
    function init() {
        initSectionToggle();
        initPreviewControls();
        initFormHandlers();
        updateZoomLevel();

        setTimeout(function() {
            generatePreview();
        }, 800);
    }

    /**
     * Initialize section toggle.
     */
    function initSectionToggle() {
        $('[data-nxtpdf-section-title]').on('click', function() {
            var $section = $(this).closest('[data-nxtpdf-section]');
            var isCollapsed = $section.is('[data-collapsed]');

            $('[data-nxtpdf-section]').attr('data-collapsed', '');

            if (isCollapsed) {
                $section.removeAttr('data-collapsed');
            }
        });
    }

    /**
     * Initialize preview controls.
     */
    function initPreviewControls() {
        $('[data-nxtpdf-zoom-in]').on('click', function() {
            if (currentScale < 2.0) {
                currentScale += 0.25;
                updatePreviewScale();
            }
        });

        $('[data-nxtpdf-zoom-out]').on('click', function() {
            if (currentScale > 0.5) {
                currentScale -= 0.25;
                updatePreviewScale();
            }
        });

        $('[data-nxtpdf-download]').on('click', function() {
            downloadPdf();
        });

        $('[data-nxtpdf-preview-btn]').on('click', function() {
            generatePreview();
        });
    }

    /**
     * Initialize form handlers.
     */
    function initFormHandlers() {
        $('[data-nxtpdf-form]').on('submit', function(e) {
            e.preventDefault();
            saveSettings();
        });

        var debouncedPreview = debounce(function() {
            generatePreview();
        }, 500);

        $('[data-nxtpdf-form]').on(
            'input',
            'input:not([type="checkbox"]):not([type="radio"]):not([type="file"]), textarea',
            debouncedPreview
        );

        $('[data-nxtpdf-form]').on(
            'change',
            'select, input[type="checkbox"], input[type="radio"], input[type="file"], input[type="color"], input[readonly]',
            debouncedPreview
        );
    }

    /**
     * Resolve current editor option group key.
     */
    function getOptionGroup() {
        var $form = $('[data-nxtpdf-form]');

        if (!$form.length) {
            return '';
        }

        return String($form.attr('data-option-key') || '');
    }

    /**
     * Generate the live preview.
     */
    function generatePreview() {
        if (isGenerating) {
            return;
        }

        isGenerating = true;
        showLoading(true);
        hidePlaceholder();

        $.ajax({
            url: nxtpdf_admin.ajaxUrl,
            type: 'POST',
            data: {
                action: 'nxtpdf_generate_document_preview',
                nonce: nxtpdf_admin.nonce,
                settings: $('[data-nxtpdf-form]').serialize(),
                option_group: getOptionGroup()
            },
            success: function(response) {
                if (response.success && response.data.preview_url) {
                    renderPreview(response.data.preview_url);
                    return;
                }

                handlePreviewError(response.data && response.data.message ? response.data.message : nxtpdf_admin.strings.error);
            },
            error: function(xhr, status, error) {
                console.error('AJAX Error:', status, error);
                handlePreviewError(nxtpdf_admin.strings.error + ': ' + error);
            },
            complete: function() {
                isGenerating = false;
            }
        });
    }

    /**
     * Render the preview page inside the isolated iframe.
     */
    function renderPreview(previewUrl) {
        var frame = document.querySelector('[data-nxtpdf-preview-frame]');

        if (!frame) {
            handlePreviewError('Preview frame not found');
            return;
        }

        var loadToken = ++previewLoadToken;

        frame.onload = function() {
            if (loadToken !== previewLoadToken) {
                return;
            }

            var previewError = getPreviewError(frame);
            if (previewError) {
                handlePreviewError(previewError);
                return;
            }

            syncPreviewFrameSize();
            updatePreviewScale();
            bindDeferredPreviewResizes(frame, loadToken);
            showPreview();
            showLoading(false);
        };

        frame.src = previewUrl;
    }

    /**
     * Read a rendered preview error message from the iframe document.
     */
    function getPreviewError(frame) {
        var frameDocument = frame.contentDocument;
        var errorNode;

        if (!frameDocument) {
            return '';
        }

        errorNode = frameDocument.querySelector('[data-nxtpdf-preview-error]');
        if (!errorNode) {
            return '';
        }

        return String(
            errorNode.getAttribute('data-nxtpdf-preview-error') ||
            errorNode.textContent ||
            nxtpdf_admin.strings.error
        ).trim();
    }

    /**
     * Re-measure after delayed assets such as images finish loading.
     */
    function bindDeferredPreviewResizes(frame, loadToken) {
        var frameDocument = frame.contentDocument;

        if (frameDocument) {
            Array.prototype.forEach.call(frameDocument.images || [], function(image) {
                image.addEventListener('load', function() {
                    if (loadToken !== previewLoadToken) {
                        return;
                    }

                    syncPreviewFrameSize();
                    updatePreviewScale();
                });
            });
        }

        [100, 300, 800, 1500].forEach(function(delay) {
            setTimeout(function() {
                if (loadToken !== previewLoadToken) {
                    return;
                }

                syncPreviewFrameSize();
                updatePreviewScale();
            }, delay);
        });
    }

    /**
     * Measure the rendered preview size.
     */
    function syncPreviewFrameSize() {
        var frame = document.querySelector('[data-nxtpdf-preview-frame]');

        if (!frame || !frame.contentDocument) {
            return;
        }

        var frameDocument = frame.contentDocument;
        var body = frameDocument.body;
        var documentElement = frameDocument.documentElement;
        var previewDocument = frameDocument.querySelector('[data-nxtpdf-preview-document]');

        if (!body || !documentElement) {
            return;
        }

        if (previewDocument) {
            previewBaseWidth = Math.max(
                previewDocument.scrollWidth,
                previewDocument.offsetWidth,
                PREVIEW_FALLBACK_WIDTH
            );

            previewBaseHeight = Math.max(
                previewDocument.scrollHeight,
                previewDocument.offsetHeight,
                PREVIEW_FALLBACK_HEIGHT
            );
        } else {
            previewBaseWidth = Math.max(
                body.scrollWidth,
                body.offsetWidth,
                documentElement.scrollWidth,
                documentElement.offsetWidth,
                PREVIEW_FALLBACK_WIDTH
            );

            previewBaseHeight = Math.max(
                body.scrollHeight,
                body.offsetHeight,
                documentElement.scrollHeight,
                documentElement.offsetHeight,
                PREVIEW_FALLBACK_HEIGHT
            );
        }

        frame.style.width = previewBaseWidth + 'px';
        frame.style.height = previewBaseHeight + 'px';
    }

    /**
     * Update iframe scaling and shell dimensions.
     */
    function updatePreviewScale() {
        var frame = document.querySelector('[data-nxtpdf-preview-frame]');
        var shell = document.querySelector('[data-nxtpdf-preview-shell]');

        updateZoomLevel();

        if (!frame || !shell) {
            return;
        }

        shell.style.width = (previewBaseWidth * currentScale) + 'px';
        shell.style.height = (previewBaseHeight * currentScale) + 'px';
        frame.style.transform = 'scale(' + currentScale + ')';
        frame.style.transformOrigin = 'top left';
    }

    /**
     * Save settings.
     */
    function saveSettings() {
        var $btn = $('[data-nxtpdf-save-btn]');
        var originalHtml = $btn.html();

        $btn.prop('disabled', true).html(
            '<svg class="nxtpdf-spinner nxtpdf-btn-icon" fill="none" viewBox="0 0 24 24">' +
            '<circle class="nxtpdf-spinner-track" cx="12" cy="12" r="10" stroke="currentColor" stroke-width="4"></circle>' +
            '<path class="nxtpdf-spinner-head" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>' +
            '</svg> Saving...'
        );

        $.ajax({
            url: nxtpdf_admin.ajaxUrl,
            type: 'POST',
            data: {
                action: 'nxtpdf_save_document_settings',
                nonce: nxtpdf_admin.nonce,
                settings: $('[data-nxtpdf-form]').serialize(),
                option_group: getOptionGroup()
            },
            success: function(response) {
                if (response.success) {
                    showToast(nxtpdf_admin.strings.saved, 'success');
                } else {
                    showToast(response.data && response.data.message ? response.data.message : 'Error saving settings', 'error');
                }
            },
            error: function() {
                showToast('Error saving settings', 'error');
            },
            complete: function() {
                $btn.prop('disabled', false).html(originalHtml);
            }
        });
    }

    /**
     * Download PDF.
     */
    function downloadPdf() {
        var optionGroup = getOptionGroup();
        var $downloadForm = $('<form>', {
            method: 'POST',
            action: nxtpdf_admin.ajaxUrl,
            style: 'display:none;'
        });

        [
            ['action', 'nxtpdf_download_document'],
            ['nonce', nxtpdf_admin.nonce],
            ['settings', $('[data-nxtpdf-form]').serialize()],
            ['option_group', optionGroup]
        ].forEach(function(field) {
            $('<input>', {
                type: 'hidden',
                name: field[0],
                value: field[1]
            }).appendTo($downloadForm);
        });

        $('body').append($downloadForm);
        $downloadForm[0].submit();
        $downloadForm.remove();
    }

    /**
     * Handle preview errors.
     */
    function handlePreviewError(message) {
        showLoading(false);
        console.error('Preview Error:', message);
        showToast(message, 'error');
        showPlaceholder();
    }

    /**
     * UI helpers.
     */
    function showLoading(show) {
        var $element = $('[data-nxtpdf-loading]');

        if (show) {
            $element.attr('data-active', '');
            return;
        }

        $element.removeAttr('data-active');
    }

    function showPreview() {
        $('[data-nxtpdf-preview-shell]').attr('data-active', '');
        $('[data-nxtpdf-placeholder]').removeAttr('data-active');
    }

    function hidePreview() {
        $('[data-nxtpdf-preview-shell]').removeAttr('data-active');
    }

    function showPlaceholder() {
        $('[data-nxtpdf-placeholder]').attr('data-active', '');
        hidePreview();
    }

    function hidePlaceholder() {
        $('[data-nxtpdf-placeholder]').removeAttr('data-active');
    }

    function updateZoomLevel() {
        $('[data-nxtpdf-zoom-level]').text(Math.round(currentScale * 100) + '%');
    }

    function showToast(message, type) {
        $('[data-nxtpdf-toast]').remove();

        var $toast = $('<div data-nxtpdf-toast="' + type + '">' + message + '</div>');
        $('body').append($toast);

        setTimeout(function() {
            $toast.fadeOut(300, function() {
                $(this).remove();
            });
        }, 4000);
    }

    /**
     * Debounce helper.
     */
    function debounce(func, wait) {
        var timeout;

        return function() {
            var args = arguments;
            var context = this;
            var later = function() {
                clearTimeout(timeout);
                func.apply(context, args);
            };

            clearTimeout(timeout);
            timeout = setTimeout(later, wait);
        };
    }

    $(document).ready(init);
})(jQuery);
