require "nvchad.mappings"

local g = vim.g

-- add yours here

local map = vim.keymap.set

map("n", ";", ":", { desc = "CMD enter command mode" })
map("i", "jk", "<ESC>")

-- Transparency toggler
local base46 = require "base46"
vim.keymap.set("n", "<leader>tt", base46.toggle_transparency)

-- Toggle wrap
vim.keymap.set("n", "<leader>tw", function ()
    vim.wo.wrap = not vim.wo.wrap
end)

-- Togle autosave
vim.api.nvim_set_keymap("n", "<leader>ta", ":ASToggle<CR>", { desc = "Autosave Toggle" })

-- Debbuger binds
-- local dap = require "dap"
-- vim.keymap.set("n", "<space>pb", dap.toggle_breakpoint, { desc = "Dap Toggle breakpoint" })
-- vim.keymap.set("n", "<space>gb", dap.run_to_cursor, { desc = "Dap Run to cursor" })
-- vim.keymap.set("n", "<F1>", dap.continue)
-- vim.keymap.set("n", "<F2>", dap.step_into)
-- vim.keymap.set("n", "<F3>", dap.step_over)
-- vim.keymap.set("n", "<F4>", dap.step_out)
-- vim.keymap.set("n", "<F5>", dap.step_back)
-- vim.keymap.set("n", "<F13>", dap.restart)

local dap = require "dap"
vim.keymap.set("n", "<F1>", function()
    vim.cmd('NvimTreeClose')
    dap.continue()
end)
vim.keymap.set("n", "<F2>", dap.step_into, { desc = "Dap Step into" })
vim.keymap.set("n", "<F3>", dap.step_over, { desc = "Dap Step over" })
vim.keymap.set("n", "<F4>", dap.step_out, { desc = "Dap Step out" })
vim.keymap.set("n", "<F5>", dap.step_back, { desc = "Dap Step back" })
vim.keymap.set("n", "<F6>", dap.restart, { desc = "Dap Restart" })
vim.keymap.set("n", "<space>pb", dap.toggle_breakpoint, { desc = "Dap Toggle breakpoint" })
vim.keymap.set("n", "<space>gb", dap.run_to_cursor, { desc = "Dap Run to cursor" })


-- alt+h now conflicts with my hjkl movement keys, so we use alt+b instead
local function toggle_terminal()
    require("nvchad.term").toggle { pos = "sp", id = "htoggleTerm" }
end

-- Git add current file
local function git_add_current_file()
    local filepath = vim.fn.expand("%:p")  -- Get the full path of the current file
    local command = "git add " .. vim.fn.shellescape(filepath)
    local output = vim.fn.system(command)

    if vim.v.shell_error ~= 0 then
        print("Error adding file: " .. output)
    else
        print("Added: " .. filepath)
    end
end

-- Git unstage (reset) current file
local function git_unstage_current_file()
    local filepath = vim.fn.expand("%:p")  -- Get the full path of the current file
    local command = "git reset HEAD -- " .. vim.fn.shellescape(filepath)
    local output = vim.fn.system(command)

    if vim.v.shell_error ~= 0 then
        print("Error unstaging file: " .. output)
    else
        print("Unstaged: " .. filepath)
    end
end

-- Alternative unstage using restore (Git 2.23+)
local function git_unstage_current_file_restore()
    local filepath = vim.fn.expand("%:p")  -- Get the full path of the current file
    local command = "git restore --staged " .. vim.fn.shellescape(filepath)
    local output = vim.fn.system(command)

    if vim.v.shell_error ~= 0 then
        print("Error unstaging file: " .. output)
    else
        print("Unstaged: " .. filepath)
    end
end
map({ "n", "t" }, "<A-b>", toggle_terminal, { desc = "terminal toggleable horizontal term" })
map({ "n", "t" }, "<C-`>", toggle_terminal, { desc = "terminal toggleable horizontal term" })

