export type ThemeMode = "light" | "dark" | "system";
export type FontFamily = "lexend" | "atkinson" | "opendyslexic";
export type ReduceMotion = "system" | "on" | "off";
export type RecordingEngine = "whisper" | "parakeet";
export type FormatMode = "Raw" | "Clean" | "Smart";
export type WhisperModelSize =
  | "Tiny"
  | "Base"
  | "Small"
  | "Distil-S"
  | "Medium"
  | "Distil-L";
export type AiTier = "off" | "cleanup" | "tasks";
export type LlmModelIdStr =
  | "qwen3_5_2b"
  | "qwen3_5_4b"
  | "qwen3_5_9b"
  | "qwen3_6_27b";
export type LlmPromptPreset = "default" | "email" | "notes" | "code";
export type AiGpuConcurrency = "parallel" | "sequential";
export type TaskBucket = "inbox" | "today" | "soon" | "later";
export type ToastSeverity = "info" | "success" | "warn" | "error";
export type ImplementationRuleTriggerKind =
  | "time_of_day"
  | "task_completed"
  | "morning_triage_finished";
export type ImplementationRuleSurfaceTarget = "inbox" | "today" | "tasks" | "task";

export interface PageState {
  current: string;
  status: string;
  statusColor: string;
  activeProfile: string;
  recording: boolean;
  timerText: string;
  handedness: string;
  taskSidebarOpen: boolean;
}

export interface SettingsState {
  engine: RecordingEngine;
  modelSize: WhisperModelSize;
  language: string;
  device: string;
  formatMode: FormatMode;
  removeFillers: boolean;
  antiHallucination: boolean;
  britishEnglish: boolean;
  autoCopy: boolean;
  autoPaste: boolean;
  transcriptionPreview: boolean;
  meetingAutoCapture: boolean;
  meetingAutoCaptureApps: string[];
  soundCues: boolean;
  soundCueVolume: number;
  includeTimestamps: boolean;
  theme: "Dark" | "Light" | "System";
  fontSize: number;
  aiTier: AiTier;
  llmModelId: LlmModelIdStr | null;
  llmPromptPreset: LlmPromptPreset;
  aiGpuConcurrency: AiGpuConcurrency;
  prewarmModelOnStartup: boolean;
  saveAudio: boolean;
  outputFolder: string;
  globalHotkey: string;
  sidebarCollapsed: boolean;
  microphoneDevice: string;
  /**
   * Phase 3 match-my-energy: the user's self-reported current energy
   * level. `null` means "not stated" — the sort falls back to created_at
   * order. Persists across sessions because energy tracks the person,
   * not the work.
   */
  currentEnergy: EnergyLevel | null;
  /**
   * Phase 3 match-my-energy: when true, the Tasks page sorts tasks
   * matching `currentEnergy` to the top (with unset tasks treated as
   * Medium). Off by default so the list reads chronologically until
   * the user explicitly opts in.
   */
  matchMyEnergy: boolean;
  /**
   * Phase 4 Read Page Aloud: OS-native TTS. `voice` is the platform's
   * voice id (e.g. macOS `Alex`), or `null` for system default.
   * `rate` is 0.5..2.0 where 1.0 is the synth's normal speed.
   */
  ttsVoice: string | null;
  ttsRate: number;
  /**
   * Phase 5 rituals. All off by default — opt-in per Jake's standing
   * rule that rituals must never feel parental. Discovery happens
   * through the first-run prompt, not default-on behaviour.
   */
  ritualsMorning: boolean;
  /**
   * HH:MM (24h, local time) — earliest clock time after which the
   * morning triage modal is allowed to appear on a given day. Default
   * 08:00 because ADHD sleep inertia intensifies the first ~45 minutes
   * after waking (Aspire Therapy, CHADD); 06:00 is too early to ask
   * for decisions.
   */
  ritualsMorningTime: string;
  ritualsEvening: boolean;
  /**
   * Phase 5: register Lumotia as a login-time autostart entry. The
   * actual OS-level state lives in `tauri-plugin-autostart`; this
   * flag mirrors it so the Settings UI can render without a round-trip
   * on every mount.
   */
  launchAtLogin: boolean;
  /**
   * First-run has surfaced the ritual prompts at least once. Keeps the
   * prompt from re-appearing on every update-triggered reboot.
   */
  ritualsPromptSeen: boolean;
  /**
   * Phase 6 Margot nudges. All off by default per Jake's standing rule
   * about opt-in nudging. `nudgesMuted` is separate from `nudgesEnabled`
   * so the user can flip a hard mute without losing their preferences.
   */
  nudgesEnabled: boolean;
  nudgesMuted: boolean;
  /**
   * When true, nudges also speak their body through Phase 4 TTS. Only
   * has effect when `nudgesEnabled` is true.
   */
  nudgesSpeakAloud: boolean;
  /**
   * Phase 8. Controls the 7-day momentum sparkline only. The "N today"
   * badge on the Tasks header is always on regardless. Default true so
   * existing users see the sparkline on upgrade.
   */
  showMomentumSparkline: boolean;
}

export interface Profile {
  name: string;
  words: string;
}

export interface Template {
  name: string;
  sections: string[];
}

export interface AccessibilityPreferences {
  fontFamily: FontFamily;
  fontSize: number;
  letterSpacing: number;
  lineHeight: number;
  transcriptSize: number;
  bionicReading: boolean;
  reduceMotion: ReduceMotion;
}

export interface Preferences {
  theme: ThemeMode;
  zone: string;
  accessibility: AccessibilityPreferences;
}

export interface Segment {
  start: number;
  end: number;
  text: string;
  starred?: boolean;
  [key: string]: unknown;
}

