local wezterm = require("wezterm") --[[@as Wezterm]]
local util = require("util")
local act = wezterm.action

-- We override the key bindings here, so as to explicitly define what they are rather than relying on default values.
local keys = {
    -- Tab Management
    { key = "T",          mods = "SHIFT|CTRL", action = act.SpawnTab "CurrentPaneDomain" },
    {
        key = "T",
        mods = "SHIFT|ALT",
        action = act.PromptInputLine {
            description = 'Enter new name for tab',
            action = wezterm.action_callback(function(window, _, line)
                if line then
                    window:active_tab():set_title(line)
                end
            end)
        }
    },
    { key = "W",          mods = "SHIFT|CTRL", action = act.CloseCurrentTab { confirm = true } },
    { key = "LeftArrow",  mods = "ALT",        action = act.ActivateTabRelative(-1) },
    { key = "LeftArrow",  mods = "SHIFT|ALT",  action = act.MoveTabRelative(-1) },
    { key = "RightArrow", mods = "ALT",        action = act.ActivateTabRelative(1) },
    { key = "RightArrow", mods = "SHIFT|ALT",  action = act.MoveTabRelative(1) },
    -- Pane Management
    { key = "-",          mods = "CTRL|ALT",   action = act.SplitVertical { domain = "CurrentPaneDomain" } },
    { key = "\\",         mods = "CTRL|ALT",   action = act.SplitHorizontal { domain = "CurrentPaneDomain" } },
    { key = "LeftArrow",  mods = "CTRL",       action = act.ActivatePaneDirection "Left" },
    { key = "LeftArrow",  mods = "CTRL|SHIFT", action = act.AdjustPaneSize { "Left", 1 } },
    { key = "RightArrow", mods = "CTRL",       action = act.ActivatePaneDirection "Right" },
    { key = "RightArrow", mods = "CTRL|SHIFT", action = act.AdjustPaneSize { "Right", 1 } },
    { key = "UpArrow",    mods = "CTRL",       action = act.ActivatePaneDirection "Up" },
    { key = "UpArrow",    mods = "CTRL|SHIFT", action = act.AdjustPaneSize { "Up", 1 } },
    { key = "DownArrow",  mods = "CTRL",       action = act.ActivatePaneDirection "Down" },
    { key = "DownArrow",  mods = "CTRL|SHIFT", action = act.AdjustPaneSize { "Down", 1 } },
    -- Default Actions
    { key = "_",          mods = "SHIFT|CTRL", action = act.DecreaseFontSize },
    { key = "+",          mods = "SHIFT|CTRL", action = act.IncreaseFontSize },
    { key = "C",          mods = "SHIFT|CTRL", action = act.CopyTo "Clipboard" },
    { key = "F",          mods = "SHIFT|CTRL", action = act.Search "CurrentSelectionOrEmptyString" },
    { key = "K",          mods = "SHIFT|CTRL", action = act.ClearScrollback "ScrollbackOnly" },
    { key = "L",          mods = "SHIFT|CTRL", action = act.ShowDebugOverlay },
    { key = "R",          mods = "SHIFT|CTRL", action = act.ReloadConfiguration },
    { key = "V",          mods = "SHIFT|CTRL", action = act.PasteFrom "Clipboard" },
    { key = "X",          mods = "SHIFT|CTRL", action = act.ActivateCopyMode },
    { key = "Z",          mods = "SHIFT|CTRL", action = act.TogglePaneZoomState },
    { key = "phys:Space", mods = "SHIFT|CTRL", action = act.QuickSelect },
    { key = "PageUp",     mods = "SHIFT",      action = act.ScrollByPage(-1) },
    { key = "PageDown",   mods = "SHIFT",      action = act.ScrollByPage(1) },
    { key = "Insert",     mods = "SHIFT",      action = act.PasteFrom "PrimarySelection" },
    { key = "Insert",     mods = "CTRL",       action = act.CopyTo "PrimarySelection" },
    { key = "Copy",       mods = "NONE",       action = act.CopyTo "Clipboard" },
    { key = "Paste",      mods = "NONE",       action = act.PasteFrom "Clipboard" },
    -- Other
    { key = "G",          mods = "SHIFT|CTRL", action = wezterm.action_callback(util.open_last_output_in_less) },
}

