/**
 * JSONL format types - raw data structures from Claude Code session files.
 *
 * These types represent the exact format stored in .jsonl files at:
 * ~/.claude/projects/{project_name}/{session_uuid}.jsonl
 *
 * Content type guards and entry type guards are included here as they
 * operate directly on the raw JSONL structures.
 */

// =============================================================================
// Core Type Aliases
// =============================================================================

type EntryType =
  | 'user'
  | 'assistant'
  | 'system'
  | 'summary'
  | 'file-history-snapshot'
  | 'queue-operation';

type ContentType = 'text' | 'thinking' | 'tool_use' | 'tool_result' | 'image';

type StopReason = 'end_turn' | 'tool_use' | 'max_tokens' | 'stop_sequence' | null;

// =============================================================================
// Content Blocks
// =============================================================================

interface BaseContent {
  type: ContentType;
}

export interface TextContent extends BaseContent {
  type: 'text';
  text: string;
}

export interface ThinkingContent extends BaseContent {
  type: 'thinking';
  thinking: string;
  signature: string;
}

export interface ToolUseContent extends BaseContent {
  type: 'tool_use';
  id: string;
  name: string;
  input: Record<string, unknown>;
}

export interface ToolResultContent extends BaseContent {
  type: 'tool_result';
  tool_use_id: string;
  content: string | ContentBlock[];
  is_error?: boolean;
}

export interface ImageContent extends BaseContent {
  type: 'image';
  source: {
    type: 'base64';
    media_type: 'image/png' | 'image/jpeg' | 'image/gif' | 'image/webp';
    data: string;
  };
}

export type ContentBlock =
  | TextContent
  | ThinkingContent
  | ToolUseContent
  | ToolResultContent
  | ImageContent;

// =============================================================================
// Usage Metadata
// =============================================================================

export interface UsageMetadata {
  input_tokens: number;
  output_tokens: number;
  cache_read_input_tokens?: number;
  cache_creation_input_tokens?: number;
}

// =============================================================================
// Messages
// =============================================================================

interface UserMessage {
  role: 'user';
  content: string | ContentBlock[];
}

interface AssistantMessage {
  role: 'assistant';
  model: string;
  id: string;
  type: 'message';
  content: ContentBlock[];
  stop_reason: StopReason;
  stop_sequence: string | null;
  usage: UsageMetadata;
}

// =============================================================================
// JSONL Entries
// =============================================================================

interface BaseEntry {
  type: EntryType;
  timestamp?: string;
  uuid?: string;
}

/**
 * Base for conversational entries (user, assistant, system).
 *
 * Sidechain behavior:
 * - isSidechain: false -> Main agent message
 * - isSidechain: true -> Subagent message
 * - sessionId: For subagents, points to parent session UUID
 */
interface ConversationalEntry extends BaseEntry {
  parentUuid: string | null;
  isSidechain: boolean;
  userType: 'external';
  cwd: string;
  sessionId: string;
  version: string;
  gitBranch: string;
  slug?: string;
}

/**
 * Tool use result data - preserves full structure from JSONL entries.
 *
 * The structure varies significantly by tool type:
 * - File tools: { type, success, filePath, content, structuredPatch, ... }
 * - Task tools: { status, prompt, agentId, content, totalDurationMs, totalTokens, usage, ... }
 * - AskUserQuestion: { questions, answers }
 * - Bash: { stdout, stderr, exitCode, ... }
 *
 * Using Record<string, unknown> to preserve all data without loss.
 */
export type ToolUseResultData = Record<string, unknown>;

/**
 * CRITICAL: User entries serve two purposes:
 *
 * 1. Real User Input (chunk starters):
 *    - isMeta: false or undefined
 *    - content: string
 *    - These START new chunks
 *
 * 2. Response Messages (part of response flow):
 *    a) Internal (tool results):
 *       - isMeta: true
 *       - content: array with tool_result blocks
 *    b) Interruptions:
 *       - isMeta: false
 *       - content: array (not string)
 */
export interface UserEntry extends ConversationalEntry {
  type: 'user';
  message: UserMessage;
  isMeta?: boolean;
  agentId?: string;

  toolUseResult?: ToolUseResultData;
  sourceToolUseID?: string;
  sourceToolAssistantUUID?: string;
}

export interface AssistantEntry extends ConversationalEntry {
  type: 'assistant';
  message: AssistantMessage;
  requestId: string;
  agentId?: string;
}

export interface SystemEntry extends ConversationalEntry {
  type: 'system';
  subtype: 'turn_duration' | 'init';
  durationMs: number;
  isMeta: boolean;
}

export interface SummaryEntry extends BaseEntry {
  type: 'summary';
  summary: string;
  leafUuid: string;
}

export interface FileHistorySnapshotEntry extends BaseEntry {
  type: 'file-history-snapshot';
  messageId: string;
  snapshot: {
    messageId: string;
    trackedFileBackups: Record<string, string>;
    timestamp: string;
  };
  isSnapshotUpdate: boolean;
}

