-- Standalone mappings (migrated from NvChad + custom)

local map = vim.keymap.set

-- === Basic Mappings ===

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

-- Insert mode navigation
map("i", "<C-b>", "<ESC>^i", { desc = "Move beginning of line" })
map("i", "<C-e>", "<End>", { desc = "Move end of line" })
map("i", "<C-h>", "<Left>", { desc = "Move left" })
map("i", "<C-l>", "<Right>", { desc = "Move right" })

-- Window navigation
map("n", "<C-h>", "<C-w>h", { desc = "Switch window left" })
map("n", "<C-l>", "<C-w>l", { desc = "Switch window right" })

-- General
map("n", "<Esc>", "<cmd>noh<CR>", { desc = "Clear highlights" })
map("n", "<C-s>", "<cmd>w<CR>", { desc = "Save file" })
map("n", "<C-c>", "<cmd>%y+<CR>", { desc = "Copy whole file" })

-- Toggle options
map("n", "<leader>n", "<cmd>set nu!<CR>", { desc = "Toggle line number" })
map("n", "<leader>rn", "<cmd>set rnu!<CR>", { desc = "Toggle relative number" })

-- Format
map({ "n", "x" }, "<leader>fm", function()
  require("conform").format { lsp_fallback = true }
end, { desc = "Format file" })

-- Comment
map("n", "<leader>/", "gcc", { desc = "Toggle comment", remap = true })
map("v", "<leader>/", "gc", { desc = "Toggle comment", remap = true })

-- === Barbar buffer navigation ===

map("n", "<Tab>", "<cmd>BufferNext<cr>", { desc = "Next buffer" })
map("n", "<S-Tab>", "<cmd>BufferPrevious<cr>", { desc = "Previous buffer" })
map("n", "<leader>x", "<cmd>BufferClose<cr>", { desc = "Close buffer" })
map("n", "<leader>X", "<cmd>BufferClose!<cr>", { desc = "Force close buffer" })
map("n", "<leader>bn", "<cmd>enew<cr>", { desc = "New buffer" })
map("n", "<leader>bj", "<cmd>BufferPick<cr>", { desc = "Jump to buffer" })
map("n", "<leader>bp", "<cmd>BufferPin<cr>", { desc = "Pin/unpin buffer" })

map("n", "<A-,>", "<cmd>BufferPrevious<cr>", { desc = "Previous buffer" })
map("n", "<A-.>", "<cmd>BufferNext<cr>", { desc = "Next buffer" })
map("n", "<A-<>", "<cmd>BufferMovePrevious<cr>", { desc = "Move buffer left" })
map("n", "<A->>", "<cmd>BufferMoveNext<cr>", { desc = "Move buffer right" })
map("n", "<leader>bc", "<cmd>BufferCloseAllButCurrent<cr>", { desc = "Close all but current" })
map("n", "<leader>bC", "<cmd>BufferCloseAllButPinned<cr>", { desc = "Close all but pinned" })

map("n", "<A-1>", "<cmd>BufferGoto 1<cr>", { desc = "Go to buffer 1" })
map("n", "<A-2>", "<cmd>BufferGoto 2<cr>", { desc = "Go to buffer 2" })
map("n", "<A-3>", "<cmd>BufferGoto 3<cr>", { desc = "Go to buffer 3" })
map("n", "<A-4>", "<cmd>BufferGoto 4<cr>", { desc = "Go to buffer 4" })
map("n", "<A-5>", "<cmd>BufferGoto 5<cr>", { desc = "Go to buffer 5" })
map("n", "<A-6>", "<cmd>BufferGoto 6<cr>", { desc = "Go to buffer 6" })
map("n", "<A-7>", "<cmd>BufferGoto 7<cr>", { desc = "Go to buffer 7" })
map("n", "<A-8>", "<cmd>BufferGoto 8<cr>", { desc = "Go to buffer 8" })
map("n", "<A-9>", "<cmd>BufferGoto 9<cr>", { desc = "Go to buffer 9" })
map("n", "<A-0>", "<cmd>BufferLast<cr>", { desc = "Go to last buffer" })

-- === fzf-lua ===

local fzf = require('fzf-lua')

-- File finding
map("n", "<leader>ff", function() fzf.files() end, { desc = "Find files" })
map("n", "<leader>fa", function() fzf.files({ cmd = "fd --type f --hidden --follow --exclude .git" }) end, { desc = "Find all files" })
map("n", "<leader>fo", function() fzf.oldfiles() end, { desc = "Recent files" })
map("n", "<leader>fb", function() fzf.buffers() end, { desc = "Find buffers" })

-- Grep
map("n", "<leader>fw", function() fzf.live_grep() end, { desc = "Live grep" })
map("n", "<leader>fz", function() fzf.lgrep_curbuf() end, { desc = "Find in current buffer" })

-- Git
map("n", "<leader>cm", function() fzf.git_commits() end, { desc = "Git commits" })
map("n", "<leader>gt", function() fzf.git_status() end, { desc = "Git status" })

