-- lx-bundle:true

--- Core Browser commands and key bindings
-- @module core.browser.commands

local core = require("core")
local browser = require("core.browser")
local command = require("core.command")
local keymap = require("core.keymap")

local view = assert(browser.get_view(), "core Browser must be initialized before its commands")

command.register({
	-- Focuses a visible Browser before a second focused toggle closes it
	["browser:toggle"] = function()
		if view.visible and core.active_view == view then
			view.visible = false

			return view:focus_editor()
		end

		local source_view = core.active_view
		view.visible = true
		view:sync_to_document_view(source_view)

		return view:focus()
	end,
	-- Shows the Browser
	["browser:show"] = function()
		local source_view = core.active_view
		view.visible = true
		view:sync_to_document_view(source_view)

		return view:focus()
	end,
	-- Hides the Browser and returns its focus to the editor
	["browser:hide"] = function()
		view.visible = false

		if core.active_view == view then
			return view:focus_editor()
		end

		return true
	end,
	-- Leaves the Browser visible while returning keyboard input to the editor
	["browser:focus-editor"] = function()
		return view:on_escape()
	end,
	-- Expands the selected directory without toggling an already open directory
	["browser:expand-selected"] = function()
		local _, index = view:ensure_selection()

		if not index or not view.selected_item or view.selected_item.type ~= "dir" then
			return false
		end

		return view:expand_item(view.selected_item)
	end,
	-- Collapses an open folder or selects the closest visible parent row
	["browser:collapse-selected"] = function()
		if not view.visible then
			return false
		end

		return view:collapse_selected()
	end,
	-- Makes the selected directory the root and remembers the current root
	["browser:root-selected"] = function()
		local _, index = view:ensure_selection()

		if not index or not view.selected_item or view.selected_item.type ~= "dir" then
			return false
		end

		return view:set_root(view.selected_item.filename, true)
	end,
	-- Restores the previous explicitly selected Browser root
	["browser:root-back"] = function()
		return view:go_back_root()
	end,
	-- Reveals the active document and remembers an outside tree root for Back
	["browser:reveal-active-document"] = function()
		view.visible = true

		if not view:reveal_active_document() then
			return false
		end

		return view:focus()
	end,
	-- Pins the selected file or toggles the selected directory
	["browser:activate-selected"] = function()
		local _, index = view:ensure_selection()

		if not index or not view.selected_item then
			return false
		end

		if view.selected_item.type == "dir" then
			if view.selected_item.expanded then
				view:collapse_item(view.selected_item)
			else
				view:expand_item(view.selected_item)
			end

			return true
		end

		view:pin_doc_from_browser(view.selected_item.filename)

		return view:focus_editor()
	end,
	-- Selects the previous visible Browser entry
	["browser:select-previous"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection(-1)
	end,
	-- Selects the next visible Browser entry
	["browser:select-next"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection(1)
	end,
	-- Selects the previous page of Browser entries
	["browser:page-up"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection_page(-1)
	end,
	-- Selects the next page of Browser entries
	["browser:page-down"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection_page(1)
	end,
	-- Selects the first Browser entry
	["browser:select-first"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection_edge(false)
	end,
	-- Selects the last Browser entry
	["browser:select-last"] = function()
		if not view.visible then
			return false
		end

		return view:move_selection_edge(true)
	end,
})

-- Keep built-in Browser shortcuts replaceable by user and plugin bindings
keymap.bind("core", {
	global = {
		["f4"] = "browser:toggle",
	},
	browser = {
		["up"] = "browser:select-previous",
		["down"] = "browser:select-next",
		["pageup"] = "browser:page-up",
		["pagedown"] = "browser:page-down",
		["home"] = "browser:select-first",
		["end"] = "browser:select-last",
		["left"] = "browser:collapse-selected",
		["right"] = "browser:expand-selected",
		["return"] = "browser:activate-selected",
		["shift+return"] = "browser:root-selected",
		["backspace"] = "browser:root-back",
		["escape"] = "browser:focus-editor",
	},
})

return true
