//! All user actions expressed as the `AppCommand` enum, dispatched by `App::dispatch()`.

use std::path::PathBuf;

use crate::model::{FollowUp, LaunchQuantization, PatternSpeed, SyncMode};
use crate::page::Page;
use crate::state::{ColorScheme, DeviceKind, EngineSection, Modal, OptionsFocus, PatternField, ScriptField, SettingKind};

pub enum AppCommand {
    // Undo/Redo
    Undo,
    Redo,

    // Playback
    TogglePlaying,
    TempoUp,
    TempoDown,

    // Navigation
    NextStep,
    PrevStep,
    StepUp,
    StepDown,
    NextPattern,
    PrevPattern,
    NextBank,
    PrevBank,

    // Pattern editing
    ToggleSteps,
    LengthIncrease,
    LengthDecrease,
    SpeedIncrease,
    SpeedDecrease,
    SetLength {
        bank: usize,
        pattern: usize,
        length: usize,
    },
    SetSpeed {
        bank: usize,
        pattern: usize,
        speed: PatternSpeed,
    },

    // Script editing
    SaveEditorToStep,
    CompileCurrentStep,
    DeleteStep {
        bank: usize,
        pattern: usize,
        step: usize,
    },
    DeleteSteps {
        bank: usize,
        pattern: usize,
        steps: Vec<usize>,
    },
    ResetPattern {
        bank: usize,
        pattern: usize,
    },
    ResetBank {
        bank: usize,
    },
    CopyPattern {
        bank: usize,
        pattern: usize,
    },
    PastePattern {
        bank: usize,
        pattern: usize,
    },
    SharePattern {
        bank: usize,
        pattern: usize,
    },
    ImportPattern {
        bank: usize,
        pattern: usize,
    },
    ShareBank {
        bank: usize,
    },
    ImportBank {
        bank: usize,
    },
    CopyPatterns {
        bank: usize,
        patterns: Vec<usize>,
    },
    PastePatterns {
        bank: usize,
        start: usize,
    },
    CopyBank {
        bank: usize,
    },
    PasteBank {
        bank: usize,
    },
    CopyBanks {
        banks: Vec<usize>,
    },
    PasteBanks {
        start: usize,
    },
    ResetPatterns {
        bank: usize,
        patterns: Vec<usize>,
    },
    ResetBanks {
        banks: Vec<usize>,
    },

    // Reorder
    ShiftPatternsUp,
    ShiftPatternsDown,

    // Clipboard
    HardenSteps,
    CopySteps,
    PasteSteps,
    LinkPasteSteps,
    DuplicateSteps,

    // Pattern playback (staging)
    ClearStagedChanges,

    // Project
    RenameBank {
        bank: usize,
        name: Option<String>,
    },
    RenamePattern {
        bank: usize,
        pattern: usize,
        name: Option<String>,
    },
    RenameStep {
        bank: usize,
        pattern: usize,
        step: usize,
        name: Option<String>,
    },
    DescribePattern {
        bank: usize,
        pattern: usize,
        description: Option<String>,
    },
    Save(PathBuf),
    Load(PathBuf),

    // UI
    SetStatus(String),
    ClearStatus,
    OpenModal(Modal),
    CloseModal,
    OpenPatternModal(PatternField),
    OpenPatternPropsModal {
        bank: usize,
        pattern: usize,
    },
    StagePatternProps {
        bank: usize,
        pattern: usize,
        name: Option<String>,
        description: Option<String>,
        length: Option<usize>,
        speed: PatternSpeed,
        quantization: LaunchQuantization,
        sync_mode: SyncMode,
        follow_up: FollowUp,
    },

    // Page navigation
    PageLeft,
    PageRight,
    PageUp,
    PageDown,
    GoToPage(Page),

    // Help navigation
    HelpToggleFocus,
    HelpNextTopic(usize),
    HelpPrevTopic(usize),
    HelpScrollDown(usize),
    HelpScrollUp(usize),
    HelpActivateSearch,
    HelpClearSearch,
    HelpSearchInput(char),
    HelpSearchBackspace,
    HelpSearchConfirm,

    // Dictionary navigation
    DictToggleFocus,
    DictNextCategory,
    DictPrevCategory,
    DictScrollDown(usize),
    DictScrollUp(usize),
    DictActivateSearch,
    DictClearSearch,
    DictSearchInput(char),
    DictSearchBackspace,
    DictSearchConfirm,

    // Patterns view
    PatternsCursorLeft,
    PatternsCursorRight,
    PatternsCursorUp,
    PatternsCursorDown,
    PatternsEnter,
    PatternsBack,

    // Mute/Solo (staged)
    StageMute { bank: usize, pattern: usize },
    StageSolo { bank: usize, pattern: usize },
    ClearMutes,  // Clears both staged and applied mutes
    ClearSolos,  // Clears both staged and applied solos

    // UI state
    ClearMinimap,
    HideTitle,
    ToggleEditorStack,
    SetColorScheme(ColorScheme),
    SetHueRotation(f32),
    ToggleRuntimeHighlight,
    ToggleCompletion,
    SetFont(String),
    SetZoomFactor(f32),
    SetWindowSize(u32, u32),

    // Live keys
    ToggleLiveKeysFill,

    // Panel
    ClosePanel,

    // Direct navigation (mouse)
    GoToStep(usize),
    PatternsSelectBank(usize),
    PatternsSelectPattern(usize),
    HelpSelectTopic(usize),
    DictSelectCategory(usize),

    // Selection
    SetSelectionAnchor(usize),

    // Audio settings (engine page)
    AudioSetSection(EngineSection),
    AudioNextSection,
    AudioPrevSection,
    AudioOutputListUp,
    AudioOutputListDown(usize),
    AudioOutputPageUp,
    AudioOutputPageDown(usize),
    AudioInputListUp,
    AudioInputListDown(usize),
    AudioInputPageDown(usize),
    AudioSettingNext,
    AudioSettingPrev,
    SetOutputDevice(String),
    SetInputDevice(String),
    SetDeviceKind(DeviceKind),
    AdjustAudioSetting {
        setting: SettingKind,
        delta: i32,
    },
    AudioTriggerRestart,
    RemoveSamplePath(usize),
    AudioRefreshDevices,

    // Options page
    OptionsNextFocus,
    OptionsPrevFocus,
    OptionsSetFocus(OptionsFocus),
    ToggleRefreshRate,
    ToggleScope,
    ToggleSpectrum,
    ToggleLissajous,
    CycleScopeMode,
    FlipScopeOrientation,
    ToggleLissajousTrails,
    CycleSpectrumMode,
    ToggleSpectrumPeaks,
    TogglePreview,
    SetGainBoost(f32),
    ToggleNormalizeViz,
    TogglePerformanceMode,

    // Metrics
    ResetPeakVoices,

    // Euclidean distribution
    ApplyEuclideanDistribution {
        bank: usize,
        pattern: usize,
        source_step: usize,
        pulses: usize,
        steps: usize,
        rotation: usize,
    },

    // Prelude
    OpenPreludeEditor,
    SavePrelude,
    EvaluatePrelude,
    ClosePreludeEditor,

    // Onboarding
    DismissOnboarding,
    ResetOnboarding,
    GoToHelpTopic(usize),

    // Periodic script
    OpenScriptModal(ScriptField),
    SetScriptSpeed(PatternSpeed),
    SetScriptLength(usize),
    ScriptSave,
    ScriptEvaluate,
    ToggleScriptStack,
}
