use crate::app::{Action, AppState};

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CommandCategory {
    GitOperations,
    FileOperations,
    Navigation,
    Configuration,
    MergeRebase,
    Conflicts,
    Staging,
    Remote,
    Log,
    Rebase,
    Reset,
    Pr,
    AutoFetch,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CommandId {
    StageSelected,
    UnstageSelected,
    StageAll,
    UnstageAll,
    Commit,
    Amend,
    Push,
    CherryPick,
    Revert,
    RebaseContinue,
    RebaseAbort,
    RebaseSkip,
    ResetSoft,
    ResetMixed,
    ResetHard,
    ShowOpLog,
    MergeToggle,
    MergeBase,
    MergeInterval,
    MergeCheck,
    MergeLog,
    MergeBasePicker,
    MergedList,
    MergedPrune,
    RemotePrune,
    ShowRemoteUrl,
    SetRemoteSsh,
    LogBrief,
    LogStats,
    Pull,
    PullRebase,
    PullTimeout,
    RebaseTimeout,
    ToggleFfOnly,
    ToggleAutostash,
    TogglePushFf,
    ConflictsOnly,
    ConflictsPopup,
    OpenInEditor,
    StageHunk,
    UnstageHunk,
    StageLines,
    UnstageLines,
    ConflictNext,
    ConflictPrev,
    ReloadTheme,
    SwitchTheme,
    LoadFullDiff,
    ShowBranches,
    ShowLog,
    ShowTags,
    ShowStash,
    ShowReflog,
    RebaseTodo,
    RebaseTodoSave,
    AutoFetchToggle,
    AutoFetchInterval,
    AutoFetchRemote,
    AutoFetchCheck,
    PrHelper,
    PrOpen,
    PrCheckout,
    CreateBranch,
    CreateStash,
}

pub struct CommandDef {
    #[allow(dead_code)]
    pub id: CommandId,
    pub name: &'static str,
    pub key: &'static str,
    pub category: CommandCategory,
    pub description: &'static str,
    pub action_factory: fn(&AppState) -> Option<Action>,
    pub is_enabled: fn(&AppState) -> bool,
    pub keywords: &'static [&'static str],
}

impl CommandDef {
    pub fn create_action(&self, state: &AppState) -> Option<Action> {
        (self.action_factory)(state)
    }

    pub fn enabled(&self, state: &AppState) -> bool {
        (self.is_enabled)(state)
    }
}