local lazypath = vim.fn.stdpath('data') .. '/lazy/lazy.nvim'
if not vim.loop.fs_stat(lazypath) then
   vim.fn.system({
      'git',
      'clone',
      '--filter=blob:none',
      'https://github.com/folke/lazy.nvim.git',
      '--branch=stable',
      lazypath,
   })
end
vim.opt.rtp:prepend(lazypath)

vim.g.mapleader = ' '
vim.g.maplocalleader = ' '

vim.cmd.source('~/.vim/vimrc')

vim.cmd([[ set undodir=$HOME/.config/nvim/undo ]])
vim.cmd([[ set t_Co=256 ]])
vim.cmd([[ set termguicolors ]])
vim.cmd([[ let g:AutoPairs = {'(':')', '[':']', '{':'}','"':'"', '```':'```', '"""':'"""', "'''":"'''", "`":"`"} ]])

vim.opt.completeopt = { 'menuone', 'noselect', 'popup' }

vim.opt.winborder = 'none'
vim.opt.winblend = 10

local opts = { noremap = true, silent = true }

-- zero_picker: vcs-aware file finder for telescope
local zero_picker = function(picker_opts)
   local pickers = require('telescope.pickers')
   local finders = require('telescope.finders')
   local conf = require('telescope.config').values
   picker_opts = picker_opts or {}
   local finder_title, finder_cmd
   local check_dir = function(dir) return vim.fn.isdirectory(dir) == 1 end
   if check_dir('.git') then
      finder_title = 'git files'
      finder_cmd = { 'git', 'ls-files' }
   elseif check_dir('_darcs') then
      finder_title = 'darcs files'
      finder_cmd = { 'sh', '-c', 'darcs show files --no-directories | cut -c3-' }
   elseif check_dir('.pijul') then
      finder_title = 'pijul files'
      finder_cmd = { 'fd', '-Htf', '-E', '.pijul' }
   else
      finder_title = 'files'
      finder_cmd = { 'fd', '-t', 'f', '-H' }
   end
   pickers.new(picker_opts, {
      prompt_title = finder_title,
      finder = finders.new_oneshot_job(finder_cmd, picker_opts),
      sorter = conf.file_sorter(picker_opts),
      previewer = conf.file_previewer(picker_opts),
   }):find()
end

-- Telescope highlight overrides — re-applied on every colorscheme change
local function apply_telescope_highlights()
   local highlights = {
      TelescopeSelection        = { fg = 'none', bg = 'none' },
      TelescopeSelectionCaret   = { fg = '#79d4d5', bg = 'none' },
      TelescopeMultiSelection   = { fg = 'none', bg = '#202020' },
      TelescopeNormal           = { fg = 'none', bg = '#262626' },
      TelescopeBorder           = { fg = 'none', bg = 'none' },
      TelescopePromptBorder     = { fg = 'none', bg = '#202020' },
      TelescopeResultsBorder    = { fg = 'none', bg = '#262626' },
      TelescopePreviewBorder    = { fg = 'none', bg = '#262626' },
      TelescopeMatching         = { fg = '#79d4d5', bg = 'none' },
      TelescopePromptPrefix     = { fg = 'none', bg = 'none' },
      TelescopePromptNormal     = { fg = 'none', bg = '#202020' },
      TelescopePromptTitle      = { fg = 'none', bg = 'none' },
      TelescopePreviewTitle     = { fg = '#262626', bg = 'none' },
      TelescopeResultsTitle     = { fg = '#202020', bg = 'none' },
   }
   for hl, col in pairs(highlights) do
      vim.api.nvim_set_hl(0, hl, col)
   end
end
apply_telescope_highlights()
vim.api.nvim_create_autocmd('ColorScheme', { callback = apply_telescope_highlights })

