-- Pull in the wezterm API
local wezterm = require("wezterm")

-- This will hold the configuration.
local config = wezterm.config_builder()

-- Wezterm plugins

local sessionizer = require("plugins/sessionizer")
local tabline = require("plugins/tabline")
local smart_splits = require("plugins/smart_splits")

-- This will hold the actions

local actions = wezterm.action

-- TMUX config

-- Leader key like in TMUX

config.leader = { key = "a", mods = "CTRL", timeout_milliseconds = 1000 }

-- unix socket to enable sessions

config.unix_domains = {
	{
		name = "unix",
	},
}

-- general keybindings

config.keys = {
	{
		key = "p",
		mods = "CTRL",
		action = wezterm.action.ShowDebugOverlay,
	},
	{
		-- sessionizer
		key = "s",
		mods = "LEADER|SHIFT",
		action = actions.PromptInputLine({
			description = wezterm.format({
				{ Attribute = { Intensity = "Bold" } },
				{ Foreground = { AnsiColor = "Fuchsia" } },
				{ Text = "Enter name for new workspace" },
			}),
			action = wezterm.action_callback(function(window, pane, line)
				if line then
					window:perform_action(
						actions.SwitchToWorkspace({
							name = line,
						}),
						pane
					)
				end
			end),
		}),
	},
	{
		-- Maximize Pane
		key = "m",
		mods = "LEADER",
		action = actions.TogglePaneZoomState,
	},
	-- Split Panes
	{
		key = "-",
		mods = "LEADER",
		action = actions.SplitVertical,
	},
	{
		key = "|",
		mods = "LEADER",
		action = actions.SplitHorizontal,
	},
	-- Rename Session or Tab
	{
		key = ",",
		mods = "LEADER",
		action = wezterm.action.PromptInputLine({
			description = "Enter new workspace name",
			action = wezterm.action_callback(function(window, pane, line)
				if line and line ~= "" then
					window:set_workspace(line)
					wezterm.notify("Workspace renamed to: " .. line, "WezTerm", { urgency = "normal" })
				else
					wezterm.notify("Workspace rename cancelled", "WezTerm", { urgency = "normal" })
				end
			end),
		}),
	},
	{
		key = ".",
		mods = "LEADER",
		action = wezterm.action.PromptInputLine({
			description = "Enter new tab title",
			action = wezterm.action_callback(function(window, pane, line)
				if line and line ~= "" then
					pane:tab():set_title(line)
					wezterm.notify("Tab renamed to: " .. line, "WezTerm", { urgency = "normal" })
				else
					wezterm.notify("Tab rename cancelled", "WezTerm", { urgency = "normal" })
				end
			end),
		}),
	},
	-- Create and Kill Tab
	{
		key = "c",
		mods = "LEADER",
		action = actions.SpawnCommandInNewTab,
	},
	{
		key = "x",
		mods = "LEADER",
		action = wezterm.action_callback(function(window, pane)
			local tab = pane:tab()
			if tab then
				local pane_count = #tab:panes()
				if pane_count > 1 then
					window:perform_action(wezterm.action.CloseCurrentPane({ confirm = false }), pane)
				else
					window:perform_action(wezterm.action.CloseCurrentTab({ confirm = false }), pane)
				end
			else
				wezterm.notify("No tab found, cannot close", "WezTerm", { urgency = "normal" })
			end
		end),
	},
	-- Move Tab to index
	{
		key = "/",
		mods = "LEADER",
		action = wezterm.action.PromptInputLine({
			description = "Move Tab to Index",
			action = wezterm.action_callback(function(window, pane, line)
				if not line or line == "" then
					wezterm.notify("Tab move cancelled", "WezTerm", { urgency = "normal" })
					return
				end
				local index = tonumber(line)
				if not index then
					wezterm.notify("Invalid index: must be a number", "WezTerm", { urgency = "normal" })
					return
				end
				-- Convert 1-based user input to 0-based index
				index = index - 1
				local tab_count = #window:mux_window():tabs()
				if index < 0 or index >= tab_count then
					wezterm.notify(
						"Invalid index: must be between 1 and " .. tab_count,
						"WezTerm",
						{ urgency = "normal" }
					)
					return
				end
				window:perform_action(wezterm.action.MoveTab(index), pane)
				wezterm.notify("Tab moved to index: " .. (index + 1), "WezTerm", { urgency = "normal" })
			end),
		}),
	},
	-- Move to next and previous Tab
	{
		key = "n",
		mods = "LEADER",
		action = actions.ActivateTabRelative(1),
	},
	{
		key = "p",
		mods = "LEADER",
		action = actions.ActivateTabRelative(-1),
	},
	-- Vim Mode
	{
		key = "]",
		mods = "LEADER",
		action = actions.ActivateCopyMode,
	},
}

-- Go to Tab with index

for i = 1, 8 do
	-- LEADER + number to move to that position
	table.insert(config.keys, {
		key = tostring(i),
		mods = "LEADER",
		action = actions.ActivateTab(i - 1),
	})
end

-- This causes `wezterm` to act as though it was started as
-- `wezterm connect unix` by default, connecting to the unix
-- domain on startup.
-- If you prefer to connect manually, leave out this line.
config.default_gui_startup_args = { "connect", "unix" }

-- Tabline plugin

tabline.apply_to_config(config)

-- Append keys from plugins

for _, key in ipairs(sessionizer.keys) do
	table.insert(config.keys, key)
end

for _, key in ipairs(smart_splits.keys) do
	table.insert(config.keys, key)
end

-- Font Config

config.font = wezterm.font({
	family = "JetBrainsMono Nerd Font",
	assume_emoji_presentation = false,
})
config.font_size = 13

-- Color Scheme

config.color_scheme = "Catppuccin Macchiato"

-- Window Config

config.window_decorations = "RESIZE"
config.use_fancy_tab_bar = false

--Key Config

config.send_composed_key_when_left_alt_is_pressed = true

--Variables

config.set_environment_variables = {
	PATH = os.getenv("PATH"),
}

return config
