

export type SpecialKey =
  | "escape"
  | "tab"
  | "ctrl"
  | "alt"
  | "up"
  | "down"
  | "left"
  | "right"
  | "home"
  | "end"
  | "pageup"
  | "pagedown"
  | "ctrlc"
  | "ctrld"
  | "ctrlz"
  | "f1"
  | "f2"
  | "f3"
  | "f4"
  | "f5"
  | "f6"
  | "f7"
  | "f8"
  | "f9"
  | "f10"
  | "f11"
  | "f12";

export type ModifierKey = "ctrl" | "alt";

const KEY_SEQUENCES: Record<SpecialKey, string> = {
  escape: "\x1B",
  tab: "\t",
  ctrl: "",
  alt: "",
  up: "\x1B[A",
  down: "\x1B[B",
  right: "\x1B[C",
  left: "\x1B[D",
  home: "\x1B[H",
  end: "\x1B[F",
  pageup: "\x1B[5~",
  pagedown: "\x1B[6~",
  ctrlc: "\x03",
  ctrld: "\x04",
  ctrlz: "\x1A",
  f1: "\x1BOP",
  f2: "\x1BOQ",
  f3: "\x1BOR",
  f4: "\x1BOS",
  f5: "\x1B[15~",
  f6: "\x1B[17~",
  f7: "\x1B[18~",
  f8: "\x1B[19~",
  f9: "\x1B[20~",
  f10: "\x1B[21~",
  f11: "\x1B[23~",
  f12: "\x1B[24~",
};

// Single character sequences with modifier prefixes
const MODIFIER_PREFIXES: Record<string, { ctrl: string; alt: string; ctrlAlt: string }> = {
  // Letters
  a: { ctrl: "\x01", alt: "\x1Ba", ctrlAlt: "\x1B\x01" },
  b: { ctrl: "\x02", alt: "\x1Bb", ctrlAlt: "\x1B\x02" },
  c: { ctrl: "\x03", alt: "\x1Bc", ctrlAlt: "\x1B\x03" },
  d: { ctrl: "\x04", alt: "\x1Bd", ctrlAlt: "\x1B\x04" },
  e: { ctrl: "\x05", alt: "\x1Be", ctrlAlt: "\x1B\x05" },
  f: { ctrl: "\x06", alt: "\x1Bf", ctrlAlt: "\x1B\x06" },
  g: { ctrl: "\x07", alt: "\x1Bg", ctrlAlt: "\x1B\x07" },
  h: { ctrl: "\x08", alt: "\x1Bh", ctrlAlt: "\x1B\x08" },
  i: { ctrl: "\x09", alt: "\x1Bi", ctrlAlt: "\x1B\x09" },
  j: { ctrl: "\x0A", alt: "\x1Bj", ctrlAlt: "\x1B\x0A" },
  k: { ctrl: "\x0B", alt: "\x1Bk", ctrlAlt: "\x1B\x0B" },
  l: { ctrl: "\x0C", alt: "\x1Bl", ctrlAlt: "\x1B\x0C" },
  m: { ctrl: "\x0D", alt: "\x1Bm", ctrlAlt: "\x1B\x0D" },
  n: { ctrl: "\x0E", alt: "\x1Bn", ctrlAlt: "\x1B\x0E" },
  o: { ctrl: "\x0F", alt: "\x1Bo", ctrlAlt: "\x1B\x0F" },
  p: { ctrl: "\x10", alt: "\x1Bp", ctrlAlt: "\x1B\x10" },
  q: { ctrl: "\x11", alt: "\x1Bq", ctrlAlt: "\x1B\x11" },
  r: { ctrl: "\x12", alt: "\x1Br", ctrlAlt: "\x1B\x12" },
  s: { ctrl: "\x13", alt: "\x1Bs", ctrlAlt: "\x1B\x13" },
  t: { ctrl: "\x14", alt: "\x1Bt", ctrlAlt: "\x1B\x14" },
  u: { ctrl: "\x15", alt: "\x1Bu", ctrlAlt: "\x1B\x15" },
  v: { ctrl: "\x16", alt: "\x1Bv", ctrlAlt: "\x1B\x16" },
  w: { ctrl: "\x17", alt: "\x1Bw", ctrlAlt: "\x1B\x17" },
  x: { ctrl: "\x18", alt: "\x1Bx", ctrlAlt: "\x1B\x18" },
  y: { ctrl: "\x19", alt: "\x1By", ctrlAlt: "\x1B\x19" },
  z: { ctrl: "\x1A", alt: "\x1Bz", ctrlAlt: "\x1B\x1A" },
  // Numbers
  "0": { ctrl: "0", alt: "\x1B0", ctrlAlt: "\x1B0" },
  "1": { ctrl: "1", alt: "\x1B1", ctrlAlt: "\x1B1" },
  "2": { ctrl: "\x00", alt: "\x1B2", ctrlAlt: "\x1B\x00" },
  "3": { ctrl: "\x1B", alt: "\x1B3", ctrlAlt: "\x1B\x1B" },
  "4": { ctrl: "\x1C", alt: "\x1B4", ctrlAlt: "\x1B\x1C" },
  "5": { ctrl: "\x1D", alt: "\x1B5", ctrlAlt: "\x1B\x1D" },
  "6": { ctrl: "\x1E", alt: "\x1B6", ctrlAlt: "\x1B\x1E" },
  "7": { ctrl: "\x1F", alt: "\x1B7", ctrlAlt: "\x1B\x1F" },
  "8": { ctrl: "\x7F", alt: "\x1B8", ctrlAlt: "\x1B\x7F" },
  "9": { ctrl: "9", alt: "\x1B9", ctrlAlt: "\x1B9" },
};

export function getSequenceWithModifier(
  key: SpecialKey,
  activeModifier: ModifierKey | null
): { sequence: string; clearModifier: boolean } | null {
  // Handle modifier keys (one-shot)
  if (key === "ctrl" || key === "alt") {
    return null; // Modifiers don't send anything themselves
  }

  const sequence = KEY_SEQUENCES[key];
  if (!sequence) return null;

  // Check if we have an active modifier and the key is a single character
  if (activeModifier && sequence.length === 1) {
    const char = sequence;
    const mapping = MODIFIER_PREFIXES[char.toLowerCase()];
    if (mapping) {
      return { sequence: mapping[activeModifier], clearModifier: true };
    }
  }

  return { sequence, clearModifier: !!activeModifier };
}

export function applyModifierToChar(
  char: string,
  modifier: ModifierKey
): string | null {
  if (char.length !== 1) return null;
  const mapping = MODIFIER_PREFIXES[char.toLowerCase()];
  if (!mapping) return null;
  return mapping[modifier];
}

export { KEY_SEQUENCES };
