/**
 * eval-transcript.js - Stream-json parsing and transcript action extraction
 *
 * Self-contained leaf: pure functions that parse Claude stream-json output into
 * text/rich transcripts and structured Action objects. No dependencies beyond
 * each other.
 *
 * Dependency direction is one-way: eval.js imports and re-exports the public
 * functions here; this module never imports from ./eval.
 *
 * Zero external dependencies — Node.js standard library only.
 */

/**
 * Parse stream-json output from `claude -p --output-format stream-json --verbose`.
 * Extracts assistant messages with tool calls to build a rich transcript
 * showing the full conversation flow (text + tool use in order).
 * Also extracts usage metrics (tokens, duration) from the terminal result event.
 * @param {string} rawOutput - Raw JSONL output from stream-json
 * @returns {{ textResult: string, richTranscript: string, usage: { input_tokens: number|null, output_tokens: number|null, duration_ms: number|null } }}
 */
function parseStreamJsonOutput(rawOutput) {
  if (!rawOutput)
    return {
      textResult: '',
      richTranscript: '',
      usage: { input_tokens: null, output_tokens: null, duration_ms: null },
    };

  const lines = rawOutput.split('\n').filter((l) => l.trim());
  const parts = [];
  let textResult = '';
  const usage = { input_tokens: null, output_tokens: null, duration_ms: null };

  for (const line of lines) {
    let event;
    try {
      event = JSON.parse(line);
    } catch {
      continue;
    }

    if (event.type === 'assistant' && event.message?.content) {
      for (const block of event.message.content) {
        if (block.type === 'text' && block.text) {
          parts.push(`[Assistant] ${block.text}`);
        } else if (block.type === 'tool_use') {
          const inputSummary = summarizeToolInput(block.name, block.input);
          parts.push(`[Tool: ${block.name}] ${inputSummary}`);
        }
      }
    } else if (event.type === 'result') {
      textResult = event.result || '';
      if (event.usage && typeof event.usage === 'object') {
        usage.input_tokens = event.usage.input_tokens ?? null;
        usage.output_tokens = event.usage.output_tokens ?? null;
      }
      usage.duration_ms = event.duration_ms ?? null;
    }
  }

  return { textResult, richTranscript: parts.join('\n\n'), usage };
}

/**
 * Parse a rich transcript into structured Action objects.
 * Rich transcripts are produced by parseStreamJsonOutput() and contain
 * blocks like "[Tool: Bash] $ ls" and "[Assistant] some text" separated
 * by double newlines.
 *
 * NOTE: This parses markers generated by parseStreamJsonOutput(), not raw
 * assistant text. The [Tool: ...] markers come from tool_use blocks in the
 * stream-json output, so false positives from assistant prose are unlikely.
 * A future improvement could extract actions directly from JSON events.
 *
 * @param {string} richTranscript - Rich transcript text
 * @returns {Array<{type: string, name?: string, args?: string, content?: string, index: number}>}
 */
function parseActionsFromTranscript(richTranscript) {
  if (!richTranscript) return [];
  const blocks = richTranscript.split('\n\n').filter((b) => b.trim());
  const actions = [];
  for (const block of blocks) {
    const toolMatch = block.match(/^\[Tool: ([^\]]+)\]\s*(.*)/);
    if (toolMatch) {
      const firstLine = toolMatch[2].split('\n')[0];
      actions.push({ type: 'tool', name: toolMatch[1], args: firstLine, index: actions.length });
      continue;
    }
    const textMatch = block.match(/^\[Assistant\]\s*([\s\S]*)/);
    if (textMatch) {
      actions.push({ type: 'text', content: textMatch[1].trim(), index: actions.length });
    }
  }
  return actions;
}

/**
 * Summarize tool input for transcript readability.
 * Shows key details without overwhelming the transcript.
 * @param {string} toolName - Tool name (Write, Edit, Bash, etc.)
 * @param {Object} input - Tool input parameters
 * @returns {string} Human-readable summary
 */
function summarizeToolInput(toolName, input) {
  if (!input) return '';
  switch (toolName) {
    case 'Write': {
      const content = input.content || '';
      return `${input.file_path || ''}\n\`\`\`\n${content}\n\`\`\``;
    }
    case 'Edit': {
      const old = input.old_string || '';
      const rep = input.new_string || '';
      const maxLen = 300;
      return `${input.file_path || ''} (replace "${old.slice(0, maxLen)}${old.length > maxLen ? '...' : ''}" → "${rep.slice(0, maxLen)}${rep.length > maxLen ? '...' : ''}")`;
    }
    case 'Read':
      return input.file_path || '';
    case 'Bash':
      return `$ ${input.command || ''}`;
    case 'Glob':
      return `pattern: ${input.pattern || ''}`;
    case 'Grep':
      return `pattern: ${input.pattern || ''} ${input.path ? `in ${input.path}` : ''}`;
    default:
      return JSON.stringify(input).slice(0, 200);
  }
}

module.exports = {
  parseStreamJsonOutput,
  parseActionsFromTranscript,
};
