(function ($, window, document) {
    'use strict';

    const data = window.peepsogettingstarteddata || {};
    const root = document.querySelector('.psa-gswizard');

    if (!root) {
        return;
    }

    const typeContent = {
        creator: {
            // step 3
            name: "Field Notes",
            tagline: "A learning community for people building real skills — not another course, a place where we actually talk about what we're working on.",
            cta: "Come learn with us",
            images: [
                'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=400&q=80',
                'https://images.unsplash.com/photo-1529070538774-1843cb3265df?w=400&q=80',
                'https://images.unsplash.com/photo-1524178232363-1fb2b075b655?w=400&q=80',
                'https://images.unsplash.com/photo-1491841550275-ad7854e35ca6?w=400&q=80'
            ],
            // step 4
            lede: "You teach, you coach, you have an audience. Here's the path from 'just made a course' to 'thriving community' — the milestones that matter, and the honest timing.",
            introTitle: "Shared truth:",
            introBody: "Creator communities succeed when the teacher shows up. Your members didn't join to talk to each other — they joined for you. Stay visible for the first 90 days. That's the deal.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Invite your warmest audience first",
                    body: "Email your existing list, your students, your clients. Not everyone — just the 20-30 most engaged. Walk them in personally. Welcome each by name. Post a 'why I built this' note and let them respond.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }, { text: "Media", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Seed the habits",
                    body: "Post 3-4 times per week. Mix teaching, questions, behind-the-scenes, and student wins. Respond to every single comment. By week 6 you'll know which members are 'core' — they show up, post, comment. Those are your champions.",
                    tools: [{ text: "Chat", premium: true }, { text: "Photos", premium: true }, { text: "Email Digest", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Add structure as it's needed",
                    body: "At ~50-100 members, sub-groups start to matter (intros, wins, Q&A, off-topic). If you sell courses, this is where LearnDash/Tutor LMS integration becomes a force-multiplier — your students get a community built around the material.",
                    tools: [{ text: "LearnDash integration", premium: true }, { text: "File Uploads", premium: true }, { text: "User Limits", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "The fork in the road",
                    body: "By now you know: is this thing alive? If yes — mobile apps become worth it, premium tiers inside the community start making sense, you can charge for access. If it's quiet, don't panic — most communities need 6 months before the flywheel turns. Keep showing up.",
                    tools: [{ text: "Mobile Apps", premium: true }, { text: "Early Access", premium: true }]
                }
            ]
        },
        brand: {
            name: "The Trailhead",
            tagline: "A space for cyclists who ride for the road less traveled. Share routes. Meet for rides. Talk gear. Bring coffee.",
            cta: "Join the ride",
            images: [
                'https://images.unsplash.com/photo-1517649763962-0c623066013b?w=400&q=80',
                'https://images.unsplash.com/photo-1485965120184-e220f721d03e?w=400&q=80',
                'https://images.unsplash.com/photo-1511994298241-608e28f14fde?w=400&q=80',
                'https://images.unsplash.com/photo-1571068316344-75bc76f77890?w=400&q=80'
            ],
            lede: "You sell something. Your customers use it. Here's how a community becomes a sales engine — not in a cheesy way, but in the way a good shop becomes a neighborhood hub.",
            introTitle: "The bike shop rule:",
            introBody: "A community tied to a product works when it's genuinely useful to own the product. Strava routes, gear reviews, ride meetups — people come for those, and they come back to you when they need a new chain, a new bike, a new jersey.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Invite your best customers by name",
                    body: "Pull a list of repeat customers, people who left reviews, people who emailed you questions. Email them personally: 'I'm opening a space for people who care about [thing]. Would love you to be in the first 20.' Expect 30-50% to say yes.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Seed with real content",
                    body: "Post questions, not announcements. 'What's your current setup?' 'What problem did you solve this week?' Your brand voice, unscripted. Share customer builds/photos/uses. Not a single sales post. Build a reason to come back.",
                    tools: [{ text: "Media", free: true }, { text: "Photos", premium: true }, { text: "Chat", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Wire it into your store",
                    body: "This is the leverage point. WooCommerce integration: community members see product threads, your product pages link to community discussions, logged-in members get the WooCommerce experience without bouncing. Members come for community, buy because they're already there.",
                    tools: [{ text: "WooCommerce integration", premium: true }, { text: "MyCred gamification", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "Lock in the loop",
                    body: "Advanced Ads (promote products inside the community to members who opted in), Early Access for new product drops to community members first, badges for contributors. Mobile apps become a real asset — push notifications when you launch something mean you're the first thing a customer sees when they pick up their phone.",
                    tools: [{ text: "Advanced Ads", premium: true }, { text: "Mobile Apps", premium: true }, { text: "BadgeOS", premium: true }]
                }
            ]
        },
        professional: {
            name: "The Guild",
            tagline: "A private network for working professionals in our field — real conversations, real job leads, and the people worth knowing.",
            cta: "Request an invite",
            images: [
                'https://images.unsplash.com/photo-1497366216548-37526070297c?w=400&q=80',
                'https://images.unsplash.com/photo-1521737711867-e3b97375f902?w=400&q=80',
                'https://images.unsplash.com/photo-1515378791036-0648a3ef77b2?w=400&q=80',
                'https://images.unsplash.com/photo-1556761175-5973dc0f32e7?w=400&q=80'
            ],
            lede: "Peers in your field. Job boards, knowledge sharing, real connections. The kind of network LinkedIn used to be before it became an ad platform.",
            introTitle: "Why people stay:",
            introBody: "Professionals join networks for one of three things: opportunities, learning, or recognition. Deliver at least two consistently and your community becomes the default place to be in your niche.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Curate the founding cohort",
                    body: "Personally invite 30-50 people you respect. Keep it invite-only for the first month. The scarcity and curation will make it feel valuable — which it should, because it is.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Establish the rhythms",
                    body: "A weekly thread: wins, asks, offers. Monthly: AMA with someone notable. Let members post job openings, opportunities, questions. Your job is to keep the conversation moving and quality high.",
                    tools: [{ text: "Chat", premium: true }, { text: "Email Digest", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Add job board, add structure",
                    body: "WP Job Manager integration turns a side thread into a real professional resource. Sub-groups for specialties. User limits to keep newcomers on track. Consider paid tiers for premium resources — professionals are used to paying for associations.",
                    tools: [{ text: "WP Job Manager integration", premium: true }, { text: "File Uploads", premium: true }, { text: "User Limits", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "The paid tier conversation",
                    body: "If it's working, consider monetizing directly. Paid Memberships Pro integration for premium resources. Events. Mentorship pairings. A job board with premium listings. Your community becomes an industry utility.",
                    tools: [{ text: "Paid Memberships Pro", premium: true }, { text: "Mobile Apps", premium: true }]
                }
            ]
        },
        hobby: {
            name: "The Workshop",
            tagline: "For people who actually care about miniature painting — work-in-progress, techniques, fails, and the weird rabbit holes we all go down.",
            cta: "Pull up a bench",
            images: [
                'https://images.unsplash.com/photo-1513708927688-890fe41c2e99?w=400&q=80',
                'https://images.unsplash.com/photo-1511512578047-dfb367046420?w=400&q=80',
                'https://images.unsplash.com/photo-1452860606245-08befc0ff44b?w=400&q=80',
                'https://images.unsplash.com/photo-1509048191080-d2984bad6ae5?w=400&q=80'
            ],
            lede: "The best communities on the internet are built around real, specific passion. You're in the right place — hobby groups outlast almost everything else online. Here's the path.",
            introTitle: "The secret:",
            introBody: "Hobby communities work because the love is already there. You're not creating demand, you're creating a home. Focus on making it feel like home — warm, welcoming, slightly inside-jokey — and the rest follows.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Find your first 10 fellow nerds",
                    body: "You know these people. Friends who share the hobby. Regulars from other forums. People on Instagram who post about it. Invite them individually. Don't try to mass-recruit. Your first 10 set the entire culture.",
                    tools: [{ text: "Groups", free: true }, { text: "Media", free: true }, { text: "Friends", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Post like a fellow enthusiast, not an admin",
                    body: "Share your own work, your current project, your questions. Ask what others are working on. Run a weekly show-and-tell. This is the phase where you set the tone — if you're enthusiastic and warm, the community will be too.",
                    tools: [{ text: "Photos", premium: true }, { text: "Chat", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Sub-groups, but only when needed",
                    body: "Don't create 15 groups on day one. Wait until you see natural clusters — beginners asking beginner questions, advanced folks wanting their own space, regional meetups forming. Then create groups that solve specific problems.",
                    tools: [{ text: "File Uploads", premium: true }, { text: "Email Digest", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "The retention game",
                    body: "Hobby communities can run for 10+ years if you keep them fed. Mobile apps help with daily engagement. Badges/MyCred reward regulars. If the hobby has products (paint, gear, tools), consider WooCommerce integration as a natural extension — not a pivot.",
                    tools: [{ text: "Mobile Apps", premium: true }, { text: "BadgeOS", premium: true }, { text: "MyCred", premium: true }]
                }
            ]
        },
        faith: {
            name: "The Fellowship",
            tagline: "A private space for our congregation to stay connected, share what's on our hearts, and walk this together — between Sundays.",
            cta: "Join the fellowship",
            images: [
                'https://images.unsplash.com/photo-1507692049790-de58290a4334?w=400&q=80',
                'https://images.unsplash.com/photo-1519491050282-cf00c82424b4?w=400&q=80',
                'https://images.unsplash.com/photo-1528378515802-98d25b4c8a2d?w=400&q=80',
                'https://images.unsplash.com/photo-1476611317561-60117649dd94?w=400&q=80'
            ],
            lede: "Your congregation, your seekers, your practice. A private space for connection that doesn't depend on a social platform that doesn't share your values.",
            introTitle: "What matters most here:",
            introBody: "Faith communities thrive on trust, continuity, and the feeling that this space is set apart. Privacy is non-negotiable. Your members need to know their conversations stay here — not mined, not sold, not shown to advertisers.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Invite the core first",
                    body: "Your most engaged members — the ones who show up consistently, lead studies, serve. Not everyone at once. The tone you establish with your first 15 people becomes the culture. Make it warm, respectful, real.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Weekly rhythms",
                    body: "Share reflections from your service. Weekly prayer or intention threads. Reading discussion. A thread for celebrations and concerns. The goal is a community that extends the weekly gathering into daily connection — not replaces it.",
                    tools: [{ text: "Email Digest", premium: true }, { text: "Chat", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Small groups matter most",
                    body: "Study groups, life stage groups, neighborhood groups. This is where real relationship happens. Sub-groups with their own space, their own rhythms, their own members. Moderators from within the community, not you doing everything.",
                    tools: [{ text: "Groups", free: true }, { text: "File Uploads", premium: true }, { text: "User Limits", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "Extend to the mission",
                    body: "Events, service opportunities, giving integration (GiveWP) for offerings/donations, and mobile apps so members stay connected through the week. A real community extension of your congregation — and it belongs to you, not Meta.",
                    tools: [{ text: "GiveWP", premium: true }, { text: "Mobile Apps", premium: true }, { text: "WP Event Manager", premium: true }]
                }
            ]
        },
        support: {
            name: "The Circle",
            tagline: "A private, moderated space for people navigating this together. What's shared here, stays here. You're not alone.",
            cta: "Request to join",
            images: [
                'https://images.unsplash.com/photo-1491438590914-bc09fcaaf77a?w=400&q=80',
                'https://images.unsplash.com/photo-1609220136736-443140cffec6?w=400&q=80',
                'https://images.unsplash.com/photo-1519834785169-98be25ec3f84?w=400&q=80',
                'https://images.unsplash.com/photo-1508672019048-805c876b67e2?w=400&q=80'
            ],
            lede: "People going through something together. These communities work differently from everything else — privacy, moderation, and careful growth matter more than scale or revenue.",
            introTitle: "The non-negotiables:",
            introBody: "Support communities live or die by trust. That means real moderation from day one, strong privacy controls, and zero tolerance for bad actors. Do not scale faster than you can moderate. A small safe space beats a large unsafe one every time.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Start small. Verify carefully.",
                    body: "Invite-only, vetted members, anonymous display names allowed, private groups by default. Your first 10-15 people set the tone for everything. Moderators in place before you open the door wider.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }, { text: "User Limits", premium: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Build the safe rhythms",
                    body: "Weekly check-in threads. Resources pinned. Clear community guidelines visible always. Your job is less 'grow fast' and more 'protect what's here'. Members come to heal and share — make that possible.",
                    tools: [{ text: "Email Digest", premium: true }, { text: "Chat", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Sub-groups for specific journeys",
                    body: "Different stages, different experiences, different needs — create smaller spaces where people going through the same thing can find each other. Careful moderator training for each. Privacy settings that let members control what they share and with whom.",
                    tools: [{ text: "Groups", free: true }, { text: "File Uploads", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "Sustainability, not scale",
                    body: "If monetization fits (paid membership for premium resources, professional access, therapy group adjuncts), Paid Memberships Pro integration makes sense. If not, keep it free and protected. The goal isn't a big community — it's a durable, safe one.",
                    tools: [{ text: "Paid Memberships Pro", premium: true }, { text: "Mobile Apps", premium: true }]
                }
            ]
        },
        local: {
            name: "Town Square",
            tagline: "A better way to stay in the loop about what's happening in our neighborhood — without the drama and ads of the big platforms.",
            cta: "Join the neighborhood",
            images: [
                'https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=400&q=80',
                'https://images.unsplash.com/photo-1523712999610-f77fbcfc3843?w=400&q=80',
                'https://images.unsplash.com/photo-1517457373958-b7bdd4587205?w=400&q=80',
                'https://images.unsplash.com/photo-1449824913935-59a10b8d2000?w=400&q=80'
            ],
            lede: "Local communities are undervalued on the internet. Nextdoor, your city subreddit, the parents' Facebook group — they're all full of ads and drama. Yours doesn't have to be.",
            introTitle: "What makes local work:",
            introBody: "Real-world anchor. Real-world meetups. When members can see each other in person, the online community becomes a coordinator — not a replacement. Plan that in from day one.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Hand-pick the anchor members",
                    body: "Local community leaders, trusted neighbors, teachers, shop owners. Not the loudest people — the most trusted. Invite them personally. Offline recruiting (flyers, mentions at events) works for this segment better than digital.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Useful over chatty",
                    body: "Post local info: events this weekend, what's opening, what's closing, who's hiring, who needs help. Be the bulletin board. Early members come for utility and stay for connection.",
                    tools: [{ text: "Chat", premium: true }, { text: "Pages", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Meetups and subgroups",
                    body: "By now you'll know who the parents are, who the cyclists are, who the dog walkers are. Create groups. Start scheduling casual real-world meetups. The moment members meet in person is when the community stops being a website and becomes something real.",
                    tools: [{ text: "WP Event Manager", premium: true }, { text: "File Uploads", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "Moderation becomes the job",
                    body: "Local gets political fast. You'll need clear rules and willing moderators. This is also where mobile apps and notifications really shine — locals want to know about today's events today, not in a weekly digest.",
                    tools: [{ text: "User Limits", premium: true }, { text: "Mobile Apps", premium: true }]
                }
            ]
        },
        other: {
            name: "Our Community",
            tagline: "A space for people who get what we're building. Come help us shape what this becomes.",
            cta: "Join us",
            images: [
                'https://images.unsplash.com/photo-1529156069898-49953e39b3ac?w=400&q=80',
                'https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=400&q=80',
                'https://images.unsplash.com/photo-1515187029135-18ee286d815b?w=400&q=80',
                'https://images.unsplash.com/photo-1494548162494-384bba4ab999?w=400&q=80'
            ],
            lede: "Your community doesn't fit a box. That's fine — most of the best ones don't. Here's the general path, and you'll tune it as you figure out what yours actually is.",
            introTitle: "The universal truth:",
            introBody: "No matter what type, every successful community needs the same thing in the first 30 days: a small group of real people who actually talk to each other. Don't scale before that's happening.",
            milestones: [
                {
                    label: "Week 1-2",
                    title: "Find your first 10 believers",
                    body: "People who get what you're building, even if you can't quite explain it yet. Invite them personally. Tell them they're early, tell them it's rough, tell them you want their help shaping it.",
                    tools: [{ text: "Groups", free: true }, { text: "Friends", free: true }, { text: "Media", free: true }]
                },
                {
                    label: "Week 3-6",
                    title: "Let the shape emerge",
                    body: "Post, ask, respond. Don't over-engineer. Watch what conversations happen naturally. Watch what questions come up. The real shape of your community tells you what it wants to be — you just have to listen.",
                    tools: [{ text: "Chat", premium: true }, { text: "Photos", premium: true }]
                },
                {
                    label: "Month 2-3",
                    title: "Structure based on reality",
                    body: "Now that you see the patterns, build for them. Sub-groups for the clusters you actually see. Integrations that fit your specific use case. This is the moment to re-evaluate — maybe you're actually a creator community, or a brand community, now that you've seen what's happening.",
                    tools: [{ text: "Email Digest", premium: true }, { text: "File Uploads", premium: true }]
                },
                {
                    label: "Month 3+",
                    title: "Double down on what's working",
                    body: "By 90 days the signal is clear. Either something's happening, or it isn't. If it is: invest. Better integrations, mobile apps, premium tiers. If it's quiet, don't give up — but do reconsider the positioning. Most communities need 6 months before they click.",
                    tools: [{ text: "Mobile Apps", premium: true }]
                }
            ]
        }
    };

    const state = {
        currentStep: Math.max(1, Math.min(5, parseInt(data.initialStep || 1, 10) || 1)),
        selectedType: data.selectedType || null,
        validImages: [],
        customImage: data.saved && data.saved.customImage && !data.saved.customImageIsDefault ? data.saved.customImage : '',
        selectedImage: null,
        imageFrame: null,
        step3Initialized: false,
        step3Dirty: false,
        step3AutoType: null,
        imageInitialized: false,
        isSavingStep3: false
    };

    const overlay = 'linear-gradient(135deg, rgba(29,35,39,0.35) 0%, rgba(29,35,39,0.6) 100%)';

    function qs(selector) { return root.querySelector(selector); }
    function qsa(selector) { return Array.prototype.slice.call(root.querySelectorAll(selector)); }

    function escapeHtml(str) {
        return String(str || '').replace(/[&<>"']/g, function (match) {
            return { '&': '&amp;', '<': '&lt;', '>': '&gt;', '"': '&quot;', "'": '&#039;' }[match];
        });
    }

    function trackEvent(event, payload) {
        if (window.console && console.log) {
            console.log('[peepso-getting-started]', event, payload || {});
        }
    }

    function getSelectedTypeData() {
        return typeContent[state.selectedType] || typeContent.other;
    }

    function getStep3Values() {
        return {
            header: (qs('#community-name') || { value: '' }).value.trim(),
            callout: (qs('#community-tagline') || { value: '' }).value.trim(),
            buttonText: (qs('#community-cta') || { value: '' }).value.trim()
        };
    }

    function getSelectedImageUrl() {
        if (state.selectedImage && state.selectedImage.value) {
            return state.selectedImage.value;
        }
        return (data.saved && data.saved.defaultImage) ? data.saved.defaultImage : '';
    }

    function setPreviewImage(url) {
        const hero = qs('#preview-hero');
        if (!hero) return;
        const finalUrl = url || (data.saved && data.saved.defaultImage) || '';
        hero.style.background = finalUrl ? `${overlay}, url('${String(finalUrl).replace(/'/g, "\'")}')` : overlay;
        hero.style.backgroundSize = 'cover';
        hero.style.backgroundPosition = 'center';
    }

    function updatePreview() {
        const values = getStep3Values();
        const nameEl = qs('#preview-name');
        const taglineEl = qs('#preview-tagline');
        const ctaEl = qs('#preview-cta');
        if (nameEl) nameEl.textContent = values.header || 'Your community';
        if (taglineEl) taglineEl.textContent = values.callout || 'What this community is about, in one line.';
        if (ctaEl) ctaEl.textContent = values.buttonText || 'Join';
        setPreviewImage(getSelectedImageUrl());
    }

    function updateImageSourceNote() {
        const note = qs('#image-source-note');
        const removeBtn = qs('#image-remove-btn');
        if (!note || !removeBtn) return;
        let text = '';
        let showRemove = false;
        if (state.selectedImage && state.selectedImage.mode === 'preset') {
            text = 'Preset image selected. It will be imported into your site media library when you continue.';
            showRemove = true;
        } else if (state.selectedImage && state.selectedImage.mode === 'custom') {
            text = 'Using your own uploaded image.';
            showRemove = true;
        } else {
            text = 'Using the default PeepSo landing page image.';
        }
        note.textContent = text;
        removeBtn.style.display = showRemove ? '' : 'none';
    }

    function setSelectedImage(mode, value) {
        state.selectedImage = { mode: mode, value: value || ((data.saved && data.saved.defaultImage) || '') };
        qsa('.image-option').forEach(function (el) {
            const isSelected = el.getAttribute('data-image-mode') === mode && el.getAttribute('data-image-value') === (value || '');
            el.classList.toggle('selected', !!isSelected);
        });
        updateImageSourceNote();
        updatePreview();
    }

    function createImageTile(mode, url, label, selected) {
        const tile = document.createElement('button');
        tile.type = 'button';
        tile.className = 'image-option' + (mode === 'custom' ? ' custom-image' : '') + (selected ? ' selected' : '');
        tile.setAttribute('data-image-mode', mode);
        tile.setAttribute('data-image-value', url || '');
        tile.style.backgroundImage = `url('${String(url || '').replace(/'/g, "\'")}')`;
        if (label) {
            const badge = document.createElement('span');
            badge.className = 'image-option-label';
            badge.textContent = label;
            tile.appendChild(badge);
        }
        tile.addEventListener('click', function () { setSelectedImage(mode, url); });
        return tile;
    }

    function showPickerNotice(message, isError) {
        const notice = qs('#image-picker-empty');
        if (!notice) return;
        if (!message) {
            notice.textContent = '';
            notice.classList.remove('is-error', 'is-success');
            notice.style.display = 'none';
            return;
        }
        notice.textContent = message;
        notice.classList.remove('is-error', 'is-success');
        notice.classList.add(isError ? 'is-error' : 'is-success');
        notice.style.display = 'block';
    }

    function showSaveMessage(message, isError) {
        const notice = qs('#step3-save-message');
        if (!notice) return;
        if (!message) {
            notice.textContent = '';
            notice.classList.remove('is-error', 'is-success');
            notice.style.display = 'none';
            return;
        }
        notice.textContent = message;
        notice.classList.remove('is-error', 'is-success');
        notice.classList.add(isError ? 'is-error' : 'is-success');
        notice.style.display = 'block';
    }

    function renderImagePicker() {
        const picker = qs('#image-picker');
        if (!picker) return;
        picker.innerHTML = '';
        if (state.customImage) {
            picker.appendChild(createImageTile('custom', state.customImage, 'Custom', state.selectedImage && state.selectedImage.mode === 'custom' && state.selectedImage.value === state.customImage));
        }
        state.validImages.forEach(function (url, index) {
            const selected = state.selectedImage && state.selectedImage.mode === 'preset' && state.selectedImage.value === url;
            picker.appendChild(createImageTile('preset', url, '', selected || (!state.selectedImage && index === 0 && !state.customImage)));
        });
        if (!state.validImages.length && !state.customImage) {
            showPickerNotice('Preset images for this community type are unavailable right now. The default PeepSo landing page image will be used unless you upload your own.', false);
        } else {
            showPickerNotice('', false);
        }
        updateImageSourceNote();
    }

    function preloadImage(url) {
        return new Promise(function (resolve) {
            if (!url) { resolve(false); return; }
            const img = new Image();
            img.onload = function () { resolve(true); };
            img.onerror = function () { resolve(false); };
            img.src = url;
        });
    }

    async function validateImages(urls) {
        const results = await Promise.all((urls || []).map(async function (url) {
            return (await preloadImage(url)) ? url : null;
        }));
        return results.filter(Boolean);
    }

    function applyTypeDefaultsToStep3(typeData) {
        const nameField = qs('#community-name');
        const taglineField = qs('#community-tagline');
        const ctaField = qs('#community-cta');
        if (nameField) nameField.value = typeData.name || '';
        if (taglineField) taglineField.value = typeData.tagline || '';
        if (ctaField) ctaField.value = typeData.cta || '';
    }

    async function populateStep3() {
        const saved = data.saved || {};
        if (!state.selectedType) state.selectedType = 'other';
        const typeData = getSelectedTypeData();
        const nameField = qs('#community-name');
        const taglineField = qs('#community-tagline');
        const ctaField = qs('#community-cta');

        if (!state.step3Initialized) {
            const hasSavedValues = !!(saved.header || saved.callout || saved.buttonText);
            if (hasSavedValues && state.selectedType === 'other') {
                if (nameField) nameField.value = saved.header || '';
                if (taglineField) taglineField.value = saved.callout || '';
                if (ctaField) ctaField.value = saved.buttonText || '';
                state.step3AutoType = null;
            } else {
                applyTypeDefaultsToStep3(typeData);
                state.step3AutoType = state.selectedType;
            }
            state.step3Initialized = true;
        } else if (!state.step3Dirty && state.step3AutoType !== state.selectedType) {
            applyTypeDefaultsToStep3(typeData);
            state.step3AutoType = state.selectedType;
        }

        state.validImages = await validateImages(typeData.images || []);
        if (!state.imageInitialized) {
            if (state.customImage) {
                state.selectedImage = { mode: 'custom', value: state.customImage };
            } else if (state.validImages.length) {
                state.selectedImage = { mode: 'preset', value: state.validImages[0] };
            } else {
                state.selectedImage = { mode: 'default', value: (saved.defaultImage || '') };
            }
            state.imageInitialized = true;
        } else if (state.selectedImage && state.selectedImage.mode === 'preset' && state.validImages.indexOf(state.selectedImage.value) === -1) {
            if (state.customImage) state.selectedImage = { mode: 'custom', value: state.customImage };
            else if (state.validImages.length) state.selectedImage = { mode: 'preset', value: state.validImages[0] };
            else state.selectedImage = { mode: 'default', value: (saved.defaultImage || '') };
        }
        renderImagePicker();
        updatePreview();
    }

    function renderPath() {
        const typeData = getSelectedTypeData();
        const timeline = qs('#timeline');
        if (qs('#path-lede')) qs('#path-lede').textContent = typeData.lede;
        if (qs('#path-intro-title')) qs('#path-intro-title').textContent = typeData.introTitle;
        if (qs('#path-intro-body')) qs('#path-intro-body').textContent = typeData.introBody;
        if (timeline) {
            timeline.innerHTML = (typeData.milestones || []).map(function (milestone) {
                const tools = (milestone.tools || []).map(function (tool) {
                    return '<span class="tool-chip ' + (tool.free ? 'free' : 'premium') + '">' + escapeHtml(tool.text) + (tool.free ? ' · Free' : '') + '</span>';
                }).join('');
                return [
                    '<div class="milestone">',
                    '<div class="milestone-label">' + escapeHtml(milestone.label) + '</div>',
                    '<h3 class="milestone-h">' + escapeHtml(milestone.title) + '</h3>',
                    '<p class="milestone-body">' + escapeHtml(milestone.body) + '</p>',
                    '<div class="milestone-tools">' + tools + '</div>',
                    '</div>'
                ].join('');
            }).join('');
        }
    }

    function updateProgress() {
        qsa('.progress-step').forEach(function (el, index) {
            el.classList.remove('active', 'done');
            if (index + 1 < state.currentStep) el.classList.add('done');
            if (index + 1 === state.currentStep) el.classList.add('active');
        });
        qsa('.progress-labels span').forEach(function (el, index) {
            el.classList.remove('active', 'done');
            if (index + 1 < state.currentStep) el.classList.add('done');
            if (index + 1 === state.currentStep) el.classList.add('active');
        });
    }

    function syncTypeSelectionUi() {
        qsa('.type-card').forEach(function (card) {
            card.classList.toggle('selected', card.getAttribute('data-type') === state.selectedType);
        });
        const nextBtn = qs('#step-2-next');
        if (nextBtn) nextBtn.disabled = !state.selectedType;
    }

    function showStep(stepNumber) {
        state.currentStep = Math.max(1, Math.min(5, parseInt(stepNumber, 10) || 1));
        qsa('.step').forEach(function (step) { step.classList.remove('active'); });
        const activeStep = qs('#step-' + state.currentStep);
        if (activeStep) activeStep.classList.add('active');
        updateProgress();
        syncTypeSelectionUi();
        showSaveMessage('', false);
        if (state.currentStep >= 3 && !state.selectedType) state.selectedType = 'other';
        if (state.currentStep === 3) populateStep3();
        if (state.currentStep === 4) renderPath();
        trackEvent('step_view', { step: state.currentStep, community_type: state.selectedType });
        window.scrollTo({ top: 0, behavior: 'smooth' });
    }

    function selectType(el) {
        if (!el) return;
        state.selectedType = el.getAttribute('data-type') || 'other';
        syncTypeSelectionUi();
        trackEvent('community_type_selected', { community_type: state.selectedType });
    }

    function restart() {
        trackEvent('wizard_restarted', {});
        state.selectedType = null;
        state.validImages = [];
        state.selectedImage = null;
        state.imageInitialized = false;
        state.step3Initialized = false;
        state.step3Dirty = false;
        state.step3AutoType = null;
        const saved = data.saved || {};
        state.customImage = saved.customImage && !saved.customImageIsDefault ? saved.customImage : '';
        if (qs('#community-name')) qs('#community-name').value = '';
        if (qs('#community-tagline')) qs('#community-tagline').value = '';
        if (qs('#community-cta')) qs('#community-cta').value = '';
        syncTypeSelectionUi();
        showStep(1);
    }

    function prevStep() {
        if (state.isSavingStep3) return;
        if (state.currentStep > 1) showStep(state.currentStep - 1);
    }

    function setStep3ButtonBusy(isBusy) {
        const btn = qs('#step-3-next');
        if (!btn) return;
        btn.classList.toggle('is-busy', !!isBusy);
        btn.disabled = !!isBusy;
        btn.textContent = isBusy ? 'Saving…' : 'Continue →';
    }

    function saveStep3() {
        return new Promise(function (resolve, reject) {
            const values = getStep3Values();
            const payload = {
                header: values.header,
                callout: values.callout,
                button_text: values.buttonText,
                image_mode: state.selectedImage ? state.selectedImage.mode : 'default',
                image_value: state.selectedImage ? state.selectedImage.value : ''
            };
            peepso.getJson('gettingstartedajax.save_step3', payload, function (response) {
                if (response && response.success) {
                    if (response.data) {
                        data.saved = data.saved || {};
                        data.saved.header = values.header;
                        data.saved.callout = values.callout;
                        data.saved.buttonText = values.buttonText;
                        data.saved.customImage = response.data.image_url || '';
                        data.saved.customImageIsDefault = !!response.data.image_is_default;
                        if (response.data.default_image) data.saved.defaultImage = response.data.default_image;
                        if (response.data.image_url) {
                            state.customImage = response.data.image_url;
                            state.selectedImage = response.data.image_is_default ? { mode: 'default', value: data.saved.defaultImage || '' } : { mode: 'custom', value: response.data.image_url };
                        } else if (response.data.image_is_default) {
                            state.customImage = '';
                            state.selectedImage = { mode: 'default', value: data.saved.defaultImage || '' };
                        }
                    }
                    renderImagePicker();
                    updatePreview();
                    resolve(response);
                    return;
                }
                reject(response && response.errors ? response.errors.join(' ') : 'Unable to save your landing page settings.');
            });
        });
    }

    function nextStep() {
        if (state.isSavingStep3) return;
        if (state.currentStep === 2 && !state.selectedType) return;
        if (state.currentStep === 3) {
            state.isSavingStep3 = true;
            setStep3ButtonBusy(true);
            showSaveMessage('', false);
            trackEvent('landing_page_saved', getStep3Values());
            saveStep3().then(function () {
                showSaveMessage('Landing page settings saved.', false);
                showStep(4);
            }).catch(function (message) {
                showSaveMessage(message || 'Something went wrong while saving the landing page settings.', true);
            }).finally(function () {
                state.isSavingStep3 = false;
                setStep3ButtonBusy(false);
            });
            return;
        }
        if (state.currentStep < 5) showStep(state.currentStep + 1);
    }

    function openMediaFrame() {
        if (!window.wp || !wp.media) return;
        if (!state.imageFrame) {
            state.imageFrame = wp.media({
                title: 'Select or upload a landing page image',
                button: { text: 'Use this image' },
                library: { type: 'image' },
                multiple: false
            });
            state.imageFrame.on('select', function () {
                const selection = state.imageFrame.state().get('selection').first();
                if (!selection) return;
                const attachment = selection.toJSON();
                if (!attachment || !attachment.url) return;
                state.customImage = attachment.url;
                setSelectedImage('custom', attachment.url);
                renderImagePicker();
            });
        }
        state.imageFrame.open();
    }

    function removeCustomOrUseDefault() {
        state.customImage = '';
        if (state.validImages.length) setSelectedImage('preset', state.validImages[0]);
        else setSelectedImage('default', (data.saved && data.saved.defaultImage) || '');
        renderImagePicker();
    }

    function subscribeNewsletter() {
        const emailField = qs('#newsletter-email');
        const email = emailField ? emailField.value.trim() : '';
        if (!email || email.indexOf('@') === -1) {
            window.alert('Please enter a valid email.');
            return;
        }

        const fields = {
            publicaccountid: '563cdd68-a533-4d35-83cf-ab4ce3155ab2',
            email: email,
            returnUrl: '',
            activationReturnUrl: '',
            activationTemplate: 'SubscriptionConfirmation',
            source: 'WebForm',
            notifyEmail: ''
        };

        const form = document.createElement('form');
        form.method = 'POST';
        form.action = 'https://api.elasticemail.com/contact/add?version=2';
        form.target = '_blank';
        form.rel = 'noopener';
        form.style.display = 'none';
        Object.keys(fields).forEach(function (name) {
            const input = document.createElement('input');
            input.type = 'hidden';
            input.name = name;
            input.value = fields[name];
            form.appendChild(input);
        });

        document.body.appendChild(form);
        trackEvent('newsletter_signup', { email: email, community_type: state.selectedType });
        form.submit();
        document.body.removeChild(form);

        if (emailField) emailField.value = '';
    }


    window.nextStep = nextStep;
    window.prevStep = prevStep;
    window.restart = restart;
    window.selectType = selectType;
    window.updatePreview = updatePreview;
    window.subscribeNewsletter = subscribeNewsletter;

    root.addEventListener('input', function (event) {
        if (event.target && /community-(name|tagline|cta)/.test(event.target.id || '')) {
            state.step3Dirty = true;
            updatePreview();
        }
    });

    qsa('.progress-step, .progress-labels span').forEach(function (el, index) {
        el.addEventListener('click', function () {
            const step = index + 1;
            if (step <= state.currentStep || step === state.currentStep + 1) showStep(step);
        });
    });

    if (qs('#image-upload-btn')) qs('#image-upload-btn').addEventListener('click', openMediaFrame);
    if (qs('#image-remove-btn')) qs('#image-remove-btn').addEventListener('click', removeCustomOrUseDefault);
    showStep(state.currentStep);
})(jQuery, window, document);