-- Other
map("n", "<leader>fh", function() fzf.help_tags() end, { desc = "Help tags" })
map("n", "<leader>ma", function() fzf.marks() end, { desc = "Marks" })

-- LSP
map('n', '<leader>fs', function() fzf.lsp_document_symbols() end, { desc = 'Document symbols' })
map('n', '<leader>fd', function() fzf.diagnostics_document({ severity_limit = vim.diagnostic.severity.ERROR }) end, { desc = "Buffer diagnostics" })
map('n', '<leader>fD', function() fzf.diagnostics_workspace({ severity_limit = vim.diagnostic.severity.ERROR }) end, { desc = "Workspace diagnostics" })
map('n', '<leader>fr', function() fzf.lsp_references() end, { desc = 'References' })
map('n', '<leader>fW', function() vim.diagnostic.open_float() end, { desc = "Open diagnostics window" })
-- <leader>ca is mapped per-buffer in configs/lspconfig.lua on_attach

-- === Themery ===

map("n", "<leader>th", "<cmd>Themery<CR>", { desc = "Theme switcher" })

-- === WhichKey ===

map("n", "<leader>wK", "<cmd>WhichKey <CR>", { desc = "Show all keymaps" })
map("n", "<leader>wk", function()
  vim.cmd("WhichKey " .. vim.fn.input "WhichKey: ")
end, { desc = "Query lookup" })

-- === NvimTree ===

map("n", "<C-n>", "<cmd>NvimTreeToggle<CR>", { desc = "Toggle nvimtree" })
map("n", "<leader>e", "<cmd>NvimTreeFocus<CR>", { desc = "Focus nvimtree" })

-- === VGit ===

map('n', '<C-k>', function() require('vgit').hunk_up() end, { desc = 'Previous hunk' })
map('n', '<C-j>', function() require('vgit').hunk_down() end, { desc = 'Next hunk' })
map('n', '<leader>gs', function() require('vgit').buffer_hunk_stage() end, { desc = 'Stage hunk' })
map('n', '<leader>gr', function() require('vgit').buffer_hunk_reset() end, { desc = 'Reset hunk' })
map('n', '<leader>gp', function() require('vgit').buffer_hunk_preview() end, { desc = 'Preview hunk' })
map('n', '<leader>gb', function() require('vgit').buffer_blame_preview() end, { desc = 'Blame buffer' })
map('n', '<leader>gf', function() require('vgit').buffer_diff_preview() end, { desc = 'Show buffer diff' })
map('n', '<leader>gh', function() require('vgit').buffer_history_preview() end, { desc = 'Show buffer history' })
map('n', '<leader>gu', function() require('vgit').buffer_reset() end, { desc = 'Reset buffer' })
map('n', '<leader>gx', function() require('vgit').toggle_diff_preference() end, { desc = 'Toggle diff view' })
map('n', '<leader>gd', function() require('vgit').project_diff_preview() end, { desc = 'Show project diff' })

-- === Custom scrolling ===

map("n", "<C-Up>", "10k", { remap = true })
map("n", "<C-Down>", "10j", { remap = true })


-- === Move lines ===

map("n", "ø", ":m -2<CR>==", { desc = "Move line up" })
map("v", "ø", ":'<,'>m '<-2<CR>gv=gv", { desc = "Move selection up" })
map("n", "æ", ":m +1<CR>==", { desc = "Move line down" })
map("v", "æ", ":'<,'>m '>+1<CR>gv=gv", { desc = "Move selection down" })

-- === Cargo ===

map("n", "<leader>cr", function()
  vim.cmd("vsplit")
  vim.cmd("terminal cargo run")
end, { desc = "Cargo run in terminal" })

map("n", "<leader>cb", function()
  vim.cmd("vsplit")
  vim.cmd("terminal cargo build")
end, { desc = "Cargo build in terminal" })

-- === Claude Code ===

map("n", "<leader>cc", "<cmd>ClaudeCodeAdd %<cr>", { desc = "Add current file to Claude" })
map("v", "<leader>cc", "<cmd>ClaudeCodeSend<cr>", { desc = "Send to Claude Code" })

-- Create command for Claude context with range support
vim.api.nvim_create_user_command("ClaudeContext", function(opts)
  local filepath = vim.fn.fnamemodify(vim.fn.expand("%"), ":.")
  local context = string.format("@%s#L%d-%d", filepath, opts.line1, opts.line2)
  vim.fn.setreg("+", context)
  vim.notify("Copied: " .. context, vim.log.levels.INFO)
end, { range = true })

map("v", "<leader>cy", ":ClaudeContext<CR>", { desc = "Copy selection as Claude Code context" })

map("n", "<leader>ct", function()
  vim.g.claude_mode = vim.g.claude_mode == "work" and "normal" or "work"
  vim.notify("Claude mode: " .. vim.g.claude_mode, vim.log.levels.INFO)
end, { desc = "Toggle Claude mode (work/normal)" })
