/**
 * Domain/business entity types for Hermit.
 *
 * These types represent the application's domain model:
 * - Projects and sessions
 * - Repository and worktree grouping
 * - Search and pagination
 * - Token usage and metrics
 */

import { type UsageMetadata } from './jsonl';

// =============================================================================
// Application-Specific Type Aliases
// =============================================================================

/**
 * Token usage statistics (alias for API compatibility).
 * Maps to UsageMetadata from the spec.
 */
export type TokenUsage = UsageMetadata;

/**
 * Message type classification for parsed messages.
 */
export type MessageType =
  | 'user'
  | 'assistant'
  | 'system'
  | 'summary'
  | 'file-history-snapshot'
  | 'queue-operation';

/**
 * Message category for chunk building.
 * Used to classify messages into one of four categories for independent chunk creation.
 */
export type MessageCategory = 'user' | 'system' | 'hardNoise' | 'ai' | 'compact';

// =============================================================================
// Project & Session Types
// =============================================================================

/**
 * Project information derived from ~/.claude/projects/ directory.
 */
export interface Project {
  /** Encoded directory name (e.g., "-Users-username-projectname") */
  id: string;
  /** Decoded actual filesystem path */
  path: string;
  /** Display name (last path segment) */
  name: string;
  /**
   * List of session IDs (JSONL filenames without extension).
   * Note: this list may be truncated for performance; use totalSessions for counts.
   */
  sessions: string[];
  /** Total session count (may exceed sessions.length if sessions list is truncated) */
  totalSessions?: number;
  /** Unix timestamp when project directory was created */
  createdAt: number;
  /** Unix timestamp of most recent session activity */
  mostRecentSession?: number;
}

/**
 * Session metadata and summary.
 */
export type SessionMetadataLevel = 'light' | 'deep';

/**
 * Per-phase token breakdown for compaction-aware context consumption.
 */
export interface PhaseTokenBreakdown {
  /** 1-based phase number */
  phaseNumber: number;
  /** Tokens added during this phase */
  contribution: number;
  /** Context window at peak (pre-compaction or final) */
  peakTokens: number;
  /** Tokens after compaction (undefined for the last/current phase) */
  postCompaction?: number;
}

export interface Session {
  /** Session UUID (JSONL filename without extension) */
  id: string;
  /** Parent project ID */
  projectId: string;
  /** Project filesystem path */
  projectPath: string;
  /** Task list data from ~/.claude/todos/{id}.json if exists */
  todoData?: unknown;
  /** Unix timestamp when session file was created */
  createdAt: number;
  /** First user message text (for preview) */
  firstMessage?: string;
  /** Timestamp of first user message (RFC3339) */
  messageTimestamp?: string;
  /** Whether this session has subagents */
  hasSubagents: boolean;
  /** Total message count in the session */
  messageCount: number;
  /** Whether the session is ongoing (last AI response has no output yet) */
  isOngoing?: boolean;
  /** Latest main-thread model seen in the session metadata scan */
  model?: string;
  /** Git branch name if available */
  gitBranch?: string;
  /** Metadata completeness level */
  metadataLevel?: SessionMetadataLevel;
  /** Total context consumed (compaction-aware sum of all phases) */
  contextConsumption?: number;
  /** Number of compaction events */
  compactionCount?: number;
  /** Per-phase token breakdown for tooltip display */
  phaseBreakdown?: PhaseTokenBreakdown[];
}

/**
 * Aggregated metrics for a session or chunk.
 */
export interface SessionMetrics {
  /** Duration in milliseconds */
  durationMs: number;
  /** Total tokens (input + output) */
  totalTokens: number;
  /** Input tokens */
  inputTokens: number;
  /** Output tokens */
  outputTokens: number;
  /** Cache read tokens */
  cacheReadTokens: number;
  /** Cache creation tokens */
  cacheCreationTokens: number;
  /** Number of messages */
  messageCount: number;
  /** Estimated cost in USD */
  costUsd?: number;
}

// =============================================================================
// Repository & Worktree Grouping Types
// =============================================================================

/**
 * Worktree source identifies how/where the worktree was created.
 * Used for badge display and source-specific naming strategies.
 */
export type WorktreeSource =
  | 'vibe-kanban' // /tmp/vibe-kanban/worktrees/{issue-branch}/{repo}
  | 'conductor' // /Users/.../conductor/workspaces/{repo}/{workspace}
  | 'auto-claude' // /Users/.../.auto-claude/worktrees/tasks/{task-id}
  | '21st' // /Users/.../.21st/worktrees/{id}/{name [bracket-id]}
  | 'claude-desktop' // /Users/.../.claude-worktrees/{repo}/{name}
  | 'claude-code' // /Users/.../.claude/worktrees/{name}
  | 'ccswitch' // /Users/.../.ccswitch/worktrees/{repo}/{name}
  | 'git' // Standard git worktree (main repo or detached)
  | 'unknown'; // Non-git project or undetectable

/**
 * Git repository identity for grouping worktrees.
 * Multiple projects (worktrees) can share the same RepositoryIdentity.
 */
