-- lx-bundle:true

local core = require("core")

local navigate = {}

-- Jump to a 1-based line/column with bounds validation
-- Returns true on success, or false plus an error string
function navigate.jump_to_line_col(line, col, view, instant)
	view = view or core.active_view
	if not (view and view.doc) then
		return false, "No active document view"
	end

	local doc = view.doc
	if type(line) ~= "number" then
		return false, "Invalid line number"
	end
	line = math.floor(line)
	if line < 1 or line > #doc.lines then
		return false, string.format("Line out of range: %d (1-%d)", line, #doc.lines)
	end

	if col == nil then
		col = 1
	end
	if type(col) ~= "number" then
		return false, "Invalid column number"
	end
	col = math.floor(col)

	local maxcol = #doc.lines[line]
	if line == #doc.lines and doc.lines[line]:sub(-1) ~= "\n" then
		maxcol = maxcol + 1
	end
	if col < 1 or col > maxcol then
		return false, string.format("Column out of range on line %d: %d (1-%d)", line, col, maxcol)
	end

	doc:set_selection(line, col)
	view:scroll_to_line(line, false, instant)
	view:scroll_to_make_visible(line, col)
	return true
end

-- Parses 'line' or 'line:column' user input into numeric coordinates
function navigate.parse_line_col(text)
	local trimmed = text:match("^%s*(.-)%s*$")
	if trimmed == "" then
		return nil, nil, "empty"
	end

	local line, col = trimmed:match("^(%d+)%s*:%s*(%d+)$")
	if line and col then
		return tonumber(line), tonumber(col)
	end

	line = trimmed:match("^(%d+)$")
	if line then
		return tonumber(line), nil
	end

	return nil, nil, "invalid"
end

return navigate