local key_tables = {
    copy_mode = {
        { key = "Tab",        mods = "NONE",  action = act.CopyMode "MoveForwardWord" },
        { key = "Tab",        mods = "SHIFT", action = act.CopyMode "MoveBackwardWord" },
        { key = "Enter",      mods = "NONE",  action = act.CopyMode "MoveToStartOfNextLine" },
        { key = "Escape",     mods = "NONE",  action = act.CopyMode "Close" },
        { key = "Space",      mods = "NONE",  action = act.CopyMode { SetSelectionMode = "Cell" } },
        { key = "$",          mods = "NONE",  action = act.CopyMode "MoveToEndOfLineContent" },
        { key = "$",          mods = "SHIFT", action = act.CopyMode "MoveToEndOfLineContent" },
        { key = "0",          mods = "NONE",  action = act.CopyMode "MoveToStartOfLine" },
        { key = "G",          mods = "NONE",  action = act.CopyMode "MoveToScrollbackBottom" },
        { key = "G",          mods = "SHIFT", action = act.CopyMode "MoveToScrollbackBottom" },
        { key = "H",          mods = "NONE",  action = act.CopyMode "MoveToViewportTop" },
        { key = "H",          mods = "SHIFT", action = act.CopyMode "MoveToViewportTop" },
        { key = "L",          mods = "NONE",  action = act.CopyMode "MoveToViewportBottom" },
        { key = "L",          mods = "SHIFT", action = act.CopyMode "MoveToViewportBottom" },
        { key = "M",          mods = "NONE",  action = act.CopyMode "MoveToViewportMiddle" },
        { key = "M",          mods = "SHIFT", action = act.CopyMode "MoveToViewportMiddle" },
        { key = "O",          mods = "NONE",  action = act.CopyMode "MoveToSelectionOtherEndHoriz" },
        { key = "O",          mods = "SHIFT", action = act.CopyMode "MoveToSelectionOtherEndHoriz" },
        { key = "V",          mods = "NONE",  action = act.CopyMode { SetSelectionMode = "Line" } },
        { key = "V",          mods = "SHIFT", action = act.CopyMode { SetSelectionMode = "Line" } },
        { key = "^",          mods = "NONE",  action = act.CopyMode "MoveToStartOfLineContent" },
        { key = "^",          mods = "SHIFT", action = act.CopyMode "MoveToStartOfLineContent" },
        { key = "b",          mods = "NONE",  action = act.CopyMode "MoveBackwardWord" },
        { key = "b",          mods = "ALT",   action = act.CopyMode "MoveBackwardWord" },
        { key = "b",          mods = "CTRL",  action = act.CopyMode "PageUp" },
        { key = "c",          mods = "CTRL",  action = act.CopyMode "Close" },
        { key = "f",          mods = "ALT",   action = act.CopyMode "MoveForwardWord" },
        { key = "f",          mods = "CTRL",  action = act.CopyMode "PageDown" },
        { key = "g",          mods = "NONE",  action = act.CopyMode "MoveToScrollbackTop" },
        { key = "g",          mods = "CTRL",  action = act.CopyMode "Close" },
        { key = "h",          mods = "NONE",  action = act.CopyMode "MoveLeft" },
        { key = "j",          mods = "NONE",  action = act.CopyMode "MoveDown" },
        { key = "k",          mods = "NONE",  action = act.CopyMode "MoveUp" },
        { key = "l",          mods = "NONE",  action = act.CopyMode "MoveRight" },
        { key = "m",          mods = "ALT",   action = act.CopyMode "MoveToStartOfLineContent" },
        { key = "o",          mods = "NONE",  action = act.CopyMode "MoveToSelectionOtherEnd" },
        { key = "q",          mods = "NONE",  action = act.CopyMode "Close" },
        { key = "v",          mods = "NONE",  action = act.CopyMode { SetSelectionMode = "Cell" } },
        { key = "v",          mods = "CTRL",  action = act.CopyMode { SetSelectionMode = "Block" } },
        { key = "w",          mods = "NONE",  action = act.CopyMode "MoveForwardWord" },
        { key = "y",          mods = "NONE",  action = act.Multiple { { CopyTo = "ClipboardAndPrimarySelection" }, { CopyMode = "Close" } } },
        { key = "PageUp",     mods = "NONE",  action = act.CopyMode "PageUp" },
        { key = "PageDown",   mods = "NONE",  action = act.CopyMode "PageDown" },
        { key = "LeftArrow",  mods = "NONE",  action = act.CopyMode "MoveLeft" },
        { key = "LeftArrow",  mods = "ALT",   action = act.CopyMode "MoveBackwardWord" },
        { key = "RightArrow", mods = "NONE",  action = act.CopyMode "MoveRight" },
        { key = "RightArrow", mods = "ALT",   action = act.CopyMode "MoveForwardWord" },
        { key = "UpArrow",    mods = "NONE",  action = act.CopyMode "MoveUp" },
        { key = "DownArrow",  mods = "NONE",  action = act.CopyMode "MoveDown" },
    },

    search_mode = {
        { key = "Enter",     mods = "NONE", action = act.CopyMode "PriorMatch" },
        { key = "Escape",    mods = "NONE", action = act.CopyMode "Close" },
        { key = "n",         mods = "CTRL", action = act.CopyMode "NextMatch" },
        { key = "p",         mods = "CTRL", action = act.CopyMode "PriorMatch" },
        { key = "r",         mods = "CTRL", action = act.CopyMode "CycleMatchType" },
        { key = "u",         mods = "CTRL", action = act.CopyMode "ClearPattern" },
        { key = "PageUp",    mods = "NONE", action = act.CopyMode "PriorMatchPage" },
        { key = "PageDown",  mods = "NONE", action = act.CopyMode "NextMatchPage" },
        { key = "UpArrow",   mods = "NONE", action = act.CopyMode "PriorMatch" },
        { key = "DownArrow", mods = "NONE", action = act.CopyMode "NextMatch" },
    }
}

