use crate::state::EditorMode;
use crate::glide::{Motion, Operator, FindKind};

#[derive(Debug, Clone, PartialEq)]
pub enum Action {
    // Navigation
    MoveUp,
    MoveDown,
    MoveLeft,
    MoveRight,
    PageUp,
    PageDown,
    PageTop,
    PageBottom,
    Home,
    End,

    // Editing
    InsertChar(char),
    InsertString(String), // Paste operation
    Backspace,
    Delete,
    Enter,

    // Mode Switching
    EnterMode(EditorMode),

    // Execution
    Save(String),
    SaveAndExit(String), // Ctrl+X → Enter: save, then exit
    Open(String),
    SearchNext,
    SearchPrevious,
    Undo,
    Redo,
    ReplaceCurrent,
    ReplaceAll,

    SwitchFocus,
    ToggleSearchMode,

    // System
    Quit,   // Force Quit (Ctrl+Q)
    Cancel, // Esc
    ReloadConfig, // F5
    ToggleLineNumbers, // Ctrl+L
    DeleteLine, // Ctrl+K
    GotoLine(usize), // 行ジャンプ (1-indexed)
    PasteFromClipboard,
    ToggleWrap,

    // Glide mode movement: a motion resolved by the glide engine
    GlideMove(Motion),
    // Paste the unnamed register: true = after cursor/line (p), false = before (P)
    PasteRegister(bool),
    // Operator+motion: d/c/y set a pending operator; the next motion applies it
    SetOperator(Operator),
    ClearOperator,
    SetFindPending(FindKind), // f/t/F/T while an operator is pending: capture next char
    ToggleCase,      // ~ : toggle case of the char under the cursor and move right
    ChangeToLineEnd, // C = c$
    YankLine,        // Y = yy

    // Glide mode edit-entry
    DeleteToLineEnd,      // D: delete from cursor to end of line
    GlideJoin,            // J: join current line with next
    GlideInsert,          // i: Edit mode at cursor
    GlideInsertLineStart, // I: first non-whitespace then Edit
    GlideAppend,          // a: move right then Edit
    GlideAppendEnd,       // A: line end then Edit
    GlideOpenLine,        // o: open line below then Edit
    GlideOpenLineAbove,   // O: open line above then Edit

    // Internal: set/clear the Glide prefix key (e.g. 'g' waiting for second 'g')
    SetGlidePrefix(Option<char>),
    // Internal: accumulate a count digit in Glide mode
    GlideDigit(char),
}
