local H=require("\099\111\114\101\046\117\116\105\108\115\046\102\117\110\099\116\105\111\110\115")local P=vim.keymap.set P({"\110";"\105"},"\060\117\112\062","",{noremap=true})P({"\110","\105"},"\060\100\111\119\110\062","",{noremap=true})P({"\110";"\105"},"\060\108\101\102\116\062","",{noremap=true})P({"\110";"\105"},"\060\114\105\103\104\116\062","",{noremap=true})P("\118","\044\121","\"\043\121",{silent=true,noremap=true,desc="\067\111\112\121 \116\111 \115\121\115\116\101\109 \099\108\105\112\098\111\097\114\100 \040\111\110 \121\097\110\107\041"})P("\118","\044\100","\"\043\100",{silent=true;noremap=true;desc="\067\111\112\121 \116\111 \115\121\115\116\101\109 \099\108\105\112\098\111\097\114\100 \040\111\110 \100\101\108\101\116\101\041"})P({"\110";"\118"},"\044\112","\"\043\112",{silent=true;noremap=true;desc=" \080\097\115\116\101 \102\114\111\109 \115\121\115\116\101\109 \099\108\105\112\098\111\097\114\100"})P({"\110","\118"},"\044\080","\"\043\080",{silent=true;noremap=true;desc="\080\097\115\116\101 \102\114\111\109 \115\121\115\116\101\109 \099\108\105\112\098\111\097\114\100 \040\098\101\102\111\114\101 \112\111\115\105\116\105\111\110\041"})P("\110","\107","\118\058\099\111\117\110\116 \061\061 \048 \063 \'\103\107\' \058 \'\107\'",{expr=true})P("\110","\106","\118\058\099\111\117\110\116 \061\061 \048 \063 \'\103\106\' \058 \'\106\'",{expr=true})P("\118","\060","\060\103\118")P("\118","\062","\062\103\118")P("\110","\060\116\097\098\062","\060\099\109\100\062\098\110\101\120\116\060\099\114\062",{desc="\078\101\120\116 \098\117\102\102\101\114"})P("\110","\060\083-\116\097\098\062","\060\099\109\100\062\098\112\114\101\118\105\111\117\115\060\099\114\062",{desc="\080\114\101\118 \098\117\102\102\101\114"})P({"\105";"\110"},"\060\101\115\099\062","\060\099\109\100\062\110\111\104\060\099\114\062\060\101\115\099\062",{desc="\067\108\101\097\114 \104\108\115\101\097\114\099\104 \097\110\100 \069\083\067"})P("\105","\060\067-\108\062",function()return(require("\099\111\114\101\046\117\116\105\108\115\046\102\117\110\099\116\105\111\110\115")).escapePair()end)P({"\105","\118","\110";"\115"},"\060\067-\115\062","\060\099\109\100\062\119\060\099\114\062\060\101\115\099\062",{desc="\083\097\118\101 \102\105\108\101"})P({"\118";"\110"},"\060\108\101\097\100\101\114\062\115\114","\058\037\115\047",{desc="\066\117\102\102\101\114 \115\101\097\114\099\104 \097\110\100 \114\101\112\108\097\099\101"})P("\110","\060\108\101\097\100\101\114\062\116\104",function()H.notify("\084\111\103\103\108\105\110\103 \104\105\100\100\101\110 \099\104\097\114\115",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.list=vim.o.list==false and true or false end,{desc="\084\111\103\103\108\101 \104\105\100\100\101\110 \099\104\097\114\115"})P("\110","\060\108\101\097\100\101\114\062\116\108",function()H.notify("\084\111\103\103\108\105\110\103 \115\105\103\110\099\111\108\117\109\110",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.signcolumn=vim.o.signcolumn=="\121\101\115"and"\110\111"or"\121\101\115"end,{desc="\084\111\103\103\108\101 \115\105\103\110\099\111\108\117\109\110"})P("\110","\060\108\101\097\100\101\114\062\116\118",function()H.notify("\084\111\103\103\108\105\110\103 \118\105\114\116\117\097\108\101\100\105\116",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.virtualedit=vim.o.virtualedit=="\097\108\108"and"\098\108\111\099\107"or"\097\108\108"end,{desc="\084\111\103\103\108\101 \118\105\114\116\117\097\108\101\100\105\116"})P("\110","\060\108\101\097\100\101\114\062\116\115",function()H.notify("\084\111\103\103\108\105\110\103 \115\112\101\108\108",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.spell=vim.o.spell==false and true or false end,{desc="\084\111\103\103\108\101 \115\112\101\108\108"})P("\110","\060\108\101\097\100\101\114\062\116\119",function()H.notify("\084\111\103\103\108\105\110\103 \119\114\097\112",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.wrap=vim.o.wrap==false and true or false end,{desc="\084\111\103\103\108\101 \119\114\097\112"})P("\110","\060\108\101\097\100\101\114\062\116\099",function()H.notify("\084\111\103\103\108\105\110\103 \099\117\114\115\111\114\108\105\110\101",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")vim.o.cursorline=vim.o.cursorline==false and true or false end,{desc="\084\111\103\103\108\101 \099\117\114\115\111\114\108\105\110\101"})P("\110","\060\108\101\097\100\101\114\062\116\109",function()if vim.o.mouse==""then vim.o.mouse=(require("\099\111\114\101\046\115\101\116\116\105\110\103\115")).mouse H.notify("\084\111\103\103\108\105\110\103 \109\111\117\115\101 \111\110",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")else vim.o.mouse=""H.notify("\084\111\103\103\108\105\110\103 \109\111\117\115\101 \111\102\102",vim.log.levels.INFO,"\099\111\114\101\046\109\097\112\112\105\110\103\115")end end,{desc="\084\111\103\103\108\101 \109\111\117\115\101"})P("\110","\060\108\101\097\100\101\114\062\116\111","\060\099\109\100\062\108\117\097 \114\101\113\117\105\114\101\040\'\099\111\114\101\046\117\116\105\108\115\046\102\117\110\099\116\105\111\110\115\'\041\046\116\111\103\103\108\101\095\099\111\108\111\114\099\111\108\117\109\110\040\041\060\099\114\062",{desc="\084\111\103\103\108\101 \099\111\108\111\114\099\111\108\117\109\110"})P("\110","\060\108\101\097\100\101\114\062\116\116","\060\099\109\100\062\108\117\097 \114\101\113\117\105\114\101\040\'\099\111\114\101\046\112\108\117\103\105\110\115\046\108\115\112\046\117\116\105\108\115\'\041\046\116\111\103\103\108\101\095\118\105\114\116\117\097\108\095\116\101\120\116\040\041\060\099\114\062",{desc="\084\111\103\103\108\101 \086\105\114\116\117\097\108\116\101\120\116"})P("\110","\060\108\101\097\100\101\114\062\116\115","\060\099\109\100\062\083\121\109\098\111\108\115\079\117\116\108\105\110\101\060\099\114\062",{desc="\084\111\103\103\108\101 \083\121\109\098\111\108\115\079\117\116\108\105\110\101"})P("\110","\060\108\101\097\100\101\114\062\116\083","\060\099\109\100\062\119\105\110\100\111 \115\101\116 \115\099\098\033\060\099\114\062",{desc="\084\111\103\103\108\101 \083\099\114\111\108\108\098\105\110\100"})local g=require("\119\104\105\099\104-\107\101\121")g.add({{"\115\070",desc="\070\105\110\100 \108\101\102\116 \115\117\114\114\111\117\110\100\105\110\103"};{"\115\097";desc="\065\100\100 \115\117\114\114\111\117\110\100\105\110\103"};{"\115\100";desc="\068\101\108\101\116\101 \115\117\114\114\111\117\110\100\105\110\103"},{"\115\102";desc="\082\101\112\108\097\099\101 \114\105\103\104\116 \115\117\114\114\111\117\110\100\105\110\103"},{"\115\104",desc="\072\105\103\104\108\105\103\104\116 \115\117\114\114\111\117\110\100\105\110\103"},{"\115\110",desc="\083\117\114\114\111\117\110\100 \117\112\100\097\116\101 \110 \108\105\110\101\115"},{"\115\114",desc="\082\101\112\108\097\099\101 \115\117\114\114\111\117\110\100\105\110\103"},{"\115\116","\060\099\109\100\062\108\117\097 \114\101\113\117\105\114\101\040\'\116\115\104\116\'\041\046\110\111\100\101\115\040\041\060\099\114\062";desc="\084\083 \104\105\110\116 \116\101\120\116\111\098\106\101\099\116"}})g.add({{"\060\108\101\097\100\101\114\062\060\116\097\098\062","\060\099\109\100\062\101\035\060\099\114\062",desc="\080\114\101\118 \098\117\102\102\101\114"};{"\060\108\101\097\100\101\114\062\098";group="\066\117\102\102\101\114\115"};{"\060\108\101\097\100\101\114\062\098\068";"\060\099\109\100\062\037\098\100\124\101\035\124\098\100\035\060\099\114\062",desc="\067\108\111\115\101 \097\108\108 \098\117\116 \116\104\101 \099\117\114\114\101\110\116 \098\117\102\102\101\114"},{"\060\108\101\097\100\101\114\062\098\100";"\060\099\109\100\062\098\100\101\108\101\116\101\060\099\114\062";desc="\067\108\111\115\101 \098\117\102\102\101\114"};{"\060\108\101\097\100\101\114\062\102";group="\070\105\108\101\115"},{"\060\108\101\097\100\101\114\062\102\115";"\060\099\109\100\062\119\060\099\114\062";desc="\083\097\118\101 \066\117\102\102\101\114"},{"\060\108\101\097\100\101\114\062\108";desc="\076\083\080"};{"\060\108\101\097\100\101\114\062\108\119";desc="\087\111\114\107\115\112\097\099\101\115"};{"\060\108\101\097\100\101\114\062\109",group="\077\105\115\099"};{"\060\108\101\097\100\101\114\062\109\108","\060\099\109\100\062\115\111\117\114\099\101 ~\047\046\099\111\110\102\105\103\047\110\118\105\109\047\115\110\105\112\112\101\116\115\047\042\060\099\114\062",desc="\082\101\108\111\097\100 \115\110\105\112\112\101\116\115"},{"\060\108\101\097\100\101\114\062\109\112","\060\099\109\100\062\076\097\122\121 \099\104\101\099\107\060\099\114\062",desc="\076\097\122\121 \099\104\101\099\107"},{"\060\108\101\097\100\101\114\062\113",group="\081\117\105\099\107\102\105\120"},{"\060\108\101\097\100\101\114\062\113\106","\060\099\109\100\062\099\110\101\120\116\060\099\114\062",desc="\078\101\120\116 \081\117\105\099\107\102\105\120 \073\116\101\109"},{"\060\108\101\097\100\101\114\062\113\107";"\060\099\109\100\062\099\112\114\101\118\105\111\117\115\060\099\114\062";desc="\080\114\101\118\105\111\117\115 \081\117\105\099\107\102\105\120 \073\116\101\109"},{"\060\108\101\097\100\101\114\062\113\113","\060\099\109\100\062\108\117\097 \114\101\113\117\105\114\101\040\'\099\111\114\101\046\117\116\105\108\115\046\102\117\110\099\116\105\111\110\115\'\041\046\116\111\103\103\108\101\095\113\102\040\041\060\099\114\062";desc="\084\111\103\103\108\101 \113\117\105\099\107\102\105\120 \108\105\115\116"},{"\060\108\101\097\100\101\114\062\113\116","\060\099\109\100\062\084\111\100\111\081\117\105\099\107\070\105\120\060\099\114\062";desc="\083\104\111\119 \084\079\068\079\115"};{"\060\108\101\097\100\101\114\062\115",desc="\083\101\097\114\099\104"},{"\060\108\101\097\100\101\114\062\116";group="\084\111\103\103\108\101\115"},{"\060\108\101\097\100\101\114\062\119",desc="\087\105\110\100\111\119\115"},{"\060\108\101\097\100\101\114\062\122",desc="\083\112\101\108\108\105\110\103"}})
-- TODO: Keep all mappings possible in this module
-- Example https://github.com/dkarter/dotfiles/blob/master/config/nvim/lua/core/mappings.lua

--local opts = { noremap = true, silent = true }
--
--local term_opts = { silent = true }
--
---- Shorten function name
--local keymap = vim.api.nvim_set_keymap
--
----Remap space as leader key
--keymap('', '<Space>', '<Nop>', opts)
--vim.g.mapleader = ' '
--vim.g.maplocalleader = ' '
--
---- Modes
----   normal_mode = "n",
----   insert_mode = "i",
----   visual_mode = "v",
----   visual_block_mode = "x",
----   term_mode = "t",
----   command_mode = "c",
--
---- Normal --
---- Better window navigation
--keymap('n', '<C-h>', '<C-w>h', opts)
--keymap('n', '<C-k>', '<C-w>k', opts)
--keymap('n', '<C-j>', '<C-w>j', opts)
--keymap('n', '<C-l>', '<C-w>l', opts)
--
---- Resize with arrows when using multiple windows
--keymap('n', '<C-Up>', ':resize -2<CR>', opts)
--keymap('n', '<c-down>', ':resize +2<cr>', opts)
--keymap('n', '<c-right>', ':vertical resize -2<cr>', opts)
--keymap('n', '<c-left>', ':vertical resize +2<cr>', opts)
--
---- navigate buffers
--keymap('n', '<tab>', ':bnext<cr>', opts)
--keymap('n', '<s-tab>', ':bprevious<cr>', opts)
--keymap('n', '<leader>h', ':nohlsearch<cr>', opts) -- No highlight search
--
---- move text up and down
--keymap('n', '<a-j>', '<esc>:m .+1<cr>==gi', opts)
--keymap('n', '<a-k>', '<esc>:m .-2<cr>==gi', opts)
--
---- insert --
---- press jk fast to exit insert mode
--keymap('i', 'jk', '<esc>', opts)
--keymap('i', 'kj', '<esc>', opts)
--
--keymap('n', 'df', 'ggdG', opts)
--keymap('n', 'yf', 'ggyG', opts)
--
--keymap('n', 'z', '0', opts)
--keymap('n', 'm', '$', opts)
--keymap('n', ';', '%', opts)
---- visual --
---- stay in indent mode
--keymap('v', '<', '<gv', opts)
--keymap('v', '>', '>gv', opts)
--
---- move text up and down
--keymap('v', '<a-j>', ':m .+1<cr>==', opts)
--keymap('v', '<a-k>', ':m .-2<cr>==', opts)
--keymap('v', 'p', '"_dp', opts)
--
---- Visual Block --
---- Move text up and down
----Terminal --
--keymap('x', 'J', ":move '>+1<CR>gv-gv", opts)
--keymap('x', 'K', ":move '<-2<CR>gv-gv", opts)
--keymap('x', '<A-j>', ":move '>+1<CR>gv-gv", opts)
--keymap('x', '<A-k>', ":move '<-2<CR>gv-gv", opts)
--
----Better terminal navigation
--keymap('t', '<C-h>', '<C-\\><C-N><C-w>h', term_opts)
--keymap('t', '<C-j>', '<C-\\><C-N><C-w>j', term_opts)
--keymap('t', '<C-k>', '<C-\\><C-N><C-w>k', term_opts)
--keymap('t', '<C-l>', '<C-\\><C-N><C-w>l', term_opts)

local utils = require 'core.utils.functions'
local map = vim.keymap.set

-- disable arrow keys on normal and insert mode
map({ 'n', 'i' }, '<up>', '', { noremap = true })
map({ 'n', 'i' }, '<down>', '', { noremap = true })
map({ 'n', 'i' }, '<left>', '', { noremap = true })
map({ 'n', 'i' }, '<right>', '', { noremap = true })

-- copy and paste to clipboard
map('v', ',y', '"+y', { silent = true, noremap = true, desc = 'Copy to system clipboard (on yank)' })
map('v', ',d', '"+d', { silent = true, noremap = true, desc = 'Copy to system clipboard (on delete)' })
map({ 'n', 'v' }, ',p', '"+p', { silent = true, noremap = true, desc = ' Paste from system clipboard' })
map({ 'n', 'v' }, ',P', '"+P', { silent = true, noremap = true, desc = 'Paste from system clipboard (before position)' })

-- Remap for dealing with visual line wraps
map('n', 'k', "v:count == 0 ? 'gk' : 'k'", { expr = true })
map('n', 'j', "v:count == 0 ? 'gj' : 'j'", { expr = true })

-- better indenting
map('v', '<', '<gv')
map('v', '>', '>gv')

-- switch buffer
map('n', '<tab>', '<cmd>bnext<cr>', { desc = 'Next buffer' })
map('n', '<S-tab>', '<cmd>bprevious<cr>', { desc = 'Prev buffer' })

-- Cancel search highlighting with ESC
map({ 'i', 'n' }, '<esc>', '<cmd>noh<cr><esc>', { desc = 'Clear hlsearch and ESC' })

-- move over a closing element in insert mode
map('i', '<C-l>', function()
  return require('core.utils.functions').escapePair()
end)

-- save like your are used to
map({ 'i', 'v', 'n', 's' }, '<C-s>', '<cmd>w<cr><esc>', { desc = 'Save file' })

-- search and replace is a pain with a German keyboard layout
map({ 'v', 'n' }, '<leader>sr', ':%s/', { desc = 'Buffer search and replace' })

-- toggles
map('n', '<leader>th', function()
  utils.notify('Toggling hidden chars', vim.log.levels.INFO, 'core.mappings')
  vim.o.list = vim.o.list == false and true or false
end, { desc = 'Toggle hidden chars' })
map('n', '<leader>tl', function()
  utils.notify('Toggling signcolumn', vim.log.levels.INFO, 'core.mappings')
  vim.o.signcolumn = vim.o.signcolumn == 'yes' and 'no' or 'yes'
end, { desc = 'Toggle signcolumn' })
map('n', '<leader>tv', function()
  utils.notify('Toggling virtualedit', vim.log.levels.INFO, 'core.mappings')
  vim.o.virtualedit = vim.o.virtualedit == 'all' and 'block' or 'all'
end, { desc = 'Toggle virtualedit' })
map('n', '<leader>ts', function()
  utils.notify('Toggling spell', vim.log.levels.INFO, 'core.mappings')
  vim.o.spell = vim.o.spell == false and true or false
end, { desc = 'Toggle spell' })
map('n', '<leader>tw', function()
  utils.notify('Toggling wrap', vim.log.levels.INFO, 'core.mappings')
  vim.o.wrap = vim.o.wrap == false and true or false
end, { desc = 'Toggle wrap' })

map('n', '<leader>tc', function()
  utils.notify('Toggling cursorline', vim.log.levels.INFO, 'core.mappings')
  vim.o.cursorline = vim.o.cursorline == false and true or false
end, { desc = 'Toggle cursorline' })

map('n', '<leader>tm', function()
  if vim.o.mouse == '' then
    vim.o.mouse = require('core.settings').mouse
    utils.notify('Toggling mouse on', vim.log.levels.INFO, 'core.mappings')
  else
    vim.o.mouse = ''
    utils.notify('Toggling mouse off', vim.log.levels.INFO, 'core.mappings')
  end
end, { desc = 'Toggle mouse' })

map('n', '<leader>to', "<cmd>lua require('core.utils.functions').toggle_colorcolumn()<cr>", { desc = 'Toggle colorcolumn' })
map('n', '<leader>tt', "<cmd>lua require('core.plugins.lsp.utils').toggle_virtual_text()<cr>", { desc = 'Toggle Virtualtext' })
map('n', '<leader>ts', '<cmd>SymbolsOutline<cr>', { desc = 'Toggle SymbolsOutline' })
map('n', '<leader>tS', '<cmd>windo set scb!<cr>', { desc = 'Toggle Scrollbind' })

local wk = require 'which-key'

-- register non leader based mappings
wk.add {
  { 'sF', desc = 'Find left surrounding' },
  { 'sa', desc = 'Add surrounding' },
  { 'sd', desc = 'Delete surrounding' },
  { 'sf', desc = 'Replace right surrounding' },
  { 'sh', desc = 'Highlight surrounding' },
  { 'sn', desc = 'Surround update n lines' },
  { 'sr', desc = 'Replace surrounding' },
  { 'st', "<cmd>lua require('tsht').nodes()<cr>", desc = 'TS hint textobject' },
}

-- Register leader based mappings
wk.add {
  { '<leader><tab>', '<cmd>e#<cr>', desc = 'Prev buffer' },
  { '<leader>b', group = 'Buffers' },
  { '<leader>bD', '<cmd>%bd|e#|bd#<cr>', desc = 'Close all but the current buffer' },
  { '<leader>bd', '<cmd>bdelete<cr>', desc = 'Close buffer' },
  { '<leader>f', group = 'Files' },
  { '<leader>fs', '<cmd>w<cr>', desc = 'Save Buffer' },
  { '<leader>l', desc = 'LSP' },
  { '<leader>lw', desc = 'Workspaces' },
  { '<leader>m', group = 'Misc' },
  { '<leader>ml', '<cmd>source ~/.config/nvim/snippets/*<cr>', desc = 'Reload snippets' },
  { '<leader>mp', '<cmd>Lazy check<cr>', desc = 'Lazy check' },
  { '<leader>q', group = 'Quickfix' },
  { '<leader>qj', '<cmd>cnext<cr>', desc = 'Next Quickfix Item' },
  { '<leader>qk', '<cmd>cprevious<cr>', desc = 'Previous Quickfix Item' },
  { '<leader>qq', "<cmd>lua require('core.utils.functions').toggle_qf()<cr>", desc = 'Toggle quickfix list' },
  { '<leader>qt', '<cmd>TodoQuickFix<cr>', desc = 'Show TODOs' },
  { '<leader>s', desc = 'Search' },
  { '<leader>t', group = 'Toggles' },
  { '<leader>w', desc = 'Windows' },
  { '<leader>z', desc = 'Spelling' },
}
