/**
 * Window and application domain type definitions
 */

import type { HistoryItem, DraftData } from './history';
import type { DirectoryInfo } from './file-search';

/**
 * Color value type supporting both named colors and hex color codes
 * Named colors: 'grey', 'darkGrey', 'slate', 'stone', 'red', 'rose', 'orange', 'amber', 'yellow', 'lime', 'green', 'emerald', 'teal', 'cyan', 'sky', 'blue', 'indigo', 'violet', 'purple', 'fuchsia', 'pink'
 * Hex codes: '#RGB' or '#RRGGBB' (e.g., '#0066CC', '#F5A')
 */
export type ColorValue = 'grey' | 'darkGrey' | 'slate' | 'stone' | 'red' | 'rose' | 'orange' | 'amber' | 'yellow' | 'lime' | 'green' | 'emerald' | 'teal' | 'cyan' | 'sky' | 'blue' | 'indigo' | 'violet' | 'purple' | 'fuchsia' | 'pink' | string;

/**
 * Plugin format: v1 (string[]) or v2 (Record<string, string[]>)
 */
export type PluginFormat = string[] | Record<string, string[]>;

/**
 * Parsed plugin entry with optional overrides from @suffix?params syntax
 * e.g., "claude/custom-search/agents@agent?open=iTerm"
 * → { path: "claude/custom-search/agents", overrides: { searchPrefix: "agent", args: { open: "iTerm" } } }
 */
export interface ParsedPluginEntry {
  path: string;
  overrides?: {
    searchPrefix?: string;
    args?: Record<string, string>;
  };
}

/**
 * Custom shortcut action entry (from settings shortcuts with custom actions)
 * e.g., { key: "Ctrl+m", action: "input=@md:" }
 */
export interface CustomShortcutEntry {
  key: string;
  action: string;
}

export interface AppInfo {
  name: string;
  bundleId?: string | null;
}

export interface SpaceInfo {
  method: string;
  signature: string;
  frontmostApp?: AppInfo | string | null;
  windowCount: number;
  appCount: number;
  apps: Array<{
    name: string;
    pid: number;
    windowCount: number;
    isActive: boolean;
  }>;
}

export interface WindowData {
  sourceApp?: AppInfo | string | null;
  currentSpaceInfo?: SpaceInfo | null;
  history?: HistoryItem[];
  draft?: string | DraftData | null;
  settings?: UserSettings;
  directoryData?: DirectoryInfo;
  fileSearchEnabled?: boolean;
  symbolSearchEnabled?: boolean;
}

export interface WindowBounds {
  x: number;
  y: number;
  width: number;
  height: number;
}

export type StartupPosition = 'cursor' | 'center' | 'active-window-center' | 'active-text-field';

export interface PlatformConfig {
  isMac: boolean;
  isWindows: boolean;
  isLinux: boolean;
}

export interface WindowConfig {
  width: number;
  height: number;
  frame: boolean;
  transparent: boolean;
  backgroundColor?: string;
  alwaysOnTop: boolean;
  skipTaskbar: boolean;
  resizable: boolean;
  webPreferences: {
    nodeIntegration: boolean;
    contextIsolation: boolean;
    webSecurity: boolean;
    preload?: string;  // Preload script path
    spellcheck: boolean;
    disableDialogs: boolean;
    enableWebSQL: boolean;
    experimentalFeatures: boolean;
    defaultEncoding: string;
    offscreen: boolean;
    enablePreferredSizeMode: boolean;
    disableHtmlFullscreenWindowResize: boolean;
    allowRunningInsecureContent?: boolean;  // Security setting
    sandbox?: boolean;  // Sandbox setting
  };
}

export interface ShortcutsConfig {
  main: string;
  paste: string;
  close: string;
  historyNext: string;
  historyPrev: string;
  search: string;
}

export interface PathsConfig {
  userDataDir: string;
  historyFile: string;
  draftFile: string;
  logFile: string;
  imagesDir: string;
  directoryFile: string;
  cacheDir: string;             // Cache root directory
  projectsCacheDir: string;     // Projects cache directory
  agentBuiltInDir: string;      // Agent built-in YAML files directory
  pluginsDir: string;           // Plugins directory
  agentSkillsDir: string;       // Agent skills YAML files directory
  customSearchDir: string;      // Custom search YAML files directory
}

