import type { MathProblem, Difficulty } from "../types";
import { randomInt } from "@/lib/utils";

let counter = 0;
function nextId() {
  return `ns-${++counter}-${Date.now()}`;
}

export function generateBinaryToDenary(difficulty: Difficulty): MathProblem {
  const bits = difficulty === 1 ? randomInt(3, 4) : difficulty === 2 ? randomInt(5, 6) : randomInt(7, 8);
  // ensure a leading 1 so the length is meaningful
  let binary = "1";
  for (let i = 1; i < bits; i++) binary += Math.random() < 0.5 ? "0" : "1";

  const len = binary.length;
  let value = 0;
  const parts: string[] = [];
  for (let i = 0; i < len; i++) {
    const exp = len - 1 - i;
    const digit = parseInt(binary[i], 10);
    const place = Math.pow(2, exp);
    if (digit === 1) parts.push(`${place}`);
    value += digit * place;
  }

  return {
    id: nextId(),
    prompt: `${binary}_{2} = ?_{10}`,
    answer: { kind: "integer", value },
    hints: [
      "Each column is a power of 2, doubling from the right: 1, 2, 4, 8, 16 …",
      "Add up the place values wherever there is a 1.",
      `${parts.join(" + ")} = ${value}`,
    ],
    steps: [
      { explanation: "Label each column with its power of 2, starting at 1 on the right." },
      { explanation: `Add the place values under each 1: ${parts.join(" + ")}` },
      { explanation: `${binary} in binary = ${value} in denary.` },
    ],
  };
}

export function generateQuaternaryToDenary(difficulty: Difficulty): MathProblem {
  const digits = difficulty === 1 ? randomInt(2, 3) : difficulty === 2 ? randomInt(3, 4) : randomInt(4, 5);
  let quaternary = `${randomInt(1, 3)}`; // leading non-zero digit
  for (let i = 1; i < digits; i++) quaternary += `${randomInt(0, 3)}`;

  const len = quaternary.length;
  let value = 0;
  const parts: string[] = [];
  for (let i = 0; i < len; i++) {
    const exp = len - 1 - i;
    const digit = parseInt(quaternary[i], 10);
    const place = Math.pow(4, exp);
    if (digit !== 0) parts.push(`${digit}×${place}`);
    value += digit * place;
  }

  return {
    id: nextId(),
    prompt: `${quaternary}_{4} = ?_{10}`,
    answer: { kind: "integer", value },
    hints: [
      "Each column is a power of 4, from the right: 1, 4, 16, 64 …",
      "Multiply each digit by its place value and add them up.",
      `${parts.join(" + ")} = ${value}`,
    ],
    steps: [
      { explanation: "Label each column with its power of 4, starting at 1 on the right." },
      { explanation: `Add the products: ${parts.join(" + ")}` },
      { explanation: `${quaternary} in base 4 = ${value} in denary.` },
    ],
  };
}

export function generateDigitValue(difficulty: Difficulty): MathProblem {
  const digits = difficulty === 1 ? randomInt(3, 4) : difficulty === 2 ? 5 : 6;
  const min = Math.pow(10, digits - 1);
  const max = Math.pow(10, digits) - 1;
  const n = randomInt(min, max);
  const str = `${n}`;

  // pick a non-zero digit position
  const nonZeroPositions = str.split("").map((d, i) => ({ d, i })).filter((x) => x.d !== "0");
  const pick = nonZeroPositions[randomInt(0, nonZeroPositions.length - 1)];
  const exp = str.length - 1 - pick.i;
  const place = Math.pow(10, exp);
  const value = parseInt(pick.d, 10) * place;

  return {
    id: nextId(),
    prompt: `\\text{In } ${n} \\text{, what is the value of the digit } ${pick.d}\\text{?}`,
    answer: { kind: "integer", value },
    hints: [
      "Find which column the digit sits in.",
      `That column is worth 10^${exp} = ${place}.`,
      `${pick.d} × ${place} = ${value}`,
    ],
    steps: [
      { explanation: `The digit ${pick.d} is in the 10^${exp} (${place}) column.` },
      { explanation: `Its value is ${pick.d} × ${place} = ${value}.` },
    ],
  };
}