export interface QueueOperationEntry extends BaseEntry {
  type: 'queue-operation';
  operation: string;
}

export type ChatHistoryEntry =
  | UserEntry
  | AssistantEntry
  | SystemEntry
  | SummaryEntry
  | FileHistorySnapshotEntry
  | QueueOperationEntry;

/**
 * Conversational entries - entries that represent chat messages.
 * These share common properties like message, cwd, gitBranch, etc.
 */
export type ConversationalChatEntry = UserEntry | AssistantEntry | SystemEntry;

// =============================================================================
// Content Type Guards
// =============================================================================

export function isTextContent(content: ContentBlock): content is TextContent {
  return content.type === 'text';
}

export function isToolResultContent(content: ContentBlock): content is ToolResultContent {
  return content.type === 'tool_result';
}

/**
 * Type guard to check if an entry is a conversational entry.
 */
export function isConversationalEntry(entry: ChatHistoryEntry): entry is ConversationalChatEntry {
  return entry.type === 'user' || entry.type === 'assistant' || entry.type === 'system';
}

// =============================================================================
// Subagent Directory Structures
// =============================================================================

/**
 * Claude Code supports two subagent directory structures:
 *
 * NEW STRUCTURE (Current):
 * ~/.claude/projects/
 *   {project_name}/
 *     {session_uuid}.jsonl              <- Main agent
 *     {session_uuid}/
 *       agent_{agent_uuid}.jsonl         <- Subagents
 *
 * OLD STRUCTURE (Legacy, still supported):
 * ~/.claude/projects/
 *   {project_name}/
 *     {session_uuid}.jsonl              <- Main agent
 *     agent_{agent_uuid}.jsonl           <- Subagents (at root)
 *
 * Identification:
 * - Main agent: isSidechain: false (or undefined)
 * - Subagent: isSidechain: true
 * - Linking: subagent.sessionId === parent session UUID
 *
 * When scanning for subagents:
 * 1. First check {session_uuid}/ subdirectory (new structure)
 * 2. Fall back to project root for agent_*.jsonl (old structure)
 * 3. Match by sessionId field to link to parent
 */

// =============================================================================
// Message Flow Pattern
// =============================================================================

/**
 * Typical conversation flow:
 *
 * 1. User types -> type: "user", isMeta: false, content: string -> TRIGGER MESSAGE (STARTS CHUNK)
 * 2. Assistant responds -> type: "assistant", may contain tool_use -> FLOW MESSAGE (PART OF RESPONSE)
 * 3. Tool executes -> type: "user", isMeta: true, contains tool_result -> FLOW MESSAGE (PART OF RESPONSE)
 * 4. User interrupts -> type: "user", isMeta: false, content: array -> FLOW MESSAGE (PART OF RESPONSE)
 * 5. Assistant continues -> type: "assistant" -> FLOW MESSAGE (PART OF RESPONSE)
 *
 * Message Categories (New 4-Category System):
 *
 * 1. USER MESSAGES (create UserChunks):
 *    - Genuine user input that initiates a new request/response cycle
 *    - Detected by: isParsedUserChunkMessage() type guard
 *    - Requirements: type='user', isMeta!=true, has text/image content
 *    - Excludes: <local-command-stdout>, <local-command-caveat>, <system-reminder>
 *    - Allows: <command-name> (slash commands like /model are visible user input)
 *
 * 2. SYSTEM MESSAGES (create SystemChunks):
 *    - Command output from slash commands
 *    - Detected by: isParsedSystemChunkMessage() type guard
 *    - Contains <local-command-stdout> tag
 *    - Renders on LEFT side like AI responses
 *
 * 3. HARD NOISE MESSAGES (filtered out):
 *    - System-generated metadata that should NEVER be displayed
 *    - Detected by: isParsedHardNoiseMessage() type guard
 *    - Includes: system/summary/file-history-snapshot/queue-operation entries
 *    - Includes: User messages with ONLY <local-command-caveat> or <system-reminder>
 *
 * 4. AI MESSAGES (create AIChunks):
 *    - All assistant messages and flow messages between User/System/HardNoise
 *    - Includes: assistant messages, tool results, interruptions
 *    - Consecutive AI messages are grouped into single AIChunk
 *    - AIChunks are INDEPENDENT - no longer paired with UserChunks
 *
 * Key Rules:
 * - User messages START UserChunks (render on RIGHT)
 * - System messages START SystemChunks (render on LEFT)
 * - AI messages are GROUPED into independent AIChunks (render on LEFT)
 * - Hard noise messages are FILTERED OUT entirely
 *
 * Tool Linking:
 * - tool_use.id in assistant message
 * - tool_result.tool_use_id in internal user message
 * - Also: sourceToolUseID field directly on internal user entry
 */
