-- Lumacs User Configuration File
-- ============================================================================
-- This file runs AFTER defaults.hpp, allowing you to customize and extend
-- the default Emacs-like behavior. The mode system, keybindings, and commands
-- are already set up - use this file to:
--   1. Load additional major modes
--   2. Load themes
--   3. Add custom keybindings
--   4. Define custom commands
--   5. Override default settings
-- ============================================================================

-- ============================================================================
-- PACKAGE SYSTEM INITIALIZATION
-- ============================================================================

-- Add lua/ to package path for require() to work
package.path = package.path .. ";lua/?.lua;lua/?/init.lua"

-- Load the package manager
local pkg = dofile("lua/core/package.lua")
pkg.setup()

-- Make it globally accessible
lumacs.package = pkg

-- Load package commands (M-x package-install, etc.)
dofile("lua/core/package-commands.lua")

-- Load user packages from ~/.lumacs/packages.lua
local loaded, errors = pkg.load_all()
if loaded > 0 or errors > 0 then
    print(string.format("[package] Loaded %d user packages (%d errors)", loaded, errors))
end

-- ============================================================================
-- LOAD MAJOR MODES
-- ============================================================================

-- Load individual major mode definitions
dofile("lua/major_modes/lua_mode.lua")
dofile("lua/major_modes/c_cpp_mode.lua")

-- ============================================================================
-- LOAD THEMES
-- ============================================================================

-- Load individual theme definitions
dofile("lua/themes/default.lua")
dofile("lua/themes/dracula.lua")
dofile("lua/themes/everforest-dark.lua")
dofile("lua/themes/gruvbox-light.lua")
dofile("lua/themes/nord.lua")
dofile("lua/themes/solarized-dark.lua")
dofile("lua/themes/catppuccin-mocha.lua")
dofile("lua/themes/tokyo-night.lua")
dofile("lua/themes/ayu-dark.lua")

-- Load theme switching functions and keybindings
dofile("lua/themes/themes_init.lua")

-- ============================================================================
-- LOAD PACKAGES
-- ============================================================================

-- which-key: Display available keybindings for prefix keys
dofile("lua/packages/which-key.lua")

-- doom-modeline: Doom Emacs-style modeline customization
dofile("lua/packages/doom-modeline.lua")

-- smartparens: Auto-pairing of brackets, quotes, etc.
dofile("lua/packages/smartparens.lua")

-- rainbow-delimiters: Colorize nested delimiters by depth
dofile("lua/packages/rainbow-delimiters.lua")

-- ido: Enhanced fuzzy completion (optional, provides utilities)
dofile("lua/packages/ido.lua")

-- projectile: Project management and navigation
dofile("lua/packages/projectile.lua")

-- company: Text completion framework
dofile("lua/packages/company.lua")

-- goto-line: Go to a specific line number (M-g g)
dofile("lua/packages/goto-line.lua")

-- recentf: Track and access recently opened files
dofile("lua/packages/recentf.lua")

-- bookmarks: Save and jump between named positions
dofile("lua/packages/bookmarks.lua")

-- visual-line: Soft word wrap mode
dofile("lua/packages/visual-line.lua")

-- ============================================================================
-- MINOR MODES (User-defined extensions)
-- ============================================================================

-- Auto-save minor mode
lumacs.define_minor_mode("auto-save-mode", {
    global = false,
    setup = function()
        editor:message("[auto-save-mode] Auto-save enabled")
    end,
    cleanup = function()
        editor:message("[auto-save-mode] Auto-save disabled")
    end
})

-- Line numbers minor mode (toggle control)
lumacs.define_minor_mode("line-numbers-mode", {
    global = true,
    setup = function()
        editor.config:set("show_line_numbers", true)
        editor:message("[line-numbers-mode] Line numbers enabled")
    end,
    cleanup = function()
        editor.config:set("show_line_numbers", false)
        editor:message("[line-numbers-mode] Line numbers disabled")
    end
})

-- ============================================================================
-- CUSTOM KEYBINDINGS (User overrides)
-- ============================================================================

-- Example: Custom keybinding for inserting timestamp
editor:bind_key("C-c t", function()
    local cursor_pos = editor.cursor
    local timestamp = os.date("%Y-%m-%d %H:%M:%S")
    editor.buffer:insert(cursor_pos, timestamp)
    editor:message("Inserted timestamp")
end)

-- Example: Find TODO comments in buffer
editor:bind_key("C-c o", function()
    local buf = editor.buffer
    local cursor = editor.cursor
    local search_start = lumacs.Position(cursor.line, cursor.column + 1)
    local res = buf:find("TODO", search_start)
    if res then
        editor.cursor = res.start
        editor:message("Found TODO at " .. res.start.line .. ":" .. res.start.column)
    else
        editor:message("No more TODOs found")
    end
end)