-- exiting terminal
map("t", "<C-Esc>", "<C-\\><C-N>", { desc = "terminal escape terminal mode" })

-- hop
local hop = require('hop')
local directions = require('hop.hint').HintDirection
vim.keymap.set('', 'f', function()
    hop.hint_char1({ direction = directions.AFTER_CURSOR, current_line_only = true })
end, {remap=true})
vim.keymap.set('', 'F', function()
    hop.hint_char1({ direction = directions.BEFORE_CURSOR, current_line_only = true })
end, {remap=true})
vim.keymap.set('', 't', function()
  hop.hint_char1({ direction = directions.AFTER_CURSOR, current_line_only = true, hint_offset = -1 })
end, {remap=true})
vim.keymap.set('', 'T', function()
  hop.hint_char1({ direction = directions.BEFORE_CURSOR, current_line_only = true, hint_offset = 1 })
end, {remap=true})

-- themes
vim.keymap.set("n", "<leader>tv", function() require('vscode').load('dark') end)

-- lsp
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, { desc = "Lsp Rename" })
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, { desc = "Lsp Code Action" })
vim.keymap.set("n", "<leader>ci", vim.lsp.buf.implementation, { desc = "Lsp Implementation" })

-- load Windsurf
vim.keymap.set("n", "<leader>ws", function () require("windsurf").enabled = true end, { desc = "Windsurf" })

-- cdproj
vim.keymap.set('n', '<leader>cp', '<cmd>CdProject<cr>', { desc = 'Project Switch directory directory' })

-- todocomments
vim.keymap.set("n", "<leader>ft", '<cmd>TodoTelescope<cr>', { desc = "Telescope Todos" })

-- nvimtree refresh
vim.keymap.set("n", "<leader>tr", '<cmd>NvimTreeRefresh<cr>', { desc = "Nvimtree Refresh" })

-- toggle git add current file
vim.keymap.set("n", "<leader>ga", git_add_current_file, { desc = "Git add file" })
vim.keymap.set("n", "<leader>gd", git_unstage_current_file, { desc = "Git unstage file" })
vim.keymap.set("n", "<leader>gr", git_unstage_current_file_restore, { desc = "Git unstage file (restore)" })

-- nvimtree open file without focusing
vim.keymap.set("n", "T",
    function(node)
        local nt_api = require("nvim-tree.api")
        nt_api.node.open.edit(node)
        nt_api.tree.focus()
    end,
    { desc = "Nvimtree Open without focusing" })

-- nvchad tabs
vim.keymap.set("n", "<leader>tn", '<cmd>tabNext<cr>', { desc = "Tab Next" })
vim.keymap.set("n", "<leader>tp", '<cmd>tabprevious<cr>', { desc = "Tab Previous" })
vim.keymap.set("n", "<leader>tm", '<cmd>tabnew<cr>', { desc = "Tab More!" })
vim.keymap.set("n", "<leader>tc", '<cmd>tabclose<cr>', { desc = "Tab Close" })

-- sign file with GPG
vim.keymap.set("n", "<leader>gpg", function()
    local opened_file_path = vim.fn.expand('%:p')
    os.execute("gpg --detach-sign " .. opened_file_path)  -- Execute the GPG sign command
end, { desc = "Sign currently open file with GPG" })

vim.api.nvim_create_autocmd({ "CursorMoved", "WinEnter", "BufEnter" }, {
    callback = function()
        vim.defer_fn(function()
            vim.cmd("redraw!")
        end, 50)
    end,
})

function Leave_snippet()
    if
        ((vim.v.event.old_mode == 's' and vim.v.event.new_mode == 'n') or vim.v.event.old_mode == 'i')
        and require('luasnip').session.current_nodes[vim.api.nvim_get_current_buf()]
        and not require('luasnip').session.jump_active
    then
        require('luasnip').unlink_current()
    end
end

-- stop snippets when you leave to normal mode
vim.api.nvim_command([[
    autocmd ModeChanged * lua Leave_snippet()
]])
