import test from "node:test";
import assert from "node:assert/strict";
import {
  SOMETHING_ELSE_LABEL,
  SOMETHING_ELSE_VALUE,
  allQuestionsAnswered,
  createAnsweredResult,
  createCancelledResult,
  createCustomAnswer,
  createPredefinedAnswer,
  nextTabAfterAnswer,
  normalizeQuestions,
  summarizeAnswers,
} from "./question-core.mjs";

test("normalizeQuestions adds default labels and appends the Something else option", () => {
  const [question] = normalizeQuestions([
    {
      id: "scope",
      prompt: "Which scope fits best?",
      options: [{ value: "small", label: "Small change" }],
    },
  ]);

  assert.equal(question.label, "Q1");
  assert.deepEqual(question.options[0], { value: "small", label: "Small change" });
  assert.deepEqual(question.options.at(-1), {
    value: SOMETHING_ELSE_VALUE,
    label: SOMETHING_ELSE_LABEL,
  });
});

test("normalizeQuestions keeps provided labels and descriptions intact before the synthetic option", () => {
  const [question] = normalizeQuestions([
    {
      id: "priority",
      label: "Priority",
      prompt: "Which priority?",
      options: [
        { value: "p0", label: "P0", description: "Need this now" },
        { value: "p1", label: "P1" },
      ],
    },
  ]);

  assert.equal(question.label, "Priority");
  assert.deepEqual(question.options.slice(0, 2), [
    { value: "p0", label: "P0", description: "Need this now" },
    { value: "p1", label: "P1" },
  ]);
  assert.equal(question.options[2].label, SOMETHING_ELSE_LABEL);
});

test("answer helpers preserve machine values and summary lines distinguish predefined vs custom answers", () => {
  const questions = normalizeQuestions([
    {
      id: "scope",
      label: "Scope",
      prompt: "Which scope fits best?",
      options: [{ value: "small", label: "Small change" }],
    },
    {
      id: "notes",
      label: "Notes",
      prompt: "Anything else?",
      options: [{ value: "none", label: "No extra notes" }],
    },
  ]);

  const predefined = createPredefinedAnswer("scope", questions[0].options[0], 1);
  const custom = createCustomAnswer("notes", "Needs to work with tmux");

  assert.deepEqual(predefined, {
    id: "scope",
    value: "small",
    label: "Small change",
    wasCustom: false,
    index: 1,
  });
  assert.deepEqual(custom, {
    id: "notes",
    value: "Needs to work with tmux",
    label: "Needs to work with tmux",
    wasCustom: true,
  });
  assert.deepEqual(summarizeAnswers(questions, [predefined, custom]), [
    "Scope: user selected: 1. Small change",
    "Notes: user wrote: Needs to work with tmux",
  ]);
});

test("createCancelledResult returns a structured cancelled payload", () => {
  const questions = normalizeQuestions([
    {
      id: "scope",
      prompt: "Which scope fits best?",
      options: [{ value: "small", label: "Small change" }],
    },
  ]);

  assert.deepEqual(createCancelledResult(questions), {
    questions,
    answers: [],
    cancelled: true,
  });
});

test("createAnsweredResult keeps answers in question order", () => {
  const questions = normalizeQuestions([
    {
      id: "scope",
      label: "Scope",
      prompt: "Which scope fits best?",
      options: [{ value: "small", label: "Small change" }],
    },
    {
      id: "notes",
      label: "Notes",
      prompt: "Anything else?",
      options: [{ value: "none", label: "No extra notes" }],
    },
  ]);

  const second = createCustomAnswer("notes", "Custom note");
  const first = createPredefinedAnswer("scope", questions[0].options[0], 1);
  const result = createAnsweredResult(questions, [second, first]);

  assert.equal(result.cancelled, false);
  assert.deepEqual(result.answers.map((answer) => answer.id), ["scope", "notes"]);
});

test("allQuestionsAnswered only returns true when every question has an answer", () => {
  const questions = normalizeQuestions([
    {
      id: "scope",
      prompt: "Scope?",
      options: [{ value: "small", label: "Small" }],
    },
    {
      id: "priority",
      prompt: "Priority?",
      options: [{ value: "p1", label: "P1" }],
    },
  ]);

  const answers = new Map([
    ["scope", createPredefinedAnswer("scope", questions[0].options[0], 1)],
  ]);

  assert.equal(allQuestionsAnswered(questions, answers), false);
  answers.set("priority", createCustomAnswer("priority", "Ship this week"));
  assert.equal(allQuestionsAnswered(questions, answers), true);
});

test("nextTabAfterAnswer advances through questions and then to the submit tab", () => {
  assert.equal(nextTabAfterAnswer(0, 3), 1);
  assert.equal(nextTabAfterAnswer(1, 3), 2);
  assert.equal(nextTabAfterAnswer(2, 3), 3);
});
