(function () {
    const config = window.gfMigrationPage || null;
    if (!config) {
        return;
    }

    const state = config.state || "select";
    const strings = config.strings || {};
    const apiFetch = window.wp && window.wp.apiFetch ? window.wp.apiFetch : null;
    if (!apiFetch) {
        return;
    }

    const statusPhrases = [
        "Reading your forms…",
        "Mapping fields…",
        "Creating GriffinForms layout…",
        "Transferring submissions…",
        "Finalizing…",
    ];

    function apiPath(path) {
        const restBase = String(config.restBase || "");
        const normalizedPath = String(path || "");
        const wpJsonIndex = restBase.indexOf("/wp-json/");
        let basePath = restBase;

        if (wpJsonIndex >= 0) {
            basePath = restBase.substring(wpJsonIndex + "/wp-json".length);
        } else if (/^https?:\/\//i.test(restBase)) {
            try {
                basePath = new URL(restBase).pathname;
            } catch (e) {
                basePath = restBase;
            }
        }

        basePath = basePath.replace(/\/$/, "");
        return basePath + normalizedPath;
    }

    function setNonce(headers) {
        return Object.assign({}, headers || {}, { "X-WP-Nonce": config.restNonce });
    }

    function redirectToRunning(jobId) {
        window.location.href = config.runningUrlBase + "&job_id=" + encodeURIComponent(jobId);
    }

    function redirectToResults(jobId, data) {
        try {
            window.sessionStorage.setItem("gfMigrationResult:" + jobId, JSON.stringify(data));
        } catch (e) {
        }
        window.location.href = config.resultsUrlBase + "&job_id=" + encodeURIComponent(jobId);
    }

    function escapeHtml(value) {
        return String(value)
            .replace(/&/g, "&amp;")
            .replace(/</g, "&lt;")
            .replace(/>/g, "&gt;")
            .replace(/"/g, "&quot;")
            .replace(/'/g, "&#039;");
    }

    function initSelectState() {
        const tabs = Array.from(document.querySelectorAll(".gf-migration-tab"));
        const panels = Array.from(document.querySelectorAll(".gf-migration-panel"));

        function activate(source) {
            tabs.forEach((tab) => {
                const active = tab.getAttribute("data-source") === source;
                tab.classList.toggle("is-active", active);
                tab.setAttribute("aria-selected", active ? "true" : "false");
            });
            panels.forEach((panel) => {
                panel.classList.toggle("is-active", panel.getAttribute("data-source") === source);
            });
        }

        tabs.forEach((tab) => {
            tab.addEventListener("click", function () {
                activate(tab.getAttribute("data-source"));
            });
        });

        function currentMode(source) {
            const selected = document.querySelector('.gf-migration-mode-radio[data-source="' + source + '"][value="selected"]');
            return selected && selected.checked ? "selected" : "all";
        }

        function sourceCheckboxes(source) {
            return Array.from(document.querySelectorAll('.gf-migration-form[data-source="' + source + '"]'));
        }

        function selectedIds(source) {
            return sourceCheckboxes(source).filter((input) => input.checked).map((input) => Number(input.value)).filter(Boolean);
        }

        function selectAllFor(source, checked) {
            sourceCheckboxes(source).forEach((input) => {
                input.checked = checked;
            });
        }

        function syncDisabledState(source) {
            const mode = currentMode(source);
            const disabled = mode === "all";
            sourceCheckboxes(source).forEach((input) => {
                input.disabled = disabled;
            });
            const selectAll = document.querySelector('.gf-migration-select-all[data-source="' + source + '"]');
            if (selectAll) {
                selectAll.disabled = disabled;
            }
            const startButton = document.querySelector('.gf-migration-start[data-source="' + source + '"]');
            if (startButton) {
                startButton.disabled = mode === "selected" && selectedIds(source).length === 0;
            }
        }

        document.querySelectorAll(".gf-migration-select-all").forEach((toggle) => {
            toggle.addEventListener("change", function () {
                selectAllFor(toggle.getAttribute("data-source"), toggle.checked);
                syncDisabledState(toggle.getAttribute("data-source"));
            });
        });

        document.querySelectorAll(".gf-migration-mode-radio").forEach((radio) => {
            radio.addEventListener("change", function () {
                const source = radio.getAttribute("data-source");
                if (radio.value === "all" && radio.checked) {
                    selectAllFor(source, true);
                }
                syncDisabledState(source);
            });
        });

        document.querySelectorAll(".gf-migration-form").forEach((checkbox) => {
            checkbox.addEventListener("change", function () {
                syncDisabledState(checkbox.getAttribute("data-source"));
            });
        });

        function renderInlineStatus(source, html) {
            const target = document.querySelector('.gf-migration-inline-status[data-source="' + source + '"]');
            if (target) {
                target.innerHTML = html;
            }
        }

        document.querySelectorAll(".gf-migration-start").forEach((button) => {
            button.addEventListener("click", function () {
                const source = button.getAttribute("data-source");
                const mode = currentMode(source);
                const ids = mode === "all"
                    ? sourceCheckboxes(source).map((input) => Number(input.value)).filter(Boolean)
                    : selectedIds(source);

                if (!ids.length) {
                    renderInlineStatus(source, '<div class="notice notice-warning inline"><p>' + escapeHtml(strings.selectOne || "Select at least one source form first.") + "</p></div>");
                    return;
                }

                const submissionToggle = document.querySelector('.gf-migration-import-submissions[data-source="' + source + '"]');
                const importSubmissions = !!(submissionToggle && submissionToggle.checked);

                renderInlineStatus(source, "<p>" + escapeHtml(strings.starting || "Starting migration job...") + "</p>");

                apiFetch({
                    path: apiPath("/migration/start"),
                    method: "POST",
                    headers: setNonce(),
                    data: {
                        source: source,
                        source_ids: ids,
                        import_submissions: importSubmissions,
                    },
                }).then((response) => {
                    if (!response || !response.success || !response.data || !response.data.job_id) {
                        throw new Error(strings.startError || "Migration start request failed.");
                    }
                    redirectToRunning(response.data.job_id);
                }).catch((error) => {
                    renderInlineStatus(source, '<div class="notice notice-error inline"><p>' + escapeHtml(error.message || strings.startError || "Migration start request failed.") + "</p></div>");
                });
            });
        });

        tabs[0] && activate(tabs[0].getAttribute("data-source"));
        tabs.forEach((tab) => syncDisabledState(tab.getAttribute("data-source")));
    }

    function initRunningState() {
        const root = document.querySelector(".gf-migration-running");
        if (!root || !config.jobId) {
            return;
        }

        const progressBar = root.querySelector(".progress-bar");
        const progressLabel = root.querySelector(".gf-migration-progress-label");
        const animatedTextLabel = root.querySelector(".gf-migration-animated-text-label");
        const animatedText = animatedTextLabel || root.querySelector(".gf-migration-animated-text");
        const inlineStatus = root.querySelector(".gf-migration-inline-status");
        let phraseIndex = 0;
        let pollTimer = null;
        let phraseTimer = null;

        function beforeUnload(event) {
            event.preventDefault();
            event.returnValue = strings.runningWarning || "";
            return event.returnValue;
        }

        function renderError(message) {
            inlineStatus.innerHTML = '<div class="notice notice-error inline"><p>' + escapeHtml(message) + '</p><p><button type="button" class="button gf-migration-retry">' + escapeHtml(strings.retry || "Retry") + "</button></p></div>";
            const retry = inlineStatus.querySelector(".gf-migration-retry");
            if (retry) {
                retry.addEventListener("click", function () {
                    inlineStatus.innerHTML = "";
                    poll();
                }, { once: true });
            }
        }

        function renderProgress(data) {
            const percent = Number(data.percent || 0);
            const processed = Number(data.processed || 0);
            const total = Number(data.total || 0);
            progressBar.style.width = percent + "%";
            progressBar.setAttribute("aria-valuenow", String(percent));
            progressLabel.textContent = percent + "% — " + processed + " of " + total + " forms";
        }

        function stopRunningState() {
            window.removeEventListener("beforeunload", beforeUnload);
            if (pollTimer) {
                window.clearTimeout(pollTimer);
            }
            if (phraseTimer) {
                window.clearInterval(phraseTimer);
            }
        }

        function schedulePoll() {
            pollTimer = window.setTimeout(poll, 1500);
        }

        function poll() {
            apiFetch({
                path: apiPath("/migration/progress?job_id=" + encodeURIComponent(config.jobId)),
                method: "GET",
                headers: setNonce(),
            }).then((response) => {
                if (!response || !response.success || !response.data) {
                    throw new Error(strings.progressError || "Migration progress request failed.");
                }

                renderProgress(response.data);
                if (response.data.done) {
                    stopRunningState();
                    redirectToResults(config.jobId, response.data);
                    return;
                }

                if (response.data.status === "error") {
                    renderError(strings.progressError || "Migration progress request failed.");
                    return;
                }

                schedulePoll();
            }).catch((error) => {
                renderError(error.message || strings.progressError || "Migration progress request failed.");
            });
        }

        phraseTimer = window.setInterval(function () {
            phraseIndex = (phraseIndex + 1) % statusPhrases.length;
            animatedText.textContent = statusPhrases[phraseIndex];
        }, 2500);

        window.addEventListener("beforeunload", beforeUnload);
        poll();
    }

    function loadResultsData(jobId) {
        try {
            const raw = window.sessionStorage.getItem("gfMigrationResult:" + jobId);
            if (raw) {
                return Promise.resolve(JSON.parse(raw));
            }
        } catch (e) {
        }

        return apiFetch({
            path: apiPath("/migration/progress?job_id=" + encodeURIComponent(jobId)),
            method: "GET",
            headers: setNonce(),
        }).then((response) => {
            if (!response || !response.success || !response.data) {
                throw new Error(strings.progressError || "Migration progress request failed.");
            }
            return response.data;
        });
    }

    function initResultsState() {
        const root = document.querySelector(".gf-migration-results");
        if (!root || !config.jobId) {
            return;
        }

        const header = root.querySelector(".gf-migration-results-header");
        const stats = root.querySelector(".gf-migration-results-stats");
        const tableWrap = root.querySelector(".gf-migration-results-table-wrap");

        function badge(status) {
            const labelMap = {
                migrated: strings.migrated || "Migrated",
                partial: strings.partial || "Partial",
                error: strings.error || "Error",
                skipped: strings.skipped || "Skipped",
            };
            return '<span class="gf-migration-badge gf-migration-badge-' + escapeHtml(status) + '">' + escapeHtml(labelMap[status] || status) + "</span>";
        }

        function render(data) {
            const result = data.result || {};
            const forms = Array.isArray(result.forms) ? result.forms : [];
            const totalSubmissions = forms.reduce((sum, form) => sum + Number(form.submissions_migrated || 0), 0);
            const totalSkipped = Array.isArray(result.skipped) ? result.skipped.length : 0;
            const hasIssues = totalSkipped > 0 || (Array.isArray(result.errors) && result.errors.length > 0) || forms.some((form) => form.status !== "migrated");

            header.innerHTML =
                '<div class="gf-notice gf-notice-' + (hasIssues ? "warning" : "success") + '">' +
                '<p>' + escapeHtml(hasIssues ? (strings.migrationIssues || "Migration completed with issues") : (strings.migrationComplete || "Migration complete")) + "</p>" +
                "</div>";

            stats.innerHTML =
                '<p>' +
                escapeHtml(forms.filter((form) => form.status === "migrated" || form.status === "partial").length) + " forms migrated · " +
                escapeHtml(totalSubmissions) + " submissions migrated · " +
                escapeHtml(totalSkipped) + " items skipped" +
                "</p>";

            if (!forms.length) {
                tableWrap.innerHTML = '<div class="notice notice-info inline"><p>' + escapeHtml(strings.noData || "No migration result data was found for this job.") + "</p></div>";
                return;
            }

            let html = '<table class="widefat striped gf-migration-results-table"><thead><tr><th>Form name</th><th>Status</th><th>Submissions</th><th>Actions</th></tr></thead><tbody>';
            forms.forEach((form, index) => {
                const formName = form.source_form_title || ("Source form #" + form.source_form_id);
                const toggleId = "gf-migration-skipped-" + index;
                html += "<tr>";
                html += "<td>" + escapeHtml(formName) + "</td>";
                html += "<td>" + badge(form.status || "migrated") + "</td>";
                html += "<td>" + escapeHtml(Number(form.submissions_migrated || 0)) + "</td>";
                html += '<td>';
                if (Array.isArray(form.skipped) && form.skipped.length) {
                    html += '<button type="button" class="button-link gf-migration-skipped-toggle" data-target="' + escapeHtml(toggleId) + '">' + escapeHtml(strings.whatSkipped || "What wasn’t migrated?") + "</button>";
                } else {
                    html += "&nbsp;";
                }
                html += "</td>";
                html += "</tr>";

                if (Array.isArray(form.skipped) && form.skipped.length) {
                    html += '<tr id="' + escapeHtml(toggleId) + '" class="gf-migration-skipped-row" hidden><td colspan="4"><ul class="gf-migration-skipped-list">';
                    form.skipped.forEach((item) => {
                        html += "<li><strong>" + escapeHtml(item.label || "") + ":</strong> " + escapeHtml(item.reason || "") + "</li>";
                    });
                    html += "</ul></td></tr>";
                }
            });
            html += "</tbody></table>";
            tableWrap.innerHTML = html;

            tableWrap.querySelectorAll(".gf-migration-skipped-toggle").forEach((button) => {
                button.addEventListener("click", function () {
                    const row = document.getElementById(button.getAttribute("data-target"));
                    if (!row) {
                        return;
                    }
                    const hidden = row.hasAttribute("hidden");
                    if (hidden) {
                        row.removeAttribute("hidden");
                        button.textContent = strings.hideSkipped || "Hide skipped items";
                    } else {
                        row.setAttribute("hidden", "hidden");
                        button.textContent = strings.whatSkipped || "What wasn’t migrated?";
                    }
                });
            });
        }

        loadResultsData(config.jobId).then(render).catch((error) => {
            tableWrap.innerHTML = '<div class="notice notice-error inline"><p>' + escapeHtml(error.message || strings.progressError || "Migration progress request failed.") + "</p></div>";
        });
    }

    if (state === "select") {
        initSelectState();
    } else if (state === "running") {
        initRunningState();
    } else if (state === "results") {
        initResultsState();
    }
})();
