#pragma once

namespace lumacs {

constexpr const char* LUA_DEFAULTS = R"(
-- =========================================================
-- Lumacs Embedded Defaults
-- =========================================================
-- This runs BEFORE the user's init.lua.
-- It establishes the core editing environment.

-- 1. Sane Editor Config
editor.config:set("show_line_numbers", true)
editor.config:set("tab_width", 4)

-- 2. Mode Infrastructure
local major_modes = {}
local minor_modes = {}
local buffer_major_modes = {}
local buffer_minor_modes = {}

function define_major_mode(name, config)
    major_modes[name] = {
        name = name,
        file_patterns = config.file_patterns or {},
        setup = config.setup or function() end,
        cleanup = config.cleanup or function() end,
        highlight = config.highlight or nil,
        keybindings = config.keybindings or {},
        comment_syntax = config.comment_syntax or "--",
    }
end

function define_minor_mode(name, config)
    minor_modes[name] = {
        name = name,
        setup = config.setup or function() end,
        cleanup = config.cleanup or function() end,
        keybindings = config.keybindings or {},
        global = config.global or false,
    }
end

function activate_major_mode(mode_name)
    local buf = editor.buffer
    local buf_name = buf:name()
    local mode = major_modes[mode_name]
    if not mode then return false end
    
    buffer_major_modes[buf_name] = mode_name
    
    if mode.highlight then
        buf:on_buffer_event(function(event_data)
            if event_data.event == lumacs.BufferEvent.Loaded or
               event_data.event == lumacs.BufferEvent.LanguageChanged then
                mode.highlight()
            end
        end)
        mode.highlight()
    end
    
    -- Register mode-specific keybindings
    -- Note: This is a simple implementation that binds globally for now.
    -- A proper implementation would use a keymap stack.
    for key, func in pairs(mode.keybindings) do
        editor:bind_key(key, func)
    end
    
    mode.setup()
    return true
end

function current_major_mode()
    local buf = editor.buffer
    local buf_name = buf:name()
    return buffer_major_modes[buf_name] or "fundamental-mode"
end

define_major_mode("fundamental-mode", {})

function auto_activate_major_mode()
    local buf = editor.buffer
    local buf_name = buf:name()
    for mode_name, mode in pairs(major_modes) do
        for _, pattern in ipairs(mode.file_patterns) do
            if string.match(buf_name, pattern) then
                activate_major_mode(mode_name)
                return
            end
        end
    end
    activate_major_mode("fundamental-mode")
end

-- 3. Basic Editing Commands & Registration

-- Navigation
editor:register_command("next-line", "Move cursor down", function() editor:move_down() end, true)
editor:register_command("previous-line", "Move cursor up", function() editor:move_up() end, true)
editor:register_command("forward-char", "Move cursor right", function() editor:move_right() end, true)
editor:register_command("backward-char", "Move cursor left", function() editor:move_left() end, true)
editor:register_command("forward-word", "Move forward one word", function() editor:move_forward_word() end, true)
editor:register_command("backward-word", "Move backward one word", function() editor:move_backward_word() end, true)
editor:register_command("move-beginning-of-line", "Go to beginning of line", function() editor:move_to_line_start() end, true)
editor:register_command("move-end-of-line", "Go to end of line", function() editor:move_to_line_end() end, true)
editor:register_command("beginning-of-buffer", "Go to beginning of buffer", function() editor:goto_beginning() end, true)
editor:register_command("end-of-buffer", "Go to end of buffer", function() editor:goto_end() end, true)
editor:register_command("scroll-up-command", "Page down", function() editor:page_down() end, true)
editor:register_command("scroll-down-command", "Page up", function() editor:page_up() end, true)

-- Insertion / Deletion
function lumacs_insert_newline()
    local cursor = editor.cursor
    editor.buffer:insert_newline(cursor)
    -- Move to start of next line
    editor.cursor = lumacs.Position(cursor.line + 1, 0)
end
editor:register_command("insert-newline", "Insert newline", lumacs_insert_newline, true)

function lumacs_backward_delete_char()
    local cursor = editor.cursor
    if cursor.line == 0 and cursor.column == 0 then return end
    
    editor.buffer:erase_char(cursor)
    