export interface TimingConfig {
  windowHideDelay: number;
  appFocusDelay: number;
}

export interface AppConfig {
  name: string;
  version: string;
  versionDisplay: string;
  description: string;
}

export interface LoggingConfig {
  level: 'debug' | 'info' | 'warn' | 'error';
  enableFileLogging: boolean;
  maxLogFileSize: number;
  maxLogFiles: number;
}

export type LogLevel = 'debug' | 'info' | 'warn' | 'error';

export interface FileOpenerDirectoryEntry {
  // Directory path pattern (supports ~ for home, glob: * and **)
  path: string;
  // Editor application name
  editor: string;
}

export interface UserSettings {
  shortcuts: {
    main: string;
    paste: string;
    close: string;
    historyNext: string;
    historyPrev: string;
    search: string;
  };
  window: {
    position: StartupPosition;
    width: number;
    height: number;
  };
  commands?: {
    directories: string[];
  };
  agents?: {
    directories: string[];
  };
  fileOpener?: {
    // Extension-specific application settings (e.g., { "ts": "WebStorm", "md": "Typora" })
    extensions?: Record<string, string>;
    // Directory-specific default editor with glob support
    // Supports * (single directory level) and ** (multiple levels)
    // Most specific (longest non-glob prefix) match wins
    directories?: FileOpenerDirectoryEntry[];
    // Default editor when no extension-specific or directory-specific setting exists
    defaultEditor?: string | null;
  };
  // Agent built-in: list of tools to enable (e.g., ['claude', 'codex', 'gemini'])
  agentBuiltIn?: string[];
  // Agent skills: inline entries or file names from ~/.prompt-line/agent-skills/
  agentSkills?: (AgentSkillEntry | string)[];
  // File search settings (@path/to/file completion)
  fileSearch?: FileSearchUserSettings;
  // Symbol search settings (@ts:Config, @go:Handler)
  symbolSearch?: SymbolSearchUserSettings;
  // Custom search entries: inline entries or file names from ~/.prompt-line/custom-search/
  customSearch?: (MentionEntry | string)[];
  // Image directory path (relative to CWD, or absolute path)
  // When relative, resolved against current working directory
  imagesDirectory?: string;
  // Global mention filter: whitelist (exact match: "agent-claude", prefix match: "agent-*")
  mentionEnable?: string[];
  // Global mention filter: blacklist (exact match: "agent-legacy", prefix match: "old-*")
  mentionDisable?: string[];
  // Custom shortcut actions (extracted from {key: action} shortcuts format)
  customShortcuts?: CustomShortcutEntry[];

  // Legacy: mentions wrapper (use top-level fileSearch, symbolSearch, customSearch instead)
  /** @deprecated Use top-level fileSearch, symbolSearch, customSearch instead */
  mentions?: MentionsSettings;
  // Legacy: customSearch with type field (for backward compatibility)
  legacyCustomSearch?: CustomSearchEntry[];
  /**
   * Plugin entries to enable (paths relative to ~/.prompt-line/plugins/, without .yaml extension)
   * Comment out entries to disable them.
   *
   * v1 format (string[]): ["github.com/nkmr-jp/prompt-line-plugins/claude/agent-skills/commands"]
   * v2 format (Record<string, string[]>):
   *   { "github.com/user/repo/path": ["claude/agent-skills/commands"] }
   */
  plugins?: PluginFormat;
  /** Additional PATH entries for shell command execution (e.g., sourceCommand) */
  additionalPaths?: string[];
  // Legacy alias: mdSearch (for backward compatibility)
  mdSearch?: CustomSearchEntry[];
  // Legacy: slashCommands (use agentSkills instead)
  slashCommands?: AgentSkillsSettings;
  // Legacy: Agent built-in configuration (use agentBuiltIn instead)
  legacyAgentBuiltIn?: {
    tools?: string[];
  };
}

// ============================================================================
// Mention Settings Types (@ mentions)
// ============================================================================

