import { unwrapJsonPayload } from '../../shared/utils/json.util';
import {
  parseKeyboardHighlightKeyIds,
  parseKeyboardVirtualKey,
  parseKeyboardVkScheme,
} from './keyboard-payload.util';
import { svgKeyboardKeyIdToUsUnshiftedChar, vkToKeyboardSvgKeyId } from './vk-to-keyboard-svg-id';

const MODIFIER_SVG_IDS = new Set<string>([
  'K_kb5a',
  'K_kb5m',
  'K_kb6a',
  'K_kb6n',
  'K_kb6c',
  'K_kb6k',
  'K_kb6b',
  'K_kb6l',
  'K_kb4a',
  'K_kb6m',
]);

function sliceLastCodepoint(s: string): string {
  if (!s) {
    return s;
  }
  const chars = [...s];
  chars.pop();
  return chars.join('');
}

/**
 * Явный символ из payload агента (если есть).
 */
function parseExplicitTranscriptChar(data: unknown): string | null {
  const raw = unwrapJsonPayload(data);
  if (raw == null || typeof raw !== 'object' || Array.isArray(raw)) {
    return null;
  }
  const o = raw as Record<string, unknown>;
  const keys = ['char', 'character', 'unicode_char', 'UnicodeChar', 'key_char'] as const;
  for (const k of keys) {
    const v = o[k];
    if (typeof v === 'string' && v.length === 1) {
      return v;
    }
  }
  const text = o['text'];
  if (typeof text === 'string' && text.length === 1) {
    return text;
  }
  return null;
}

function isNonPrintingKeyId(id: string): boolean {
  return MODIFIER_SVG_IDS.has(id) || id.startsWith('K_kb7');
}

function applyKeyIdToBuffer(buffer: string, id: string, data: unknown): string {
  if (isNonPrintingKeyId(id)) {
    return buffer;
  }
  if (id === 'K_kb2n') {
    return sliceLastCodepoint(buffer);
  }
  const fromId = svgKeyboardKeyIdToUsUnshiftedChar(id);
  if (fromId) {
    return buffer + fromId;
  }
  const raw = unwrapJsonPayload(data);
  const vk = parseKeyboardVirtualKey(raw);
  const scheme = parseKeyboardVkScheme(raw);
  if (vk != null) {
    const idVk = vkToKeyboardSvgKeyId(vk, scheme);
    if (idVk === 'K_kb2n') {
      return sliceLastCodepoint(buffer);
    }
    if (idVk && !isNonPrintingKeyId(idVk)) {
      const ch = svgKeyboardKeyIdToUsUnshiftedChar(idVk);
      if (ch) {
        return buffer + ch;
      }
    }
  }
  return buffer;
}

/**
 * Одно событие нажатия → обновление буфера «набранного текста».
 * Учитывает Tab (`\t`), Enter (`\n`), пробел, Backspace; буквы/цифры — US QWERTY без Shift
 * или явный символ из payload.
 */
export function applyKeyboardPressToTranscriptBuffer(buffer: string, data: unknown): string {
  const explicit = parseExplicitTranscriptChar(data);
  if (explicit !== null) {
    return buffer + explicit;
  }
  const ids = parseKeyboardHighlightKeyIds(data);
  const nonMod = ids.filter((id) => !isNonPrintingKeyId(id));
  if (nonMod.length === 0) {
    return buffer;
  }
  if (nonMod.length === 1) {
    return applyKeyIdToBuffer(buffer, nonMod[0]!, data);
  }
  const raw = unwrapJsonPayload(data);
  const vk = parseKeyboardVirtualKey(raw);
  const scheme = parseKeyboardVkScheme(raw);
  if (vk != null) {
    const idVk = vkToKeyboardSvgKeyId(vk, scheme);
    if (idVk && !isNonPrintingKeyId(idVk)) {
      return applyKeyIdToBuffer(buffer, idVk, data);
    }
  }
  return buffer;
}