-- Line swapping (like VS Code Alt+Up/Down)
local function swap_line_up()
    local buf = editor.buffer
    local cursor = editor.cursor
    if cursor.line == 0 then
        editor:message("Already at first line")
        return
    end
    local current_line = buf:line(cursor.line)
    local above_line = buf:line(cursor.line - 1)
    local delete_start = lumacs.Position(cursor.line - 1, 0)
    local delete_end = lumacs.Position(cursor.line, #current_line)
    buf:erase(lumacs.Range(delete_start, delete_end))
    local text = current_line .. "\n" .. above_line
    buf:insert(lumacs.Position(cursor.line - 1, 0), text)
    editor.cursor = lumacs.Position(cursor.line - 1, cursor.column)
    editor:message("Swapped line up")
end

local function swap_line_down()
    local buf = editor.buffer
    local cursor = editor.cursor
    if cursor.line >= buf:line_count() - 1 then
        editor:message("Already at last line")
        return
    end
    local current_line = buf:line(cursor.line)
    local below_line = buf:line(cursor.line + 1)
    local delete_start = lumacs.Position(cursor.line, 0)
    local delete_end = lumacs.Position(cursor.line + 1, #below_line)
    buf:erase(lumacs.Range(delete_start, delete_end))
    local text = below_line .. "\n" .. current_line
    buf:insert(lumacs.Position(cursor.line, 0), text)
    editor.cursor = lumacs.Position(cursor.line + 1, cursor.column)
    editor:message("Swapped line down")
end

editor:bind_key("M-ArrowUp", swap_line_up)
editor:bind_key("M-ArrowDown", swap_line_down)

-- ============================================================================
-- FONT SIZE COMMANDS
-- ============================================================================

editor:register_command("text-scale-increase", "Increase font size", function(args)
    local current = editor:font_size()
    editor:set_font_size(current + 1)
    return {success = true, message = "Font size: " .. (current + 1)}
end)

editor:register_command("text-scale-decrease", "Decrease font size", function(args)
    local current = editor:font_size()
    editor:set_font_size(current - 1)
    return {success = true, message = "Font size: " .. (current - 1)}
end)

editor:register_command("text-scale-set", "Set font size", function(args)
    if #args == 0 then
        return {success = true, message = "Current font size: " .. editor:font_size()}
    end
    local size = tonumber(args[1])
    if size then
        editor:set_font_size(size)
        return {success = true, message = "Font size set to: " .. size}
    else
        return {success = false, message = "Invalid size: " .. args[1]}
    end
end, {}, true, "s")

-- Emacs-style font size keybindings (C-x C-+ and C-x C-- in Emacs)
editor:bind_key("C-x +", "text-scale-increase", "Increase font size")
editor:bind_key("C-x -", "text-scale-decrease", "Decrease font size")
editor:bind_key("C-x =", "text-scale-set", "Show/set font size")

-- ============================================================================
-- CUSTOM COMMANDS
-- ============================================================================

-- Auto-theme based on time of day
editor:register_command("auto-theme", "Automatically set theme based on time of day", function(args)
    local hour = tonumber(os.date("%H"))
    local theme_name
    if hour >= 6 and hour < 18 then
        theme_name = "gruvbox-light"
    elseif hour >= 18 and hour < 22 then
        theme_name = "everforest-dark"
    else
        theme_name = "nord"
    end
    local success, message = editor:execute_command("set-theme", {theme_name})
    if success then
        return {success = true, message = string.format("Auto-selected %s theme for %d:00", theme_name, hour)}
    else
        return {success = false, message = "Failed to auto-select theme: " .. message}
    end
end, false)

-- Theme demo command
editor:register_command("theme-demo", "Demonstrate theme switching", function(args)
    local themes = {"solarized-dark", "nord", "gruvbox-light", "dracula"}
    local success, message = editor:execute_command("set-theme", {themes[1]})
    if success then
        return {success = true, message = "Theme demo - switched to " .. themes[1]}
    else
        return {success = false, message = "Demo failed: " .. message}
    end
end, false)

-- Evaluate Lua expression
editor:register_command("eval-expression", "Evaluate Lua expression", function(args)
    if #args == 0 then
        return {success = false, message = "Lua expression required"}
    end
    local expr = table.concat(args, " ")
    local func, err = load("return " .. expr)
    if not func then
        return {success = false, message = "Parse error: " .. err}
    end
    local success, result = pcall(func)
    if success then
        return {success = true, message = tostring(result)}
    else
        return {success = false, message = "Error: " .. tostring(result)}
    end
end, true, "s")

-- ============================================================================
-- CONFIGURATION OVERRIDES
-- ============================================================================

-- Uncomment to change defaults:
-- editor.config:set("tab_width", 2)
-- editor.config:set("indent_tabs_mode", true)
-- editor.config:set("scroll_margin", 5)

-- ============================================================================
-- AUTO-ACTIVATE MAJOR MODE
-- ============================================================================

-- This is called after loading to ensure file-specific modes are activated
lumacs.auto_activate_major_mode()

-- Welcome message (override default)
editor:message("Lumacs ready! C-h ? for help, M-x for commands, C-x t for themes")