import type { InputFormatType } from './file-search';

/**
 * File search user settings (@path/to/file completion)
 * All fields are optional - defaults are applied by the application
 */
export interface FileSearchUserSettings {
  /** Respect .gitignore files (fd only, default: true) */
  respectGitignore?: boolean;
  /** Additional exclude patterns (applied on top of .gitignore) */
  excludePatterns?: string[];
  /** Include patterns (force include even if in .gitignore) */
  includePatterns?: string[];
  /** Maximum number of files to return (default: 5000) */
  maxFiles?: number;
  /** Include hidden files (starting with .) */
  includeHidden?: boolean;
  /** Maximum directory depth (null = unlimited) */
  maxDepth?: number | null;
  /** Follow symbolic links (default: false) */
  followSymlinks?: boolean;
  /** Custom path to fd command (null = auto-detect from common paths) */
  fdPath?: string | null;
  /** Input format: 'name' (file name only) or 'path' (relative path, default) */
  inputFormat?: InputFormatType;
  /** Maximum number of suggestions to show (default: 50) */
  maxSuggestions?: number;
}

/**
 * Symbol search user settings (@language:query syntax)
 * All fields are optional - defaults are applied by the application
 */
export interface SymbolSearchUserSettings {
  /** Respect .gitignore files (default: true) */
  respectGitignore?: boolean;
  /** Maximum number of symbols to return (default: 200000) */
  maxSymbols?: number;
  /** Search timeout in milliseconds (default: 60000) */
  timeout?: number;
  /** Custom path to ripgrep command (null = auto-detect from common paths) */
  rgPath?: string | null;
  /** Additional exclude patterns (glob patterns like "vendor/**", "*.generated.go") */
  excludePatterns?: string[];
  /** Include patterns (force include even if excluded by default) */
  includePatterns?: string[];
  /** Follow symbolic links (default: false) */
  followSymlinks?: boolean;
}

/**
 * Mention settings combining fileSearch, symbolSearch, and userDefined mentions
 * @deprecated Use top-level fileSearch, symbolSearch, customSearch instead
 */
export interface MentionsSettings {
  /** File search settings (@path/to/file) */
  fileSearch?: FileSearchUserSettings;
  /** Symbol search settings (@ts:Config, @go:Handler) */
  symbolSearch?: SymbolSearchUserSettings;
  /** Custom search: mentions from markdown files */
  customSearch?: MentionEntry[];
  /** @deprecated Use customSearch instead */
  mdSearch?: MentionEntry[];
  /**
   * 有効にするメンション名のリスト（ホワイトリスト）
   * - 完全一致: "agent-claude"
   * - 前方一致: "agent-*"
   */
  enable?: string[];
  /**
   * 無効にするメンション名のリスト（ブラックリスト）
   * - 完全一致: "agent-legacy"
   * - 前方一致: "old-*"
   */
  disable?: string[];
}

// ============================================================================
// Agent Skills Settings Types
// ============================================================================

/**
 * Agent skills settings combining built-in commands and user-defined entries
 */
export interface AgentSkillsSettings {
  /** Custom agent skills from markdown files */
  custom?: AgentSkillEntry[];
  /**
   * 有効にするコマンド名のリスト（ホワイトリスト）
   * - 完全一致: "commit"
   * - 前方一致: "ralph-loop:*"
   */
  enable?: string[];
  /**
   * 無効にするコマンド名のリスト（ブラックリスト）
   * - 完全一致: "debug"
   * - 前方一致: "debug-*"
   */
  disable?: string[];
  // Legacy: agentBuiltIn (use root-level agentBuiltIn instead)
  agentBuiltIn?: string[];
}

/** @deprecated Use AgentSkillsSettings instead */
export type SlashCommandsSettings = AgentSkillsSettings;

/**
 * User-defined agent skill entry
 */