-- We also override the default mouse bindings, and the reasons are as follows:
-- 1) The default bindings often clobber the system clipboard, which I don't want, and
-- 2) Some of the default bindings are frivolous and unnecessary
local mouse_bindings = {
    -- Left mouse button click
    {
        event = { Down = { streak = 1, button = "Left" } },
        action = act.SelectTextAtMouseCursor("Cell"),
        mods = "NONE"
    },
    {
        event = { Up = { streak = 1, button = "Left" } },
        action = act.CompleteSelectionOrOpenLinkAtMouseCursor("PrimarySelection"),
        mods = "NONE"
    },
    -- Middle mouse button click
    {
        event = { Down = { streak = 1, button = "Middle" } },
        action = act.PasteFrom("PrimarySelection"),
        mods = "NONE"
    },
    {
        event = { Down = { streak = 1, button = "Middle" } },
        action = act.PasteFrom("Clipboard"),
        mods = "ALT"
    },
    -- Right mouse button click
    {
        event = { Down = { streak = 1, button = "Right" } },
        action = act.SelectTextAtMouseCursor("SemanticZone"),
        mods = "CTRL|SHIFT"
    },
    -- Left mouse button drag
    {
        event = { Drag = { streak = 1, button = "Left" } },
        action = act.ExtendSelectionToMouseCursor("Cell"),
        mods = "NONE"
    },
    {
        event = { Drag = { streak = 1, button = "Left" } },
        action = act.StartWindowDrag,
        mods = "SUPER"
    }
}

local config = {}
config.keys = keys
config.disable_default_key_bindings = true
config.disable_default_mouse_bindings = true
config.key_tables = key_tables
config.mouse_bindings = mouse_bindings

return config
