(function () {
const el = wp.element.createElement;
const useState = wp.element.useState;

// Intention library: label + meaning + implication + evidence prompt
const INTENTIONS = {
alleviate_suffering: {
label: "Alleviate suffering",
meaning: "Impact means meeting urgent needs and reducing harm in the near term.",
implication: "Prioritize proven interventions, reliable partners, and speed of execution.",
evidence: "Who is better off, how soon, and by how much?"
},
advance_equity: {
label: "Advance equity and justice",
meaning: "Impact means shifting power, access, and outcomes for historically excluded groups.",
implication: "Fund movement leaders, community accountability, and long-term systems work.",
evidence: "Whose voice and influence increased, and what changed as a result?"
},
create_opportunity: {
label: "Create opportunity",
meaning: "Impact means expanding pathways for people to thrive over time.",
implication: "Back talent, education, jobs, mobility, and catalytic supports.",
evidence: "What durable opportunities became available that were not before?"
},
strengthen_community: {
label: "Strengthen community",
meaning: "Impact means healthier, more connected communities with stronger local capacity.",
implication: "Support place-based organizations, collaboration, and civic infrastructure.",
evidence: "What improved locally, and who will carry it forward?"
},
support_innovation: {
label: "Support innovation",
meaning: "Impact means accelerating new ideas that can outperform the status quo.",
implication: "Use risk capital, pilots, learning loops, and disciplined iteration.",
evidence: "What did we learn, what worked, and what is ready to scale?"
},
improve_systems: {
label: "Improve systems and policy",
meaning: "Impact means changing rules, incentives, or structures that shape outcomes.",
implication: "Fund policy capacity, coalitions, advocacy (where appropriate), and strategy.",
evidence: "What system shifted, and how will that persist without us?"
},
respond_to_crisis: {
label: "Respond to crisis",
meaning: "Impact means rapid relief when timing matters most.",
implication: "Build rapid response capacity and choose partners with operational readiness.",
evidence: "How quickly did support reach people, and what did it prevent?"
},
protect_future: {
label: "Protect the future",
meaning: "Impact means reducing long-range risk and increasing resilience for future generations.",
implication: "Invest in climate, prevention, preparedness, and resilience-building.",
evidence: "What risk decreased, and what resilience increased over a defined horizon?"
},
build_knowledge: {
label: "Build knowledge and learning",
meaning: "Impact means producing insight that changes how decisions are made.",
implication: "Support research, evaluation, field learning, and practical dissemination.",
evidence: "Who used the knowledge, and what changed because of it?"
},
amplify_voices: {
label: "Amplify underheard voices",
meaning: "Impact means elevating leadership and storytelling from people closest to the issue.",
implication: "Fund narrative change, leadership development, and community-led approaches.",
evidence: "Whose voice reached new audiences, and what shifted as a result?"
},
build_institutions: {
label: "Build strong institutions",
meaning: "Impact means durable organizations with the capacity to deliver at a high level.",
implication: "Provide multi-year, flexible support and governance-strengthening.",
evidence: "What capabilities improved, and what results followed?"
},
express_values: {
label: "Express values and identity",
meaning: "Impact means your giving reflects who you are and what you stand for.",
implication: "Clarify a giving philosophy, align vehicles, and communicate intent well.",
evidence: "Does the portfolio clearly reflect values, priorities, and boundaries?"
},
inspire_others: {
label: "Inspire others to give",
meaning: "Impact means your philanthropy mobilizes additional people and resources.",
implication: "Use visibility, partnerships, and catalytic commitments to bring others in.",
evidence: "Who joined, how much was mobilized, and why did it happen?"
}
};

// 10 forced-choice tradeoffs (A vs B). Each maps to two intentions.
const QUESTIONS = [
{ a: "alleviate_suffering", b: "improve_systems", prompt: "Which feels more like real impact to you?" },
{ a: "advance_equity", b: "build_institutions", prompt: "When priorities compete, you lean toward:" },
{ a: "respond_to_crisis", b: "protect_future", prompt: "Your giving is most compelling when it:" },
{ a: "support_innovation", b: "alleviate_suffering", prompt: "You would rather fund:" },
{ a: "strengthen_community", b: "create_opportunity", prompt: "If you had to choose, impact is:" },
{ a: "build_knowledge", b: "respond_to_crisis", prompt: "You value philanthropy that:" },
{ a: "amplify_voices", b: "build_institutions", prompt: "You are most drawn to funding that:" },
{ a: "express_values", b: "improve_systems", prompt: "You most want your giving to:" },
{ a: "inspire_others", b: "advance_equity", prompt: "Success looks more like:" },
{ a: "protect_future", b: "strengthen_community", prompt: "Over a long horizon, you want to:" }
];

function sortTop(scores, n) {
return Object.entries(scores)
.sort((x, y) => (y[1] || 0) - (x[1] || 0))
.slice(0, n)
.map(([key, score]) => ({ key, score, ...INTENTIONS[key] }));
}

function App(props) {
const cfg = props.config || {};
const title = cfg.title || "Define what impact means to you";

const [step, setStep] = useState("quiz"); // quiz | lead | results
const [qIndex, setQIndex] = useState(0);
const [choices, setChoices] = useState(Array(QUESTIONS.length).fill(null)); // 'a' or 'b'

const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [reflection1, setReflection1] = useState("");
const [reflection2, setReflection2] = useState("");

const [submitting, setSubmitting] = useState(false);
const [submitError, setSubmitError] = useState("");

const answered = choices.filter(Boolean).length;
const done = answered === QUESTIONS.length;

const scores = Object.keys(INTENTIONS).reduce((acc, k) => (acc[k] = 0, acc), {});
choices.forEach((c, i) => {
if (!c) return;
const q = QUESTIONS[i];
const key = c === "a" ? q.a : q.b;
scores[key] += 1;
});

const top3 = sortTop(scores, 3).map(t => ({
key: t.key,
label: t.label,
score: t.score,
meaning: t.meaning,
implication: t.implication,
evidence: t.evidence
}));

function pick(choice) {
const next = [...choices];
next[qIndex] = choice;
setChoices(next);
if (qIndex < QUESTIONS.length - 1) setQIndex(qIndex + 1);
}

function goNext() {
if (!done) return;
setStep("lead");
}

function canSubmit() {
return email.trim().length > 3;
}

async function submit() {
setSubmitError("");
setSubmitting(true);

try {
const answersPayload = { choices };

const resultsPayload = {
top3,
reflections: {
"3_year_success": reflection1 || "",
"avoid": reflection2 || ""
}
};

const res = await fetch(SPImpactQuiz.restUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-WP-Nonce": SPImpactQuiz.nonce
},
body: JSON.stringify({
name: name || null,
email: email || null,
answers: answersPayload,
results: resultsPayload,
pageUrl: window.location.href
})
});

const data = await res.json();
if (!res.ok || !data.ok) throw new Error((data && data.message) ? data.message : "Submit failed.");

setStep("results");
} catch (e) {
setSubmitError(e.message || "Submit failed.");
} finally {
setSubmitting(false);
}
}

const q = QUESTIONS[qIndex];

return el("div", { className: "spiq-card premium" },
el("div", { className: "spiq-header" },
el("h2", { className: "spiq-title" }, title),
el("p", { className: "spiq-subtitle" },
"This is a prioritization tool designed to support long-term legacy and funding decisions."
)
),

step === "quiz" && el("div", null,
el("div", { className: "spiq-progress premium" },
el("div", { className: "spiq-progress-bar", style: { width: Math.round((answered / QUESTIONS.length) * 100) + "%" } })
),
el("div", { className: "spiq-qmeta" },
el("div", { className: "spiq-muted" }, "Question ", String(qIndex + 1), " of ", String(QUESTIONS.length)),
el("div", { className: "spiq-muted" }, answered, " answered")
),
el("div", { className: "spiq-question" },
el("div", { className: "spiq-question-prompt" }, q.prompt),
el("div", { className: "spiq-choicegrid" },
el("button", { type: "button", className: "spiq-choice", onClick: () => pick("a") },
el("div", { className: "spiq-choice-title" }, INTENTIONS[q.a].label),
el("div", { className: "spiq-choice-body" }, INTENTIONS[q.a].meaning)
),
el("button", { type: "button", className: "spiq-choice", onClick: () => pick("b") },
el("div", { className: "spiq-choice-title" }, INTENTIONS[q.b].label),
el("div", { className: "spiq-choice-body" }, INTENTIONS[q.b].meaning)
)
)
),
el("div", { className: "spiq-actions" },
el("button", {
type: "button",
className: (done ? "spiq-btn" : "spiq-btn disabled"),
disabled: !done,
onClick: goNext
}, "Continue to results")
)
),

step === "lead" && el("div", null,
el("div", { className: "spiq-panel" },
el("h3", { className: "spiq-h3" }, "Your preliminary top intentions"),
el("ol", { className: "spiq-results" },
top3.map((t) =>
el("li", { key: t.key },
el("div", { className: "spiq-result-label" }, t.label),
el("div", { className: "spiq-muted" }, t.implication)
)
)
)
),
el("div", { className: "spiq-field" },
el("label", null, "Name (optional)"),
el("input", { type: "text", value: name, onChange: (e) => setName(e.target.value), placeholder: "Your name" })
),
el("div", { className: "spiq-field" },
el("label", null, "Email (required)"),
el("input", { type: "email", value: email, onChange: (e) => setEmail(e.target.value), placeholder: "you@example.com" })
),
el("div", { className: "spiq-field" },
el("label", null, "In 3 years, what would make you say: “This worked” (optional)"),
el("textarea", { value: reflection1, onChange: (e) => setReflection1(e.target.value), rows: 3, placeholder: "A short description of success…" })
),
el("div", { className: "spiq-field" },
el("label", null, "What do you want to avoid (optional)"),
el("textarea", { value: reflection2, onChange: (e) => setReflection2(e.target.value), rows: 3, placeholder: "A short description of what you do not want…" })
),
submitError ? el("div", { className: "spiq-error" }, submitError) : null,
el("div", { className: "spiq-actions" },
el("button", { type: "button", className: "spiq-btn secondary", onClick: () => setStep("quiz") }, "Back"),
el("button", {
type: "button",
className: canSubmit() ? "spiq-btn" : "spiq-btn disabled",
disabled: !canSubmit() || submitting,
onClick: submit
}, submitting ? "Saving..." : "Get my results")
),
el("p", { className: "spiq-muted" },
"We use your responses to prepare a results summary and follow up if requested."
)
),

step === "results" && el("div", null,
el("div", { className: "spiq-panel" },
el("h3", { className: "spiq-h3" }, "Your impact definition"),
el("p", { className: "spiq-subtitle" },
"These intentions describe how you are most likely to define success, and what that implies for funding choices."
),
el("div", { className: "spiq-resultcards" },
top3.map((t) =>
el("div", { key: t.key, className: "spiq-resultcard" },
el("div", { className: "spiq-resultcard-title" }, t.label),
el("div", { className: "spiq-resultcard-section" },
el("div", { className: "spiq-kicker" }, "Meaning"),
el("div", null, t.meaning)
),
el("div", { className: "spiq-resultcard-section" },
el("div", { className: "spiq-kicker" }, "What it implies"),
el("div", null, t.implication)
),
el("div", { className: "spiq-resultcard-section" },
el("div", { className: "spiq-kicker" }, "Evidence to look for"),
el("div", null, t.evidence)
)
)
)
)
),
el("div", { className: "spiq-actions" },
el("button", { type: "button", className: "spiq-btn secondary", onClick: () => window.location.reload() }, "Retake"),
el("a", { className: "spiq-btn", href: "/contact/" }, "Discuss my results")
)
)
);
}

function boot() {
const root = document.getElementById("sp-impact-quiz-root");
if (!root) return;
let config = {};
try { config = JSON.parse(root.getAttribute("data-config") || "{}"); } catch (e) {}
wp.element.render(el(App, { config }), root);
}

if (document.readyState === "loading") document.addEventListener("DOMContentLoaded", boot);