use anyhow::Result;
use strum_macros::{Display, EnumIter, EnumString};

use crate::config::Colors;
use crate::event_exec::EventExec;
use crate::status::Status;

/// Different kind of action which can be mapped to a key.
/// All those actions are mapped to a key and this enum
/// makes the junction between received Key events and
/// actions in the application.
#[derive(Clone, Debug, Display, EnumString, EnumIter)]
pub enum ActionMap {
    Back,
    BackTab,
    Backspace,
    Bulk,
    Chmod,
    ClearFlags,
    CliInfo,
    Command,
    Compress,
    CopyFilename,
    CopyFilepath,
    CopyPaste,
    CutPaste,
    Delete,
    DeleteFile,
    Diff,
    ToggleDisplayFull,
    DragNDrop,
    EncryptedDrive,
    End,
    Enter,
    Exec,
    Filter,
    FlagAll,
    FuzzyFind,
    FuzzyFindLine,
    FuzzyFindHelp,
    Goto,
    Help,
    History,
    Home,
    Jump,
    KeyHome,
    Log,
    MarksJump,
    MarksNew,
    ModeNormal,
    MoveDown,
    MoveLeft,
    MoveRight,
    MoveUp,
    NewDir,
    NewFile,
    Nothing,
    NvimFilepicker,
    NvimSetAddress,
    OpenConfig,
    OpenFile,
    PageDown,
    PageUp,
    Preview,
    Quit,
    RefreshView,
    RegexMatch,
    Rename,
    ReverseFlags,
    Search,
    SearchNext,
    SetWallpaper,
    Shell,
    ShellMenu,
    Shortcut,
    Sort,
    Symlink,
    Tab,
    MocpAddToPlayList,
    MocpGoToSong,
    MocpTogglePause,
    MocpNext,
    MocpPrevious,
    MediaInfo,
    ToggleDualPane,
    ToggleFlag,
    ToggleHidden,
    TogglePreviewSecond,
    TrashMoveFile,
    TrashRestoreFile,
    TrashEmpty,
    TrashOpen,
    Tree,
    TreeFold,
    TreeUnFoldAll,
    TreeFoldAll,
}