export interface AgentSkillEntry {
  /** 名前テンプレート（例: "{basename}", "{frontmatter@name}"） */
  name: string;
  /** 説明テンプレート（例: "{frontmatter@description}"） */
  description: string;
  /** ソースパス（ディレクトリ+globパターン、例: "~/.claude/commands/*.md"） */
  sourcePath: string;
  /** オプション: argumentHintテンプレート */
  argumentHint?: string;
  /** オプション: 検索候補の最大表示数（デフォルト: 20） */
  maxSuggestions?: number;
  /** オプション: ソート順（デフォルト: 'name'） - 'name', 'name desc', 'description desc' など */
  orderBy?: string;
  /** オプション: label（静的な値 "skill" または テンプレート "{frontmatter@label}"） */
  label?: string;
  /** オプション: ラベルとハイライトの色（grey, darkGrey, blue, purple, teal, green, yellow, orange, pink, red） */
  color?: ColorValue;
  /** オプション: codiconアイコンクラス名（例: "codicon-rocket", "symbol-class"） */
  icon?: string;
  /** オプション: テンプレート変数の値パターン - JSONファイルから動的に値を読み込む（キー名がテンプレート変数名になる） */
  values?: Record<string, string>;
  /** @deprecated Use values instead (e.g., values: { prefix: "pattern" }) */
  prefixPattern?: string;
  /** オプション: トリガー文字の配列（デフォルト: ['/']）。例: ['/', '$'] で / と $ 両方で起動可能 */
  triggers?: string[];
  /**
   * このエントリで有効にするコマンド名のリスト（ホワイトリスト）
   * - 完全一致: "commit"
   * - 前方一致: "ralph-loop:*"
   */
  enable?: string[];
  /**
   * このエントリで無効にするコマンド名のリスト（ブラックリスト）
   * - 完全一致: "debug"
   * - 前方一致: "debug-*"
   */
  disable?: string[];
  /** オプション: コマンドの標準出力を検索ソースとして使用するシェルコマンド文字列（指定時は sourcePath の代わりに使用） */
  sourceCommand?: string;
  /** オプション: テンプレート引数（例: { open: "iTerm" } → {args.open} で参照可能） */
  args?: Record<string, string>;
}

/** @deprecated Use AgentSkillEntry instead */
export type SlashCommandEntry = AgentSkillEntry;

/**
 * Mention entry (@ mentions from markdown files)
 */
export interface MentionEntry {
  /** 名前テンプレート（例: "{basename}", "agent-{frontmatter@name}"） */
  name: string;
  /** 説明テンプレート（例: "{frontmatter@description}"） */
  description: string;
  /** ソースパス（ディレクトリ+globパターン、例: "~/.claude/agents/*.md"） */
  sourcePath: string;
  /** オプション: 検索候補の最大表示数（デフォルト: 20） */
  maxSuggestions?: number;
  /** オプション: 検索プレフィックス（例: "agent"）- 自動で : が追加されます（@agent: で検索） */
  searchPrefix?: string;
  /** オプション: ソート順（デフォルト: 'name'） - 'name', 'name desc', 'description desc' など */
  orderBy?: string;
  /** オプション: 末尾に表示する日時テンプレート（例: "{mtime}", "{json@createdAt}", "none"で非表示） */
  displayTime?: string;
  /** オプション: 入力フォーマット（デフォルト: 'name'） */
  inputFormat?: InputFormatType;
  /** オプション: テンプレート変数の値パターン - JSONファイルから動的に値を読み込む（キー名がテンプレート変数名になる） */
  values?: Record<string, string>;
  /** @deprecated Use values instead (e.g., values: { prefix: "pattern" }) */
  prefixPattern?: string;
  /** オプション: label（静的な値 "skill" または テンプレート "{frontmatter@label}"） */
  label?: string;
  /** オプション: ラベルとハイライトの色（grey, darkGrey, blue, purple, teal, green, yellow, orange, pink, red） */
  color?: ColorValue;
  /** オプション: codiconアイコンクラス名（例: "codicon-rocket", "symbol-class"） */
  icon?: string;
  /**
   * オプション: 有効にするメンション名のリスト（このエントリのみに適用）
   * - 完全一致: "agent-claude"
   * - 前方一致: "agent-*"
   */
  enable?: string[];
  /**
   * オプション: 無効にするメンション名のリスト（このエントリのみに適用）
   * - 完全一致: "agent-legacy"
   * - 前方一致: "old-*"
   */
  disable?: string[];
  /** オプション: Ctrl+Enter で実行するシェルコマンド。テンプレート変数({filepath}, {basename}, {content}等)使用可 */
  runCommand?: string;
  /** オプション: コマンドの標準出力を検索ソースとして使用するシェルコマンド文字列（指定時は sourcePath の代わりに使用） */
  sourceCommand?: string;
  /** オプション: テンプレート引数（例: { open: "iTerm" } → {args.open} で参照可能） */
  args?: Record<string, string>;
  /** オプション: tooltip popup に表示するテキスト（テンプレート変数使用可）。設定時はファイルのfrontmatterより優先 */
  tooltip?: string;
}

