import type { CmuxClient } from './cmux-client.js';

// Keys supported by cmux send-key socket API
const SEND_KEY_MAP: Record<string, string> = {
  Enter: 'enter',
  Escape: 'escape',
  Tab: 'tab',
  Backspace: 'backspace',
  ArrowUp: 'up',
  ArrowDown: 'down',
  ArrowLeft: 'left',
  ArrowRight: 'right',
  Home: 'home',
  End: 'end',
  Delete: 'delete',
  PageUp: 'pageup',
  PageDown: 'pagedown',
  ShiftTab: 'shift+tab',
};

export class InputHandler {
  private client: CmuxClient;

  constructor(client: CmuxClient) {
    this.client = client;
  }

  async handleText(workspace: string, surface: string, text: string): Promise<void> {
    await this.client.sendText(workspace, surface, text);
  }

  async handleKey(workspace: string, surface: string, key: string): Promise<void> {
    // Ctrl+key combos — send as control byte via send_text (0x01–0x1A)
    // cmux's send_key uses ghostty_surface_key with text:nil which may not deliver,
    // but send_text passes control bytes 0x01-0x1A directly to the PTY.
    const ctrlMatch = key.match(/^(?:Ctrl|Control)[+-](.+)$/i);
    if (ctrlMatch) {
      const inner = ctrlMatch[1].toLowerCase();
      if (inner.length === 1 && inner >= 'a' && inner <= 'z') {
        const ctrlByte = String.fromCharCode(inner.charCodeAt(0) - 0x60);
        await this.client.sendText(workspace, surface, ctrlByte);
        return;
      }
      // Non-letter ctrl combos: fall through to send_key
      await this.client.sendKey(workspace, surface, `ctrl+${inner}`);
      return;
    }

    // Alt+key combos — send as escape + char sequence
    const altMatch = key.match(/^Alt[+-](.+)$/i);
    if (altMatch) {
      await this.client.sendText(workspace, surface, `\x1b${altMatch[1].toLowerCase()}`);
      return;
    }

    // Shift+key combos
    const shiftMatch = key.match(/^Shift[+-](.+)$/i);
    if (shiftMatch) {
      const inner = shiftMatch[1];
      if (inner === 'Tab' || inner === 'tab') {
        await this.client.sendKey(workspace, surface, 'shift+tab');
        return;
      }
      return;
    }

    // Keys via send-key socket API
    const mapped = SEND_KEY_MAP[key];
    if (mapped) {
      await this.client.sendKey(workspace, surface, mapped);
      return;
    }

    // Fallback: send as text
    await this.client.sendText(workspace, surface, key);
  }
}