export interface TranscriptDto {
  id: string;
  text: string;
  source: string;
  profileId: string;
  title: string | null;
  audioPath: string | null;
  duration: number;
  engine: string | null;
  modelId: string | null;
  createdAt: string;
  starred: boolean;
  manualTags: string;
  template: string;
  language: string;
  segmentsJson: string;
  /** Phase 9. Comma-joined LLM-generated tags ("topic:foo", "intent:..."). */
  llmTags: string;
}

export interface TranscriptEntry {
  id: string;
  text: string;
  source: string;
  profileId: string;
  title: string;
  audioPath: string | null;
  duration: number;
  engine: string | null;
  modelId: string | null;
  createdAt: string | null;
  date: string;
  preview: string;
  starred: boolean;
  manualTags: string[];
  template: string;
  language: string;
  segments: Segment[];
  /** Phase 9. AI-generated content tags ("topic:foo", "intent:..."). */
  llmTags: string[];
}

export interface ContentTags {
  topic: string;
  intent: string;
}

export interface TranscriptWriteEntry extends Partial<TranscriptEntry> {
  id: string;
  text: string;
  inferenceMs?: number | null;
  sampleRate?: number | null;
  audioChannels?: number | null;
  formatMode?: string | null;
  removeFillers?: boolean;
  britishEnglish?: boolean;
  antiHallucination?: boolean;
}

export interface TranscriptMetaPatch {
  starred?: boolean;
  manualTags?: string[] | string;
  template?: string;
  language?: string;
  segments?: Segment[];
  /** Phase 9. Pass an array to set, an empty array to clear, or omit
   *  the field to leave llm_tags unchanged. */
  llmTags?: string[] | string;
}

/**
 * Phase 3: energy level tag on a task. `null` means unset — the sort
 * treats unset as Medium-equivalent. Three tagged values match the
 * brief's "High / Medium / Brain-Dead" language; `brain_dead` is the
 * stored form because SQL enums don't love hyphens.
 */
export type EnergyLevel = "high" | "medium" | "brain_dead";

/**
 * Phase 8: one bucket in the 7-day completion history fed to the
 * momentum sparkline. `day` is "YYYY-MM-DD" local time.
 */
export interface DailyCompletionCount {
  day: string;   // "YYYY-MM-DD" local
  count: number;
}

export interface TaskDto {
  id: string;
  text: string;
  bucket: string;
  listId: string | null;
  effort: string | null;
  notes: string;
  done: boolean;
  doneAt: string | null;
  createdAt: string;
  sourceTranscriptId: string | null;
  parentTaskId: string | null;
  energy: EnergyLevel | null;
}

export interface TaskEntry {
  id: string;
  text: string;
  bucket: TaskBucket;
  listId: string | null;
  effort: string;
  notes: string;
  done: boolean;
  doneAt: string | null;
  createdAt: string;
  sourceTranscriptId: string | null;
  parentTaskId: string | null;
  energy: EnergyLevel | null;
}

export type ImplementationRuleAction =
  | {
      kind: "surface";
      target: ImplementationRuleSurfaceTarget;
      taskId?: string | null;
      label?: string | null;
    }
  | {
      kind: "start_timer";
      seconds: number;
      taskId?: string | null;
      label?: string | null;
    }
  | {
      kind: "speak_line";
      text: string;
    };

export interface ImplementationRule {
  id: string;
  enabled: boolean;
  triggerKind: ImplementationRuleTriggerKind;
  triggerValue: string;
  actions: ImplementationRuleAction[];
  lastFiredKey: string | null;
  createdAt: string;
  updatedAt: string;
}

export interface ImplementationRuleDraft {
  enabled?: boolean;
  triggerKind: ImplementationRuleTriggerKind;
  triggerValue: string;
  actions: ImplementationRuleAction[];
  lastFiredKey?: string | null;
}

export interface TaskDraft {
  text: string;
  bucket?: TaskBucket;
  listId?: string | null;
  effort?: string | null;
  sourceTranscriptId?: string | null;
  energy?: EnergyLevel | null;
}

export interface TaskUpdate {
  text?: string | null;
  bucket?: TaskBucket | null;
  listId?: string | null;
  effort?: string | null;
  notes?: string | null;
}

export interface TaskList {
  id: string;
  name: string;
  builtIn: boolean;
  profileId?: string | null;
  createdAt: string | null;
}

export interface ToastItem {
  id: number;
  severity: ToastSeverity;
  title: string;
  body: string;
  duration: number;
}

export interface AudioDeviceInfo {
  name: string;
  sample_rate: number;
  channels: number;
  is_likely_monitor: boolean;
  is_default: boolean;
  description: string;
}

export interface DictionaryEntry {
  id: number;
  term: string;
  note: string | null;
}

export interface LanguageSupportInfo {
  kind: string;
  languageCount: number;
}

export interface ModelRuntimeCapabilities {
  id: string;
  displayName: string;
  downloaded: boolean;
  loaded: boolean;
  languageSupport: LanguageSupportInfo;
}

export interface EngineRuntimeCapabilities {
  id: string;
  defaultModelId: string;
  loadedModelId: string | null;
  supportsGpu: boolean;
  models: ModelRuntimeCapabilities[];
}

export interface RuntimeCapabilities {
  accelerators: string[];
  engines: EngineRuntimeCapabilities[];
}

export interface DiagnosticReportOptions {
  includeRecentErrors: boolean;
  includeCrashes: boolean;
  includeSettings: boolean;
  includeLogTail: boolean;
}

export interface ViewerSegment extends Segment {
  _idx: number;
}