// ============================================================================
// CustomSearch Related Types (Legacy - for backward compatibility)
// ============================================================================

/**
 * customSearch エントリの種類
 * - command: スラッシュコマンド（/で始まる）
 * - mention: メンション（@で始まる）
 */
export type CustomSearchType = 'command' | 'mention';

/**
 * customSearch 設定エントリ
 */
export interface CustomSearchEntry {
  /** 名前テンプレート（例: "{basename}", "agent-{frontmatter@name}"） */
  name: string;
  /** 検索タイプ */
  type: CustomSearchType;
  /** 説明テンプレート（例: "{frontmatter@description}"） */
  description: string;
  /** ソースパス（ディレクトリ+globパターン、例: "~/.claude/commands/*.md"）（sourceCommand指定時は空文字""を設定） */
  sourcePath: string;
  /** オプション: label（静的な値 "skill" または テンプレート "{frontmatter@label}"） */
  label?: string;
  /** オプション: ラベルとハイライトの色（grey, darkGrey, blue, purple, teal, green, yellow, orange, pink, red） */
  color?: ColorValue;
  /** オプション: codiconアイコンクラス名（例: "codicon-rocket", "codicon-symbol-class"） */
  icon?: string;
  /** オプション: argumentHintテンプレート */
  argumentHint?: string;
  /** オプション: 検索候補の最大表示数（デフォルト: 20） */
  maxSuggestions?: number;
  /** オプション: 検索プレフィックス（例: "agent"）- 自動で : が追加されます（@agent: で検索） */
  searchPrefix?: string;
  /** オプション: ソート順（デフォルト: 'name'） - 'name', 'name desc', 'description desc' など */
  orderBy?: string;
  /** オプション: 末尾に表示する日時テンプレート（例: "{mtime}", "{json@createdAt}", "none"で非表示） */
  displayTime?: string;
  /** オプション: 入力フォーマット（デフォルト: 'name'） - 'name': 名前のみ, 'path': ファイルパス */
  inputFormat?: InputFormatType;
  /** オプション: テンプレート変数の値パターン - JSONファイルから動的に値を読み込む（キー名がテンプレート変数名になる） */
  values?: Record<string, string>;
  /** @deprecated Use values instead (e.g., values: { prefix: "pattern" }) */
  prefixPattern?: string;
  /** オプション: トリガー文字の配列（commandタイプのみ、デフォルト: ['/']） */
  triggers?: string[];
  /**
   * オプション: 有効にするアイテム名のリスト（このエントリのみに適用）
   * - 完全一致: "commit"
   * - 前方一致: "ralph-loop:*"
   */
  enable?: string[];
  /**
   * オプション: 無効にするアイテム名のリスト（このエントリのみに適用）
   * - 完全一致: "debug"
   * - 前方一致: "debug-*"
   */
  disable?: string[];
  /** オプション: Ctrl+Enter で実行するシェルコマンド。テンプレート変数({filepath}, {basename}, {content}等)使用可 */
  runCommand?: string;
  /** オプション: このファイルが存在するディレクトリを検索対象から除外する（例: ".orphaned_at"） */
  excludeMarker?: string;
  /**
   * Optional: exclude individual items based on a template expression result
   * - `"{frontmatter@hidden}"` — exclude when the resolved template is non-empty
   * - `"{frontmatter@searchable}==false"` — exclude when the resolved value exactly matches the right-hand literal
   */
  excludeIf?: string;
  /** オプション: コマンドの標準出力を検索ソースとして使用するシェルコマンド文字列（指定時は sourcePath の代わりに使用） */
  sourceCommand?: string;
  /** オプション: テンプレート引数（例: { open: "iTerm" } → {args.open} で参照可能） */
  args?: Record<string, string>;
  /** オプション: sourceCommand/runCommand 実行時の作業ディレクトリ（YAMLファイルのディレクトリパス） */
  sourceDir?: string;
  /** オプション: tooltip popup に表示するテキスト（テンプレート変数使用可）。設定時はファイルのfrontmatterより優先 */
  tooltip?: string;
}

