/**
 * Fresh Editor TypeScript Plugin API
 *
 * This file provides type definitions for the Fresh editor's TypeScript plugin system.
 * Plugins have access to the global `editor` object which provides methods to:
 * - Query editor state (buffers, cursors, viewports)
 * - Modify buffer content (insert, delete text)
 * - Add visual decorations (overlays, highlighting)
 * - Interact with the editor UI (status messages, prompts)
 *
 * Note: types/fresh.d.ts is auto-generated from this template and src/ts_runtime.rs
 *
 * ## Core Concepts
 *
 * ### Buffers
 * A buffer holds text content and may or may not be associated with a file.
 * Each buffer has a unique numeric ID that persists for the editor session.
 * Buffers track their content, modification state, cursor positions, and path.
 * All text operations (insert, delete, read) use byte offsets, not character indices.
 *
 * ### Splits
 * A split is a viewport pane that displays a buffer. The editor can have multiple
 * splits arranged in a tree layout. Each split shows exactly one buffer, but the
 * same buffer can be displayed in multiple splits. Use split IDs to control which
 * pane displays which buffer.
 *
 * ### Virtual Buffers
 * Special buffers created by plugins to display structured data like search results,
 * diagnostics, or git logs. Virtual buffers support text properties (metadata attached
 * to text ranges) that plugins can query when the user selects a line. Unlike normal
 * buffers, virtual buffers are typically read-only and not backed by files.
 *
 * ### Text Properties
 * Metadata attached to text ranges in virtual buffers. Each entry has text content
 * and a properties object with arbitrary key-value pairs. Use `getTextPropertiesAtCursor`
 * to retrieve properties at the cursor position (e.g., to get file/line info for "go to").
 *
 * ### Overlays
 * Visual decorations applied to buffer text without modifying content. Overlays can
 * change text color and add underlines. Use overlay IDs to manage them; prefix IDs
 * enable batch removal (e.g., "lint:" prefix for all linter highlights).
 *
 * ### Modes
 * Keybinding contexts that determine how keypresses are interpreted. Each buffer has
 * a mode (e.g., "normal", "insert", "special"). Custom modes can inherit from parents
 * and define buffer-local keybindings. Virtual buffers typically use custom modes.
 */

/**
 * Get the editor API instance.
 * Plugins must call this at the top of their file to get a scoped editor object.
 * @returns The editor API object for this plugin
 * @example
 * const editor = getEditor();
 */
declare function getEditor(): EditorAPI;

/**
 * Plugin-specific methods added by the JavaScript runtime wrapper.
 * These extend the base EditorAPI with i18n and command registration helpers.
 */
interface EditorAPI {
  /**
   * Translate a string using the plugin's i18n file
   * @param key - Translation key (e.g., "status.ready")
   * @param args - Optional interpolation arguments
   * @returns Translated string
   */
  t(key: string, args?: Record<string, string>): string;

  /**
   * Get the i18n helper object (for compatibility)
   * @returns Object with t() method bound to this plugin
   */
  getL10n(): { t: (key: string, args?: Record<string, string>) => string };

  /**
   * Register a custom command (plugin wrapper - source is added automatically)
   * @param name - Command name (use %key for i18n)
   * @param description - Command description (use %key for i18n)
   * @param action - Global function name to call
   * @param contexts - Comma-separated contexts (default: "")
   * @returns true if command was registered
   */
  registerCommand(name: string, description: string, action: string, contexts?: string): boolean;

  /**
   * Copy text to system clipboard (alias for setClipboard)
   * @param text - Text to copy
   */
  copyToClipboard(text: string): void;

  /**
   * Join path segments into a single path (variadic version)
   * @param parts - Path segments to join
   * @returns Joined path string
   */
  pathJoin(...parts: string[]): string;

  /**
   * Add a visual overlay to buffer text (with optional parameters)
   * Most parameters have defaults: bold=false, italic=false, bg=-1 (transparent), extend=false
   */
  addOverlay(
    buffer_id: number,
    namespace: string,
    start: number,
    end: number,
    r: number,
    g: number,
    b: number,
    underline: boolean,
    bold?: boolean,
    italic?: boolean,
    bg_r?: number,
    bg_g?: number,
    bg_b?: number,
    extend_to_line_end?: boolean
  ): boolean;