export interface RepositoryIdentity {
  /** Unique identifier - hash of remote URL or main repo path */
  id: string;
  /** Git remote URL if available (e.g., "https://github.com/org/repo.git") */
  remoteUrl?: string;
  /** Path to the main git directory (e.g., "/Users/username/projectname/.git") */
  mainGitDir: string;
  /** Display name for the repository (e.g., "projectname") */
  name: string;
}

/**
 * A worktree represents a single working directory of a git repository.
 * In the grouped view, projects become worktrees under a RepositoryGroup.
 */
export interface Worktree {
  /** Encoded directory name (same as Project.id) */
  id: string;
  /** Decoded actual filesystem path */
  path: string;
  /** Display name (worktree-specific, e.g., branch name or "main") */
  name: string;
  /** Git branch name if available */
  gitBranch?: string;
  /** Whether this is the main worktree (not a detached worktree) */
  isMainWorktree: boolean;
  /** Worktree source for badge display (vibe-kanban, conductor, etc.) */
  source: WorktreeSource;
  /**
   * List of session IDs.
   * Note: this list may be truncated for performance; use totalSessions for counts.
   */
  sessions: string[];
  /** Total session count (may exceed sessions.length if sessions list is truncated) */
  totalSessions?: number;
  /** Unix timestamp when first session was created */
  createdAt: number;
  /** Unix timestamp of most recent session activity */
  mostRecentSession?: number;
}

/**
 * A repository group contains all worktrees of a single git repository.
 * This is the top-level entity when worktree grouping is enabled.
 * Non-git projects are represented as single-worktree RepositoryGroups.
 */
export interface RepositoryGroup {
  /** Unique identifier from RepositoryIdentity.id (or project.id for non-git) */
  id: string;
  /** Repository identity information (null for non-git projects) */
  identity: RepositoryIdentity | null;
  /** All worktrees of this repository */
  worktrees: Worktree[];
  /** Display name (derived from repo name) */
  name: string;
  /** Unix timestamp of most recent session across all worktrees */
  mostRecentSession?: number;
  /** Total session count across all worktrees */
  totalSessions: number;
}

// =============================================================================
// Search Types
// =============================================================================

/**
 * A single search result from searching sessions.
 */
export interface SearchResult {
  /** Session ID where match was found */
  sessionId: string;
  /** Project ID */
  projectId: string;
  /** Session title/first message */
  sessionTitle: string;
  /** The matched text (trimmed) */
  matchedText: string;
  /** Context around the match */
  context: string;
  /** Message type (user/assistant) */
  messageType: 'user' | 'assistant';
  /** Timestamp of the message */
  timestamp: number;
  /** Stable chat group ID used by in-session navigation (e.g., "user-..." or "ai-...") */
  groupId?: string;
  /** Searchable item type used for in-session matching */
  itemType?: 'user' | 'ai';
  /** Match index within the item's searchable text (0-based) */
  matchIndexInItem?: number;
  /** Character offset of the match within the searchable text */
  matchStartOffset?: number;
  /** Source message UUID for diagnostics/fallback mapping */
  messageUuid?: string;
}

/**
 * Result of a search operation.
 */
export interface SearchSessionsResult {
  /** Search results */
  results: SearchResult[];
  /** Total matches found */
  totalMatches: number;
  /** Sessions searched */
  sessionsSearched: number;
  /** Search query used */
  query: string;
  /** True when fast mode intentionally returns only a recent subset */
  isPartial?: boolean;
}

// =============================================================================
// Pagination Types
// =============================================================================

/**
 * Cursor for session pagination.
 * Uses timestamp + sessionId as a composite cursor for stable pagination.
 */
export interface SessionCursor {
  /** Unix timestamp (birthtimeMs) of the session file */
  timestamp: number;
  /** Session ID for tie-breaking when timestamps are equal */
  sessionId: string;
}

/**
 * Result of paginated session listing.
 */
export interface PaginatedSessionsResult {
  /** Sessions for this page */
  sessions: Session[];
  /** Cursor for next page (null if no more pages) */
  nextCursor: string | null;
  /** Whether there are more sessions to load */
  hasMore: boolean;
  /** Total count of sessions (for display purposes) */
  totalCount: number;
}

/**
 * Options controlling paginated session listing behavior.
 */
export interface SessionsPaginationOptions {
  /**
   * Whether to compute an accurate totalCount by scanning all sessions.
   * Disable for faster background refreshes.
   * @default true
   */
  includeTotalCount?: boolean;
  /**
   * Whether to pre-filter all session files before paging.
   * Disable for faster top-of-list refreshes.
   * @default true
   */
  prefilterAll?: boolean;
  /**
   * Metadata depth to return for listed sessions.
   * - light: filesystem metadata only (fast)
   * - deep: includes parsed session content summary fields (slower)
   * @default 'deep'
   */
  metadataLevel?: SessionMetadataLevel;
}

/**
 * Options for targeted session fetches by session ID.
 */
export interface SessionsByIdsOptions {
  /**
   * Metadata depth to return for each session.
   * - light: fast preview fields suitable for list/sidebar
   * - deep: full summary metadata (slower)
   * @default provider-specific default (SSH=light, local=deep)
   */
  metadataLevel?: SessionMetadataLevel;
}
