import type {
  CaptchaChallengeGenerator,
  CaptchaGeneratorContext,
  GeneratedCaptchaChallenge,
} from "../types.ts";
import { renderTextChallenge } from "./visual.ts";

const OPERATOR_WORDS: Record<string, string[]> = {
  "+": ["plus"],
  "-": ["minus"],
  "*": ["times"],
  "/": ["divided", "by"],
};

function numberTokens(value: number): string[] {
  const text = String(Math.abs(value));
  return value < 0 ? ["minus", ...text] : [...text];
}

export class CalculationCaptchaGenerator implements CaptchaChallengeGenerator {
  readonly type = "calculation" as const;

  generate(context: CaptchaGeneratorContext): GeneratedCaptchaChallenge {
    const max = context.difficulty === "easy" ? 9 : context.difficulty === "hard" ? 30 : 15;
    const operations = context.difficulty === "easy" ? ["+", "-"] : ["+", "-", "*", "/"];
    const operator = operations[context.randomInt(0, operations.length - 1)]!;
    let left = context.randomInt(2, max);
    let right = context.randomInt(1, max);
    let answer: number;

    if (operator === "+") answer = left + right;
    else if (operator === "-") {
      if (context.difficulty !== "hard" && right > left) [left, right] = [right, left];
      answer = left - right;
    } else if (operator === "*") {
      right = context.randomInt(2, context.difficulty === "hard" ? 12 : 9);
      left = context.randomInt(2, context.difficulty === "hard" ? 12 : 9);
      answer = left * right;
    } else {
      right = context.randomInt(2, context.difficulty === "hard" ? 12 : 9);
      answer = context.randomInt(2, context.difficulty === "hard" ? 12 : 9);
      left = right * answer;
    }

    const expression = `${left} ${operator} ${right} = ?`;
    return {
      type: "calculation",
      presentation: "visual",
      prompt: "Solve the calculation",
      answer: String(answer),
      answerKind: "text",
      image: renderTextChallenge(expression, context),
      inputMode: "numeric",
      audioSequence: [
        "what",
        "is",
        ...numberTokens(left),
        ...(OPERATOR_WORDS[operator] ?? []),
        ...numberTokens(right),
      ],
      metadata: { operator, imageStyle: context.imageStyle },
    };
  }
}

export const calculationCaptchaGenerator = new CalculationCaptchaGenerator();