  /**
   * Get the theme JSON Schema (with proper typing)
   */
  getThemeSchema(): {
    $defs?: Record<string, Record<string, unknown>>;
    properties?: Record<string, unknown>;
  };

  /**
   * Get built-in themes as a map of name to JSON string
   */
  getBuiltinThemes(): Record<string, string>;
}

/**
 * Buffer identifier (unique numeric ID)
 */
type BufferId = number;

/** View token wire format for view transforms */
interface ViewTokenWire {
  /** Source byte offset (null for injected view-only content) */
  source_offset: number | null;
  /** Token kind: Text, Newline, Space, or Break */
  kind: ViewTokenWireKind;
}

/** View token kind discriminated union */
type ViewTokenWireKind =
  | { Text: string }
  | "Newline"
  | "Space"
  | "Break";

/** Layout hints for compose mode */
interface LayoutHints {
  /** Optional compose width for centering/wrapping */
  compose_width?: number | null;
  /** Optional column guides for tables */
  column_guides?: number[] | null;
}

/** Handle for a cancellable process spawned with spawnProcess */
interface ProcessHandle extends PromiseLike<SpawnResult> {
  /** Promise that resolves to the process ID */
  readonly processId: Promise<number>;
  /** Promise that resolves to the result when the process completes */
  readonly result: Promise<SpawnResult>;
  /** Kill the process. Returns true if killed, false if already completed */
  kill(): Promise<boolean>;
}

/** Entry for virtual buffer content with optional text properties */
interface TextPropertyEntry {
  /** Text content for this entry */
  text: string;
  /** Optional properties attached to this text (e.g., file path, line number) */
  properties?: Record<string, unknown>;
}

/** Options for createVirtualBuffer */
interface CreateVirtualBufferOptions {
  /** Buffer name (displayed in tabs/title) */
  name: string;
  /** Mode for keybindings (e.g., "git-log", "search-results") */
  mode?: string;
  /** Whether buffer is read-only (default: false) */
  readOnly?: boolean;
  /** Show line numbers in gutter (default: false) */
  showLineNumbers?: boolean;
  /** Show cursor (default: true) */
  showCursors?: boolean;
  /** Disable text editing (default: false) */
  editingDisabled?: boolean;
  /** Hide from tab bar (default: false) */
  hiddenFromTabs?: boolean;
  /** Initial content entries with optional properties */
  entries?: TextPropertyEntry[];
}

/** Options for createVirtualBufferInSplit */
interface CreateVirtualBufferInSplitOptions {
  /** Buffer name (displayed in tabs/title) */
  name: string;
  /** Mode for keybindings (e.g., "git-log", "search-results") */
  mode?: string;
  /** Whether buffer is read-only (default: false) */
  readOnly?: boolean;
  /** Split ratio 0.0-1.0 (default: 0.5) */
  ratio?: number;
  /** Split direction: "horizontal" or "vertical" */
  direction?: string;
  /** Panel ID to split from */
  panelId?: string;
  /** Show line numbers in gutter (default: true) */
  showLineNumbers?: boolean;
  /** Show cursor (default: true) */
  showCursors?: boolean;
  /** Disable text editing (default: false) */
  editingDisabled?: boolean;
  /** Enable line wrapping */
  lineWrap?: boolean;
  /** Initial content entries with optional properties */
  entries?: TextPropertyEntry[];
}

/** Options for createVirtualBufferInExistingSplit */
interface CreateVirtualBufferInExistingSplitOptions {
  /** Buffer name (displayed in tabs/title) */
  name: string;
  /** Target split ID (required) */
  splitId: number;
  /** Mode for keybindings (e.g., "git-log", "search-results") */
  mode?: string;
  /** Whether buffer is read-only (default: false) */
  readOnly?: boolean;
  /** Show line numbers in gutter (default: true) */
  showLineNumbers?: boolean;
  /** Show cursor (default: true) */
  showCursors?: boolean;
  /** Disable text editing (default: false) */
  editingDisabled?: boolean;
  /** Enable line wrapping */
  lineWrap?: boolean;
  /** Initial content entries with optional properties */
  entries?: TextPropertyEntry[];
}

