/**
 * src/http/hook.ts (H2) — map a Claude Code hook POST to a session status update.
 *
 * Pure + never throws. The web-terminal sessionId arrives in the
 * `X-Webterm-Session` header (injected as $WEBTERM_SESSION on spawn); the hook
 * payload arrives as JSON in the body. We translate the event into a coarse
 * ClaudeStatus the UI can show. The server is still a byte-shuttle for the
 * terminal stream — this is an out-of-band side-channel.
 */

import type { ClaudeStatus } from '../types.js';

export interface HookEvent {
  sessionId: string;
  status: ClaudeStatus;
  detail?: string;
}

/**
 * @param sessionId value of the `X-Webterm-Session` header
 * @param body parsed JSON body of the hook POST (untrusted)
 * @returns a status update, or null if the payload is unusable
 */
export function parseHookEvent(sessionId: string | undefined, body: unknown): HookEvent | null {
  if (typeof sessionId !== 'string' || sessionId.length === 0) return null;
  if (body === null || typeof body !== 'object') return null;

  const b = body as Record<string, unknown>;
  const event = typeof b['hook_event_name'] === 'string' ? b['hook_event_name'] : '';
  const notif = typeof b['notification_type'] === 'string' ? b['notification_type'] : '';
  const tool = typeof b['tool_name'] === 'string' ? b['tool_name'] : undefined;

  let status: ClaudeStatus;
  switch (event) {
    case 'PreToolUse':
    case 'PostToolUse':
    case 'UserPromptSubmit':
      status = 'working';
      break;
    case 'PermissionRequest':
      status = 'waiting';
      break;
    case 'Stop':
    case 'SessionEnd':
      status = 'idle';
      break;
    case 'Notification':
      status = notif === 'permission_prompt' ? 'waiting' : 'idle';
      break;
    default:
      return null;
  }

  return status === 'waiting' && tool !== undefined
    ? { sessionId, status, detail: tool }
    : { sessionId, status };
}
