<?php

namespace GriffinForms\Admin\App\Html\Modals\Shared;

trait GuidedFlowShell
{
    protected function printGuidedFlowShellJs()
    {
        echo '
        window.griffinformsGuidedFlowShell = window.griffinformsGuidedFlowShell || (function() {
            function normalizeSteps(flow) {
                const rawSteps = typeof flow.getSteps === "function" ? flow.getSteps() : (flow.steps || []);
                const visibleSteps = rawSteps.filter(function(step) {
                    return step && step.id && !step.hidden;
                });

                let currentStepId = String(flow.currentStepId || "");
                const firstStepId = visibleSteps.length ? String(visibleSteps[0].id || "") : "";

                if (!currentStepId || !visibleSteps.some(function(step) {
                    return String(step.id || "") === currentStepId;
                })) {
                    currentStepId = firstStepId;
                }

                const currentIndex = visibleSteps.findIndex(function(step) {
                    return String(step.id || "") === currentStepId;
                });

                return {
                    steps: visibleSteps,
                    currentStepId: currentStepId,
                    currentIndex: currentIndex,
                    isFirst: currentIndex <= 0,
                    isLast: currentIndex === (visibleSteps.length - 1)
                };
            }

            function renderProgress(flow, normalized) {
                const container = flow.progressContainer;
                if (!container || !container.length) {
                    return;
                }

                if (!normalized.steps.length) {
                    container.empty().addClass("d-none");
                    return;
                }

                const progress = jQuery("<div>", { class: "gf-guided-flow-progress", role: "list" });
                normalized.steps.forEach(function(step, index) {
                    const stateClass = index < normalized.currentIndex
                        ? "is-complete"
                        : (index === normalized.currentIndex ? "is-current" : "is-upcoming");
                    const item = jQuery("<div>", {
                        class: "gf-guided-flow-progress-item " + stateClass,
                        role: "listitem"
                    });
                    const position = normalized.steps.length > 1
                        ? ((index / (normalized.steps.length - 1)) * 100)
                        : 0;
                    item.css("--gf-guided-flow-step-position", position + "%");
                    item.append(jQuery("<span>", {
                        class: "gf-guided-flow-progress-bead",
                        text: index < normalized.currentIndex ? "\u2713" : String(index + 1)
                    }));
                    item.append(jQuery("<span>", {
                        class: "gf-guided-flow-progress-label",
                        text: step.label || ("Step " + (index + 1))
                    }));
                    progress.append(item);
                });

                container.empty().removeClass("d-none").append(progress);
            }

            function renderNav(flow, normalized) {
                const container = flow.navContainer;
                if (!container || !container.length) {
                    return;
                }

                if (!normalized.steps.length) {
                    container.empty().addClass("d-none");
                    return;
                }

                const nav = jQuery("<div>", { class: "gf-guided-flow-nav-shell d-flex align-items-center gap-2" });
                const backButton = jQuery("<button>", {
                    type: "button",
                    class: "gf-btn gf-btn-secondary gf-guided-flow-back",
                    text: flow.backLabel || "Back"
                }).prop("disabled", !!flow.isBusy || normalized.isFirst);

                const nextButton = jQuery("<button>", {
                    type: "button",
                    class: "gf-btn gf-btn-primary gf-guided-flow-next",
                    text: flow.nextLabel || "Next"
                }).prop("disabled", !!flow.isBusy || normalized.isLast);

                nav.append(backButton, nextButton);
                container.empty().removeClass("d-none").append(nav);
            }

            function sync(flow) {
                const normalized = normalizeSteps(flow);
                flow.currentStepId = normalized.currentStepId;
                renderProgress(flow, normalized);
                renderNav(flow, normalized);

                if (typeof flow.onSync === "function") {
                    flow.onSync(normalized);
                }

                return normalized;
            }

            function goNext(flow) {
                const normalized = sync(flow);
                if (!normalized.steps.length || normalized.isLast) {
                    return normalized;
                }

                if (typeof flow.validateStep === "function") {
                    const result = flow.validateStep(normalized.currentStepId, normalized) || {};
                    if (result.valid === false) {
                        if (typeof flow.onInvalid === "function") {
                            flow.onInvalid(result, normalized);
                        }
                        return normalized;
                    }
                }

                const nextStep = normalized.steps[normalized.currentIndex + 1];
                flow.currentStepId = nextStep ? String(nextStep.id || "") : normalized.currentStepId;
                return sync(flow);
            }

            function goBack(flow) {
                const normalized = sync(flow);
                if (!normalized.steps.length || normalized.isFirst) {
                    return normalized;
                }

                const previousStep = normalized.steps[normalized.currentIndex - 1];
                flow.currentStepId = previousStep ? String(previousStep.id || "") : normalized.currentStepId;
                return sync(flow);
            }

            return {
                sync: sync,
                goNext: goNext,
                goBack: goBack
            };
        })();';
    }
}