/**
 * 検索結果アイテム（統一型）
 */
export interface CustomSearchItem {
  /** 解決済み名前 */
  name: string;
  /** 解決済み説明 */
  description: string;
  /** ソースタイプ */
  type: CustomSearchType;
  /** ファイルパス */
  filePath: string;
  /** Tooltip popup content（ポップアップ表示用テキスト） */
  tooltip?: string;
  /** label（オプション） */
  label?: string;
  /** ラベルとハイライトの色（オプション） */
  color?: ColorValue;
  /** codiconアイコンクラス名（オプション） */
  icon?: string;
  /** argumentHint（commandタイプのみ） */
  argumentHint?: string;
  /** 検索ソースの識別子（sourcePath） */
  sourceId: string;
  /** カスタムソートキー（orderByテンプレートの解決値） */
  sortKey?: string;
  /** 入力フォーマット（'name' | テンプレート文字列 e.g. '{filepath}', '{content}'） */
  inputFormat?: InputFormatType;
  /** テンプレート解決済みの入力テキスト（inputFormatがテンプレートの場合に使用） */
  inputText?: string;
  /** ファイル更新日時（mtimeMs） */
  mtime?: number;
  /** 表示用日時（displayTime設定で解決された値。undefinedはmtimeにフォールバック、nullは非表示） */
  displayTime?: number | null;
  /** トリガー文字の配列（commandタイプのみ） */
  triggers?: string[];
  /** テンプレート解決済みのコマンド文字列（Ctrl+Enter で実行） */
  runCommand?: string;
  /** sourceCommand/runCommand 実行時の作業ディレクトリ（YAMLファイルのディレクトリパス） */
  sourceDir?: string;
}

export interface AgentSkillItem {
  name: string;
  description: string;
  label?: string;  // Label text (e.g., from frontmatter)
  color?: ColorValue;  // Color for label and highlight
  icon?: string;  // Codicon icon class name (e.g., "codicon-rocket")
  argumentHint?: string; // Hint text shown when editing arguments (after Tab selection)
  filePath: string;
  tooltip?: string;  // Tooltip popup content（ポップアップ表示用テキスト）
  inputFormat?: InputFormatType;  // 入力フォーマット（'name' | テンプレート e.g. '{filepath}', '{content}'）
  inputText?: string;  // テンプレート解決済みの入力テキスト
  source?: string;  // Source tool identifier (e.g., 'claude-code') for filtering
  displayName?: string;  // Human-readable source name for display (e.g., 'Claude Code')
  mtime?: number;  // File modification timestamp (mtimeMs)
  triggers?: string[];  // Trigger prefixes (e.g., ['/', '$'])
}

/** @deprecated Use AgentSkillItem instead */
export type SlashCommandItem = AgentSkillItem;

export interface AgentItem {
  name: string;
  description: string;
  filePath: string;
  tooltip?: string;  // Tooltip popup content（ポップアップ表示用テキスト）
  inputFormat?: InputFormatType;  // 入力フォーマット（'name' | テンプレート e.g. '{filepath}', '{content}'）
  inputText?: string;  // テンプレート解決済みの入力テキスト
  color?: ColorValue;
  icon?: string;  // Codicon icon class name (e.g., "codicon-rocket")
  label?: string;
  mtime?: number;  // File modification timestamp (mtimeMs)
  displayTime?: number | null;  // Resolved display time (null = hidden, undefined = fallback to mtime)
  runCommand?: string;  // Shell command to execute on Ctrl+Enter (template-resolved)
}