require('lazy').setup({

   { -- color schemes
      { 'alligator/accent.vim',
         config = function()
            vim.g.accent_colour = 'cyan'
            vim.g.accent_darken = 1
            vim.g.accent_invert_status = 0
            vim.g.accent_auto_cwd_colour = 1
            vim.g.accent_no_bg = 1
         end,
      },
      'kadekillary/skull-vim',
      'lokaltog/vim-monotone',
      'arcticicestudio/nord-vim',
      'hardselius/warlock',
      'sainnhe/everforest',
      'logico/typewriter-vim',
      'reedes/vim-colors-pencil',
      'junegunn/seoul256.vim',
      'sainnhe/gruvbox-material',
      'sonph/onehalf',
      'EdenEast/nightfox.nvim',
      'nordtheme/vim',
      'joshdick/onedark.vim',
      'folke/tokyonight.nvim',
      'morhetz/gruvbox',
   },

   {
      'RRethy/vim-illuminate',
      config = function()
         require('illuminate').configure({
            providers = { 'lsp', 'treesitter', 'regex' },
            delay = 9,
            filetype_overrides = {},
            filetypes_denylist = { 'dirbuf', 'dirvish', 'fugitive' },
            filetypes_allowlist = {},
            modes_denylist = {},
            modes_allowlist = {},
            providers_regex_syntax_denylist = {},
            providers_regex_syntax_allowlist = {},
            under_cursor = true,
            large_file_cutoff = nil,
            large_file_overrides = nil,
            min_count_to_highlight = 1,
            should_enable = function(bufnr) return true end,
            case_insensitive_regex = false,
         })
      end,
   },

   {
      'jiangmiao/auto-pairs',
      config = function()
         vim.g.AutoPairsMultilineClose = 0
      end,
   },

   {
      'norcalli/nvim-colorizer.lua',
      config = function()
         require('colorizer').setup(
            { '*', '!TelescopePrompt', '!TelescopeResults' },
            {
               mode     = 'background',
               RGB      = true,
               RRGGBB   = true,
               names    = false,
               RRGGBBAA = true,
               rgb_fn   = true,
               hsl_fn   = true,
               css      = false,
               css_fn   = false,
            }
         )
         vim.api.nvim_create_autocmd('TextChanged', { command = 'ColorizerAttachToBuffer' })
      end,
   },

   {
      'mbbill/undotree',
      config = function()
         vim.g.undotree_WindowLayout          = 2
         vim.g.undotree_ShortIndicators       = 1
         vim.g.undotree_SplitWidth            = 29
         vim.g.undotree_DiffpanelHeight       = 10
         vim.g.undotree_DiffAutoOpen          = 1
         vim.g.undotree_SetFocusWhenToggle    = 1
         vim.g.undotree_TreeNodeShape         = '*'
         vim.g.undotree_TreeVertShape         = '|'
         vim.g.undotree_TreeSplitShape        = '/'
         vim.g.undotree_TreeReturnShape       = '\\'
         vim.g.undotree_DiffCommand           = 'diff -s'
         vim.g.undotree_RelativeTimestamp     = 1
         vim.g.undotree_HighlightChangedText  = 1
         vim.g.undotree_HighlightChangedWithSign = 1
         vim.g.undotree_HighlightSyntaxAdd    = 'DiffAdd'
         vim.g.undotree_HighlightSyntaxChange = 'DiffChange'
         vim.g.undotree_HighlightSyntaxDel    = 'DiffDelete'
         vim.g.undotree_HelpLine              = 1
         vim.g.undotree_CursorLine            = 1

         vim.keymap.set('n', '<leader>u',     '<cmd>UndotreeToggle<cr>',                    opts)
         vim.keymap.set('n', '<C-w>u',        '<cmd>UndotreeShow | UndotreeFocus<cr>',      opts)
         vim.keymap.set('n', '<C-w>U',        '<cmd>UndotreeHide<cr>',                      opts)
         vim.keymap.set('n', '<C-w><C-u>',    '<cmd>UndotreeShow<cr>',                      opts)
      end,
   },

   'junegunn/goyo.vim',
   'junegunn/limelight.vim',
   '907th/vim-auto-save',

   {
      'lewis6991/gitsigns.nvim',
      init = function()
         require('gitsigns').setup({
            signs = {
               add          = { text = '' },
               change       = { text = '' },
               delete       = { text = '' },
               topdelete    = { text = '' },
               changedelete = { text = '' },
               untracked    = { text = '' },
            },
            signs_staged = {
               add          = { text = '' },
               change       = { text = '' },
               delete       = { text = '' },
               topdelete    = { text = '' },
               changedelete = { text = '' },
               untracked    = { text = '' },
            },
            signs_staged_enable = true,
         })
      end,
   },

   {
      'Eiko-Tokura/darcssigns.nvim',
      init = function()
         require('darcssigns').setup({
            enabled = true,
            signs = {
               add       = { text = '', hl = 'DarcsSignsAdd' },
               change    = { text = '', hl = 'DarcsSignsChange' },
               delete    = { text = '', hl = 'DarcsSignsDelete' },
               untracked = { text = '', hl = 'DarcsSignsUntracked' },
            },
         })
      end,
   },

   {
      'nvim-telescope/telescope.nvim',
      dependencies = {
         'nvim-lua/plenary.nvim',
         { 'nvim-telescope/telescope-fzf-native.nvim', build = 'make' },
      },
      config = function()
         local actions = require('telescope.actions')
         local action_layout = require('telescope.actions.layout')

         require('telescope').setup {
            defaults = {
               initial_mode        = 'insert',
               layout_strategy     = 'horizontal',
               layout_config = {
                  prompt_position = 'top',
                  preview_cutoff  = 0,
                  height          = 0.9,
                  width           = 0.9,
                  preview_width   = 0.5,
               },
               sorting_strategy     = 'ascending',
               scroll_strategy      = 'cycle',
               file_ignore_patterns = { '.git/[^h]' },
               winblend             = 0,
               previewer            = true,
               preview = {
                  treesitter = false,
                  syntax     = true,
               },
               show_line            = false,
               prompt_prefix        = '',
               prompt_title         = false,
               results_title        = false,
               selection_strategy   = 'reset',
               border               = {},
               borderchars = {
                  prompt  = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
                  results = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
                  preview = { ' ', ' ', ' ', ' ', ' ', ' ', ' ', ' ' },
               },
               default_selection_index = 1,
               mappings = {
                  i = {
                     ['<C-h>']   = actions.which_key,
                     ['<C-j>']   = actions.move_selection_next,
                     ['<C-k>']   = actions.move_selection_previous,
                     ['<C-l>']   = actions.toggle_selection,
                     ['<C-q>']   = actions.close,
                     ['<C-BS>']  = false,
                     ['<C-w>']   = action_layout.toggle_preview,
                     ['<C-u>']   = actions.preview_scrolling_up,
                     ['<C-d>']   = actions.preview_scrolling_down,
                     ['<PageUp>']   = actions.preview_scrolling_up,
                     ['<PageDown>'] = actions.preview_scrolling_down,
                     ['<M-S-,>'] = actions.cycle_history_prev,
                     ['<M-S-.>'] = actions.cycle_history_next,
                  },
                  n = {
                     ['?']          = actions.which_key,
                     ['<ESC>']      = actions.close,
                     ['q']          = actions.close,
                     ['w']          = action_layout.toggle_preview,
                     ['<C-u>']      = actions.preview_scrolling_up,
                     ['<C-d>']      = actions.preview_scrolling_down,
                     ['<PageUp>']   = actions.preview_scrolling_up,
                     ['<PageDown>'] = actions.preview_scrolling_down,
                  },
               },
            },
            pickers = {
               colorscheme = { enable_preview = true },
               find_files = {
                  find_command = { 'fd', '-t', 'f', '-H' },
                  hidden = true,
               },
               buffers = {
                  show_all_buffers = true,
                  sort_lastused    = true,
                  mappings = {
                     i = { ['<c-d>'] = 'delete_buffer' },
                  },
               },
            },
            extensions = {
               fzf = {
                  fuzzy                   = true,
                  override_generic_sorter = true,
                  override_file_sorter    = true,
                  case_mode               = 'smart_case',
               },
            },
         }

         require('telescope').load_extension('fzf')

         local builtin = require('telescope.builtin')

         vim.keymap.set('n', '<leader>T', '<cmd>Telescope<cr>',                      opts)
         vim.keymap.set('n', '<leader>t', builtin.resume,                            opts)
         vim.keymap.set('n', '<leader>?', builtin.help_tags,                         opts)
         vim.keymap.set('n', '<leader>F', builtin.find_files,                        opts)
         vim.keymap.set('n', '<leader>f', zero_picker,                               opts)
         vim.keymap.set('n', '<leader>g', builtin.git_commits,                       opts)
         vim.keymap.set('n', '<leader>G', builtin.git_bcommits,                      opts)
         vim.keymap.set('n', '<leader>v', builtin.live_grep,                         opts)
         vim.keymap.set('n', '<leader>/', builtin.grep_string,                       opts)
         vim.keymap.set('n', '<leader>k', builtin.lsp_dynamic_workspace_symbols,     opts)
         vim.keymap.set('n', '<leader>K', builtin.lsp_definitions,                   opts)
         vim.keymap.set('n', '<leader>b', builtin.buffers,                           opts)
         vim.keymap.set('n', '<leader>d', builtin.diagnostics,                       opts)
         vim.keymap.set('n', '<leader>j', builtin.jumplist,                          opts)
         vim.keymap.set('n', '<leader>r', builtin.registers,                         opts)
         vim.keymap.set('n', '<leader>m', builtin.marks,                             opts)
         vim.keymap.set('n', '<leader>q', builtin.quickfix,                          opts)
         vim.keymap.set('n', '<leader>l', builtin.loclist,                           opts)

         -- fzf command (kept alongside telescope)
         vim.cmd([[ command! -bang -nargs=? -complete=dir Files call fzf#vim#files(<q-args>, fzf#vim#with_preview({'options': ['--layout=reverse', '--info=inline']}), <bang>0) ]])
         vim.keymap.set('n', '<leader>z', '<cmd>FZF!<cr>', opts)

         -- open telescope when nvim is invoked with a directory argument
         vim.api.nvim_create_autocmd('VimEnter', {
            callback = function()
               local arg = vim.fn.argv(0)
               if arg ~= '' and vim.fn.isdirectory(arg) == 1 then
                  vim.cmd('cd ' .. vim.fn.fnameescape(arg))
                  vim.schedule(function() zero_picker() end)
               end
            end,
         })
      end,
   },

   {
      'vifm/vifm.vim',
      init = function()
         vim.g.loaded_netrw = 1
         vim.g.loaded_netrwPlugin = 1
         vim.g.vifm_replace_netrw = 1
         vim.g.vifm_replace_netrw_cmd = 'Vifm'
      end,
      config = function()
         vim.g.vifm_embed_term = 1
         vim.keymap.set('n', '<leader>x', '<cmd>Vifm<cr>', opts)
      end,
   },
-- {
--    'ibhagwan/fzf-lua',
--    -- optional for icon support
--    -- dependencies = { 'nvim-tree/nvim-web-devicons' },
--    -- or if using mini.icons/mini.nvim
--    -- dependencies = { 'echasnovski/mini.icons' },
--    opts = {}
-- },
-- {
--    'folke/flash.nvim',
--    event = 'VeryLazy',
--    ---@type Flash.Config
--    opts = {
--       incremental = true,
--       modes = {
--          search = { enabled = false },
--       },
--       prompt = {
--          enabled = true,
--          prefix = { { ' ', 'FlashPromptIcon' } },
--       },
--    },
--    -- stylua: ignore
--    keys = {
--       { 's', mode = { 'n', 'x', 'o' }, function() require('flash').jump() end, desc = 'Flash' },
--       { 'S', mode = { 'n', 'x', 'o' }, function() require('flash').treesitter() end, desc = 'Flash Treesitter' },
--       { 'r', mode = 'o', function() require('flash').remote() end, desc = 'Remote Flash' },
--       { 'R', mode = { 'o', 'x' }, function() require('flash').treesitter_search() end, desc = 'Treesitter Search' },
--       { '<c-s>', mode = { 'c' }, function() require('flash').toggle() end, desc = 'Toggle Flash Search' },
--    },
-- },
-- {
--    'nvim-telescope/telescope-file-browser.nvim',
--    dependencies = {
--       'nvim-telescope/telescope.nvim',
--       'nvim-lua/plenary.nvim'
--    },
--    init = function()
--       vim.g.loaded_netrw = 1
--       vim.g.loaded_netrwPlugin = 1
--    end,
--    config = function()
--       require('telescope').setup {
--          extensions = {
--             file_browser = {
--                hijack_netrw = true,
--                hidden = false,  -- show hidden files
--                respect_gitignore = true,
--                dir_icon = " ",
--             }
--          }
--       }
--       require('telescope').load_extension('file_browser')
--
--       -- Open file browser (mimics your Vifm setup)
--       vim.keymap.set('n', '-', ':Telescope file_browser path=%:p:h select_buffer=true<CR>',
--          { desc = 'Open file browser' })
--    end,
-- },

   {
      'nvim-treesitter/nvim-treesitter',
      lazy = true,
      build = ':TSUpdate',
      config = function()
         require('config-treesitter')
      end,
   },

   -- lsp
   { 'mason-org/mason.nvim', config = true },
   {
      'neovim/nvim-lspconfig',
      config = function()
         require('config-lsp')
      end,
   },
   {
      'mason-org/mason-lspconfig.nvim',
      opts = {
         ensure_installed = is_64bit and {
            'rust_analyzer', 'hls', 'ts_ls', 'lua_ls',
         } or {
            'ts_ls',
         },
      },
      dependencies = { 'mason-org/mason.nvim', 'neovim/nvim-lspconfig' },
   },

   {
      'saghen/blink.cmp',
      enabled = jit.arch == 'x64' or jit.arch == 'arm64',
      dependencies = { 'rafamadriz/friendly-snippets' },
      version = '1.*',
      ---@module 'blink.cmp'
      ---@type blink.cmp.Config
      opts = {
         keymap = {
            preset = 'none',
            ['<TAB>']   = { 'select_next', 'fallback' },
            ['<S-TAB>'] = { 'select_prev', 'fallback' },
            ['<C-N>']   = { 'select_next', 'fallback' },
            ['<C-P>']   = { 'select_prev', 'fallback' },
            ['<C-K>']   = { 'show_documentation', 'fallback' },
            ['<C-U>']   = { 'scroll_documentation_up', 'fallback' },
            ['<C-D>']   = { 'scroll_documentation_down', 'fallback' },
            ['<C-C>']   = { 'cancel', 'fallback' },
         },
         appearance = { nerd_font_variant = 'mono' },
         completion = {
            documentation = { auto_show = false },
            menu = {
               auto_show = true,
               draw = {
                  padding = 1,
                  columns = {
                     { 'label', gap = 1 },
                     { 'kind_icon', 'label_description', gap = 1 },
                  },
                  components = {
                     label_description = {
                        text = function(ctx)
                           return ctx.label_description ~= '' and ctx.label_description or ctx.item.detail
                        end,
                     },
                  },
               },
               max_height = 6,
            },
            ghost_text = { enabled = true, show_with_menu = true },
            list = {
               selection = { preselect = false, auto_insert = true },
            },
         },
         cmdline = {
            keymap = { preset = 'inherit' },
            completion = {
               menu = { auto_show = true },
               list = { selection = { preselect = false, auto_insert = true } },
            },
         },
         sources = {
            default = { 'lsp', 'path', 'buffer' },
         },
         signature = { enabled = true },
         fuzzy = { implementation = 'prefer_rust' },
      },
      opts_extend = { 'sources.default' },
   },

-- {
--    'hrsh7th/nvim-cmp',
--    -- load cmp on InsertEnter
--    event = 'InsertEnter',
--    -- these dependencies will only be loaded when cmp loads
--    -- dependencies are always lazy-loaded unless specified otherwise
--    dependencies = {
--       'hrsh7th/cmp-nvim-lsp',
--       'hrsh7th/cmp-buffer',
--       'hrsh7th/cmp-path',
--       'hrsh7th/cmp-cmdline',
--       'hrsh7th/cmp-vsnip',
--       'hrsh7th/vim-vsnip',
--    },
--    config = function()
--       require('config-cmp')
--    end,
-- },
-- {
--    'folke/noice.nvim',
--    event = 'VeryLazy',
--    opts = {
--       -- add any options here
--    },
--    dependencies = {
--       -- if you lazy-load any plugin below, make sure to add proper `module="..."` entries
--       'MunifTanjim/nui.nvim',
--       -- -- OPTIONAL:
--       -- --   `nvim-notify` is only needed, if you want to use the notification view.
--       -- --   If not available, we use `mini` as the fallback
--       -- 'rcarriga/nvim-notify',
--    }
-- },

   -- Swarm LSP (started ad-hoc, not a lazy-managed plugin)
   -- see the vim.lsp.start call below

}, { install = { missing = false } })

-- Swarm LSP — started outside lazy since it's not a plugin
if vim.fn.executable('swarm') == 1 then
   vim.lsp.start({
      name = 'Swarm Language Server',
      cmd  = { 'swarm', 'lsp' },
   })
end

vim.o.clipboard = 'unnamedplus'

-- toggle autosave per buffer
vim.cmd([[
   let g:auto_save = 0
   function BufferAutoSaveToggle()
      if exists('b:auto_save')
         let b:auto_save = !b:auto_save
      else
         let b:auto_save = 1
      endif
      if b:auto_save == 1
         echo 'autosave on'
      else
         echo 'autosave off'
      endif
   endfunction
   command BufferAutoSave call BufferAutoSaveToggle()
   nnoremap <leader>a :BufferAutoSave<cr>
]])

-- focus mode
vim.cmd([[

   let g:limelight_conceal_ctermfg = 240
   let g:limelight_conceal_guifg = '#666666'
   let g:limelight_default_coefficient = 1.0
   let g:limelight_paragraph_span = 0
   let g:limelight_bop = '^\n'
   let g:limelight_eop = '^\n'
   let g:limelight_priority = -1

   nnoremap <leader>L :Limelight!!<cr>
   nnoremap <leader>I :IlluminateToggleBuf<cr>

   let g:focused = 0

   function FocusToggle()
      let g:focused = 1 - g:focused
      if g:focused == 1
         :silent! call FocusOn()
         :silent! call NumbersOff()
         :silent! call YeyOn()
         :Goyo 120
         :echo 'focus on'
      else
         :silent! call FocusOff()
         :silent! call YeyOff()
         :Goyo!
         :echo 'focus off'
      endif
   endfunction

   command Focus call FocusToggle()
   nnoremap <leader>O :Focus<cr>

   let g:yey = 0

   function YeyOn()
      let g:yey = 1
      :nmap j jzz
      :nmap k kzz
      :nmap G Gzz
      :echo 'yey on'
   endfunction

   function YeyOff()
      let g:yey = 0
      :unmap j
      :unmap k
      :unmap G
      :echo 'yey off'
   endfunction

   function YeyToggle()
      if g:yey == 0
         :call YeyOn()
      else
         :call YeyOff()
      endif
   endfunction

   command Yey call YeyToggle()
   nnoremap <leader>Y :Yey<cr>

]])