-- Snacks needs to be loaded very early, so it gets its own special file.
local set = vim.keymap.set

require('snacks').setup({
  bigfile = { enabled = true },
  notifier = { enabled = true },
  quickfile = { enabled = true },
  statuscolumn = { enabled = true },
  words = { enabled = true },
})

-- Debuggers -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

_G.dd = function(...)
  Snacks.debug.inspect(...)
end

_G.bt = function()
  Snacks.debug.backtrace()
end

vim.print = _G.dd

-- Notifier -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

set({ 'n' }, '<LEADER>un', function()
  Snacks.notifier.hide()
end, { desc = 'dismiss all notifications' })

-- Buffers -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
set({ 'n' }, '<LEADER>bd', function()
  Snacks.bufdelete()
end, { desc = 'delete buffer' })

set({ 'n' }, '<LEADER>bo', function()
  Snacks.bufdelete.other()
end, { desc = 'delete other buffers' })

-- Toggles -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

local toggle = Snacks.toggle

toggle.option('spell', { name = 'spelling' }):map('<LEADER>us')
toggle.option('wrap', { name = 'wrap' }):map('<LEADER>uw')

toggle.option('relativenumber', { name = 'relative number' }):map('<LEADER>uL')
toggle.line_number():map('<LEADER>ul')

toggle.diagnostics():map('<LEADER>ud')

toggle
  .option(
    'conceallevel',
    { off = 0, on = vim.o.conceallevel > 0 and vim.o.conceallevel or 2 }
  )
  :map('<LEADER>uc')

toggle.treesitter():map('<LEADER>uT')

if vim.lsp.inlay_hint then
  toggle.inlay_hints():map('<LEADER>uh')
end

toggle({
  name = 'auto format (global)',
  get = function()
    return vim.g.autoformat == nil or vim.g.autoformat
  end,
  set = function(enable)
    vim.g.autoformat = (enable == nil and true) or enable
    vim.b.autoformat = nil
  end,
}):map('<LEADER>uf')

toggle({
  name = 'auto format (buffer)',
  get = function()
    local buf = vim.api.nvim_get_current_buf()

    local gopt = vim.g.autoformat
    local bopt = vim.b[buf].autoformat

    if bopt ~= nil then
      return bopt
    end

    return gopt == nil or gopt
  end,
  set = function(enable)
    vim.b.autoformat = (enable == nil and true) or enable
  end,
}):map('<LEADER>uF')

-- Git -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

set({ 'n' }, '<LEADER>gb', function()
  Snacks.git.blame_line()
end, { desc = 'git blame line' })

set({ 'n' }, '<LEADER>gB', function()
  Snacks.gitbrowse()
end, { desc = 'git browse (open)' })

set({ 'n' }, '<LEADER>gY', function()
  Snacks.gitbrowse({
    open = function(url)
      vim.fn.setreg('+', url)
    end,
  })
end, { desc = 'git browse (copy)' })

-- LazyGit -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --

if vim.fn.executable('lazygit') == 1 then
  set({ 'n' }, '<LEADER>gg', function()
    Snacks.lazygit({ cwd = MarleyVim.root() })
  end, { desc = 'lazygit (root dir)' })

  -- set({ 'n' }, '<LEADER>gG', function()
  --   Snacks.lazygit()
  -- end, { desc = 'Lazygit (cwd)' })

  set({ 'n' }, '<LEADER>gf', function()
    Snacks.lazygit.log_file()
  end, { desc = 'lazygit current file history' })

  set({ 'n' }, '<LEADER>gl', function()
    Snacks.lazygit.log({ cwd = MarleyVim.root() })
  end, { desc = 'Lazygit log' })

  -- set({ 'n' }, '<LEADER>gL', function()
  --   Snacks.lazygit.log()
  -- end, { desc = 'Lazygit log (cwd)' })
end