import type { ToolInput } from "../../core/io/input-types";
import type { ToolResult } from "../../core/io/output-types";
import type { ToolContext } from "../../core/plugins/plugin-types";
import type { NumberBaseOptions } from "./index";

function formatNumber(value: bigint, base: number): string {
  if (base === 2) return "0b" + value.toString(2);
  if (base === 8) return "0o" + value.toString(8);
  if (base === 10) return value.toString(10);
  if (base === 16) return "0x" + value.toString(16).toUpperCase();
  return value.toString(base);
}

export async function runNumberBase(
  input: ToolInput,
  options: NumberBaseOptions,
  context?: ToolContext
): Promise<ToolResult> {
  void context;

  const text = (input.text || "").trim();
  if (!text) {
    throw new Error("No number provided.");
  }

  const fromBase = parseInt(options.fromBase, 10);
  const toBase = parseInt(options.toBase, 10);

  const cleaned = text.replace(/^0[box]/i, "");

  let value: bigint;
  try {
    value = BigInt(parseInt(cleaned, fromBase));
  } catch {
    throw new Error(`Invalid number "${text}" for base ${fromBase}.`);
  }

  if (isNaN(Number(value))) {
    throw new Error(`Invalid number "${text}" for base ${fromBase}.`);
  }

  return {
    type: "json",
    value: {
      input: text,
      binary: formatNumber(value, 2),
      octal: formatNumber(value, 8),
      decimal: formatNumber(value, 10),
      hexadecimal: formatNumber(value, 16),
      primary: formatNumber(value, toBase),
    },
  };
}