    -- Calculate new cursor position
    local new_pos = cursor
    if new_pos.column > 0 then 
        new_pos = lumacs.Position(new_pos.line, new_pos.column - 1)
    elseif new_pos.line > 0 then
        local prev_line_len = #editor.buffer:line(new_pos.line - 1)
        new_pos = lumacs.Position(new_pos.line - 1, prev_line_len)
    end
    editor.cursor = new_pos
end
editor:register_command("backward-delete-char", "Delete char backward", lumacs_backward_delete_char, true)

function lumacs_delete_char()
    local cursor = editor.cursor
    editor.buffer:erase_char(lumacs.Position(cursor.line, cursor.column + 1))
end
editor:register_command("delete-char", "Delete char forward", lumacs_delete_char, true)

function self_insert_command(args)
    local char_to_insert = args[1]
    if not char_to_insert then return end
    editor.buffer:insert(editor.cursor, char_to_insert)
    editor:move_right()
end
editor:register_command("self-insert-command", "Insert char", self_insert_command, true)

-- Clipboard / Kill Ring
editor:register_command("kill-line", "Kill rest of line", function() editor:kill_line() end, true)
editor:register_command("kill-region", "Kill selected region", function() editor:kill_region() end, true)
editor:register_command("copy-region-as-kill", "Copy region", function() editor:copy_region_as_kill() end, true)
editor:register_command("yank", "Paste", function() editor:yank() end, true)
editor:register_command("yank-pop", "Cycle paste", function() editor:yank_pop() end, true)

-- Undo/Redo
editor:register_command("undo", "Undo", function() editor:undo() end, true)
editor:register_command("redo", "Redo", function() editor:redo() end, true)

-- File/Buffer
editor:register_command("save-buffer", "Save current buffer", function() 
    if editor.buffer:save() then editor:message("Saved") else editor:message("Failed to save") end 
end, true)
editor:register_command("find-file", "Open file", function() editor:find_file_mode() end, true, "f")
editor:register_command("switch-buffer", "Switch buffer", function() editor:buffer_switch_mode() end, true, "b")
editor:register_command("kill-buffer", "Kill buffer", function() editor:kill_buffer_mode() end, true, "b")
editor:register_command("save-buffers-kill-terminal", "Quit", function() editor:quit() end, true)
editor:register_command("execute-extended-command", "M-x", function() editor:command_mode() end, true)

-- Macros
editor:register_command("start-kbd-macro", "Start recording macro", function() editor:start_kbd_macro() end, true)
editor:register_command("end-kbd-macro-or-call", "End recording or call macro", function() editor:end_kbd_macro_or_call() end, true)

-- 4. Default Keybindings
editor:bind_key("Return", "insert-newline")
editor:bind_key("Backspace", "backward-delete-char")
editor:bind_key("Delete", "delete-char")

-- Arrow Keys
editor:bind_key("ArrowUp", "previous-line")
editor:bind_key("ArrowDown", "next-line")
editor:bind_key("ArrowLeft", "backward-char")
editor:bind_key("ArrowRight", "forward-char")

-- Emacs Navigation
editor:bind_key("C-f", "forward-char")
editor:bind_key("C-b", "backward-char")
editor:bind_key("C-n", "next-line")
editor:bind_key("C-p", "previous-line")
editor:bind_key("C-a", "move-beginning-of-line")
editor:bind_key("C-e", "move-end-of-line")
editor:bind_key("M-f", "forward-word")
editor:bind_key("M-b", "backward-word")
editor:bind_key("M-<", "beginning-of-buffer")
editor:bind_key("M->", "end-of-buffer")
editor:bind_key("C-v", "scroll-up-command")
editor:bind_key("M-v", "scroll-down-command")

-- File & Window Ops
editor:bind_key("C-x C-c", "save-buffers-kill-terminal")
editor:bind_key("C-x C-s", "save-buffer")
editor:bind_key("C-x C-f", "find-file")
editor:bind_key("C-x b", "switch-buffer")
editor:bind_key("C-x k", "kill-buffer")
editor:bind_key("C-x 0", "delete-window") -- Need to implement
editor:bind_key("C-x 1", "delete-other-windows") -- Need to implement
editor:bind_key("C-x 2", "split-window-below") -- Need to implement
editor:bind_key("C-x 3", "split-window-right") -- Need to implement
editor:bind_key("C-x o", "other-window") -- Need to implement
editor:bind_key("M-x", "execute-extended-command")

-- Windows Implementation
editor:register_command("delete-window", "Close window", function() editor:close_window() end, true)
editor:register_command("split-window-below", "Split horizontal", function() editor:split_horizontally() end, true)
editor:register_command("split-window-right", "Split vertical", function() editor:split_vertically() end, true)
editor:register_command("other-window", "Next window", function() editor:next_window() end, true)

-- Undo/Redo
editor:bind_key("C-/", "undo")
editor:bind_key("C-_", "undo")
editor:bind_key("C-x u", "redo")

-- Mark & Kill Ring
editor:bind_key("C-@", function() editor.buffer:set_mark(editor.cursor) editor:message("Mark set") end)
editor:bind_key("C-w", "kill-region")
editor:bind_key("M-w", "copy-region-as-kill")
editor:bind_key("C-y", "yank")
editor:bind_key("M-y", "yank-pop")
editor:bind_key("C-k", "kill-line")

-- Macros
editor:bind_key("F3", "start-kbd-macro")
editor:bind_key("F4", "end-kbd-macro-or-call")

-- Auto-activate mode
auto_activate_major_mode()
)";

} // namespace lumacs