impl ActionMap {
    /// Makes the junction between `Actions` and `Events`.
    /// Every Action links to a different `EventExec` method.
    pub fn matcher(&self, status: &mut Status, colors: &Colors) -> Result<()> {
        let current_tab = status.selected();
        match *self {
            ActionMap::Back => EventExec::event_back(status, colors),
            ActionMap::BackTab => EventExec::backtab(status),
            ActionMap::Backspace => EventExec::event_backspace(status),
            ActionMap::Bulk => EventExec::event_bulk(status),
            ActionMap::Chmod => EventExec::event_chmod(status),
            ActionMap::ClearFlags => EventExec::event_clear_flags(status),
            ActionMap::CliInfo => EventExec::event_cli_info(status),
            ActionMap::Command => EventExec::event_command(current_tab),
            ActionMap::Compress => EventExec::event_compress(status),
            ActionMap::CopyFilename => EventExec::event_copy_filename(status),
            ActionMap::CopyFilepath => EventExec::event_copy_filepath(status),
            ActionMap::CopyPaste => EventExec::event_copy_paste(status),
            ActionMap::CutPaste => EventExec::event_cut_paste(status),
            ActionMap::Delete => EventExec::event_delete(status),
            ActionMap::DeleteFile => EventExec::event_delete_file(status),
            ActionMap::Diff => EventExec::event_diff(status),
            ActionMap::ToggleDisplayFull => EventExec::event_toggle_display_full(status),
            ActionMap::DragNDrop => EventExec::event_drag_n_drop(status),
            ActionMap::EncryptedDrive => EventExec::event_encrypted_drive(status),
            ActionMap::End => EventExec::event_end(status, colors),
            ActionMap::Enter => EventExec::event_enter(status, colors),
            ActionMap::Exec => EventExec::event_exec(current_tab),
            ActionMap::Filter => EventExec::event_filter(current_tab),
            ActionMap::FlagAll => EventExec::event_flag_all(status),
            ActionMap::FuzzyFind => EventExec::event_fuzzyfind(status),
            ActionMap::FuzzyFindLine => EventExec::event_fuzzyfind_line(status),
            ActionMap::FuzzyFindHelp => EventExec::event_fuzzyfind_help(status),
            ActionMap::Goto => EventExec::event_goto(current_tab),
            ActionMap::Help => EventExec::event_help(status),
            ActionMap::Log => EventExec::event_log(current_tab),
            ActionMap::History => EventExec::event_history(current_tab),
            ActionMap::Home => EventExec::event_home(current_tab),
            ActionMap::MocpAddToPlayList => EventExec::event_mocp_add_to_playlist(current_tab),
            ActionMap::MocpGoToSong => EventExec::event_mocp_go_to_song(current_tab),
            ActionMap::MocpTogglePause => EventExec::event_mocp_toggle_pause(status),
            ActionMap::MocpNext => EventExec::event_mocp_next(),
            ActionMap::MocpPrevious => EventExec::event_mocp_previous(),
            ActionMap::Jump => EventExec::event_jump(status),
            ActionMap::KeyHome => EventExec::event_key_home(status, colors),
            ActionMap::MarksJump => EventExec::event_marks_jump(status),
            ActionMap::MarksNew => EventExec::event_marks_new(current_tab),
            ActionMap::ModeNormal => EventExec::event_reset_mode(current_tab),
            ActionMap::MoveDown => EventExec::event_move_down(status, colors),
            ActionMap::MoveLeft => EventExec::event_move_left(status, colors),
            ActionMap::MoveRight => EventExec::event_move_right(status, colors),
            ActionMap::MoveUp => EventExec::event_move_up(status, colors),
            ActionMap::NewDir => EventExec::event_new_dir(current_tab),
            ActionMap::NewFile => EventExec::event_new_file(current_tab),
            ActionMap::NvimFilepicker => EventExec::event_nvim_filepicker(status),
            ActionMap::NvimSetAddress => EventExec::event_set_nvim_server(status),
            ActionMap::OpenFile => EventExec::event_open_file(status),
            ActionMap::PageDown => EventExec::event_page_down(status, colors),
            ActionMap::PageUp => EventExec::event_page_up(status, colors),
            ActionMap::Preview => EventExec::event_preview(status, colors),
            ActionMap::Quit => EventExec::event_quit(current_tab),
            ActionMap::RefreshView => EventExec::event_refreshview(status, colors),
            ActionMap::RegexMatch => EventExec::event_regex_match(current_tab),
            ActionMap::Rename => EventExec::event_rename(current_tab),
            ActionMap::ReverseFlags => EventExec::event_reverse_flags(status),
            ActionMap::Search => EventExec::event_search(current_tab),
            ActionMap::SearchNext => EventExec::event_search_next(current_tab),
            ActionMap::SetWallpaper => EventExec::event_set_wallpaper(current_tab),
            ActionMap::Shell => EventExec::event_shell(status),
            ActionMap::ShellMenu => EventExec::event_shell_menu(current_tab),
            ActionMap::Shortcut => EventExec::event_shortcut(current_tab),
            ActionMap::Sort => EventExec::event_sort(current_tab),
            ActionMap::Symlink => EventExec::event_symlink(status),
            ActionMap::Tab => EventExec::event_tab(status),
            ActionMap::MediaInfo => EventExec::event_mediainfo(current_tab),
            ActionMap::ToggleDualPane => EventExec::event_toggle_dualpane(status),
            ActionMap::ToggleFlag => EventExec::event_toggle_flag(status),
            ActionMap::ToggleHidden => EventExec::event_toggle_hidden(status, colors),
            ActionMap::TogglePreviewSecond => EventExec::event_toggle_preview_second(status),
            ActionMap::TrashMoveFile => EventExec::event_trash_move_file(status),
            ActionMap::TrashRestoreFile => EventExec::event_trash_restore_file(status),
            ActionMap::TrashEmpty => EventExec::event_trash_empty(status),
            ActionMap::TrashOpen => EventExec::event_trash_open(status),
            ActionMap::Tree => EventExec::event_tree(status, colors),
            ActionMap::TreeFold => EventExec::event_tree_fold(current_tab, colors),
            ActionMap::TreeFoldAll => EventExec::event_tree_fold_all(current_tab, colors),
            ActionMap::TreeUnFoldAll => EventExec::event_tree_unfold_all(current_tab, colors),
            ActionMap::OpenConfig => EventExec::event_open_config(status),

            ActionMap::Nothing => Ok(()),
        }
    }
}
