local M = {}

function M.colorizer_conf()
    require('colorizer').setup(
    {'*'},
    {
        RGB      = true,         -- #RGB hex codes
        RRGGBB   = true,         -- #RRGGBB hex codes
        names    = true,         -- "Name" codes like Blue
        RRGGBBAA = true,         -- #RRGGBBAA hex codes
        rgb_fn   = true,         -- CSS rgb() and rgba() functions
        hsl_fn   = true,         -- CSS hsl() and hsla() functions
        css      = true,         -- Enable all CSS features: rgb_fn, hsl_fn, names, RGB, RRGGBB
        css_fn   = true,         -- Enable all CSS *functions*: rgb_fn, hsl_fn
        mode     = 'background'  -- Set the display mode.
    })
end

function M.illuminate_conf()
    vim.g.Illuminate_delay = 500
    vim.g.Illuminate_ftblacklist = {'alpha', 'NvimTree', 'undotree', 'packer'}
end

function M.blankline_conf()
    require('indent_blankline').setup {
        char = '│',
        -- space_char_blankline = '·',
        show_first_indent_level = true,
        filetype_exclude = {
            'startify', 'dashboard', 'alpha', 'log', 'gitcommit', 'packer', 'vimwiki',
            'markdown', 'org', 'json', 'txt', 'help', 'NvimTree', 'git', 'TelescopePrompt',
            'undotree', 'dotooagenda', 'fugitive',
            '' -- for all buffers without a filetype
        },
        buftype_exclude = {'terminal', 'nofile'},
        show_trailing_blankline_indent = false,
        -- show_end_of_line = true,
        show_current_context = true,
        context_patterns = {
            'class', 'function', 'method', 'block', 'list_literal', 'selector', '^if',
            '^table', 'if_statement', 'while', 'for'
        },
        use_treesitter = true
    }

    -- Refresh often, since it is lazy-loaded
    -- vim.api.nvim_command('autocmd CursorMoved * IndentBlanklineRefresh')
end

-- function M.aniseed_conf()
--     -- Compile fennel config to lua on startup
--     require('aniseed.env').init()
-- end

function M.treesitter_conf()
    -- Additional parser for rest.nvim (*.http files)
    local parser_configs = require('nvim-treesitter.parsers').get_parser_configs()
    parser_configs.http = {
        install_info = {
            url = 'https://github.com/NTBBloodbath/tree-sitter-http',
            files = {'src/parser.c'},
            branch = 'main'
        }
    }

    require('nvim-treesitter.configs').setup {
        ensure_installed = 'maintained',
        highlight = {enable = true},
        incremental_selection = {
            enable = true,
            keymaps = {
                init_selection = 'gni',
                node_incremental = 'gnn',
                scope_incremental = 'gns',
                node_decremental = 'gnm'
            }
        },
        -- indent = {enable = true},
        textobjects = {
            select = {
                enable = true,
                lookahead = true,
                keymaps = {
                    ['af'] = '@function.outer',
                    ['if'] = '@function.inner',
                    ['ac'] = '@class.outer',
                    ['ic'] = '@class.inner'
                }
            },
            move = {
                enable = true,
                set_jumps = true, -- whether to set jumps in the jumplist
                goto_next_start = {
                    [']['] = '@function.outer',
                    [']m'] = '@class.outer'
                },
                goto_next_end = {
                    [']]'] = '@function.outer',
                    [']M'] = '@class.outer'
                },
                goto_previous_start = {
                    ['[['] = '@function.outer',
                    ['[m'] = '@class.outer'
                },
                goto_previous_end = {
                    ['[]'] = '@function.outer',
                    ['[M'] = '@class.outer'
                }
            }
        },
        matchup = {enable = true},
        rainbow = {
            enable = true,
            extended_mode = true,
            max_file_lines = 1000
        },
        playground = {
            enable = true,
            disable = {},
            updatetime = 25,
            persist_queries = false,
            keybindings = {
                toggle_query_editor = 'o',
                toggle_hl_groups = 'i',
                toggle_injected_languages = 't',
                toggle_anonymous_nodes = 'a',
                toggle_language_display = 'I',
                focus_language = 'f',
                unfocus_language = 'F',
                update = 'R',
                goto_node = '<cr>',
                show_help = '?'
            }
        },
        query_linter = {
            enable = true,
            use_virtual_text = true,
            lint_events = {'BufWrite', 'CursorHold'}
        }
    }

    -- tree-sitter based folding
    vim.opt.foldmethod = 'expr'
    vim.opt.foldexpr = 'nvim_treesitter#foldexpr()'
end

function M.iswap_conf()
    require('iswap').setup {
        -- The keys that will be used as a selection, in order
        -- ('asdfghjklqwertyuiopzxcvbnm' by default)
        -- keys = 'qwertyuiop',

        -- Grey out the rest of the text when making a selection
        -- (enabled by default)
        -- grey = 'disable',

        -- Highlight group for the sniping value (asdf etc.)
        -- default 'Search'
        -- hl_snipe = 'ErrorMsg',

        -- Highlight group for the visual selection of terms
        -- default 'Visual'
        -- hl_selection = 'WarningMsg',

        -- Highlight group for the greyed background
        -- default 'Comment'
        hl_grey = 'LineNr',

        -- Automatically swap with only two arguments
        -- default nil
        autoswap = true
    }
end

function M.matchup_conf()
    vim.g.matchup_matchparen_offscreen = {method = 'popup'}
end

function M.twilight_conf()
    require('twilight').setup {
        dimming = {
            alpha = 0.25, -- amount of dimming
            -- we try to get the foreground from the highlight groups or fallback color
            color = {'Normal', '#ffffff'},
            inactive = false -- when true, other windows will be fully dimmed (unless they contain the same buffer)
        },
        context = 10,
        treesitter = true,
        expand = { -- for treesitter, we we always try to expand to the top-most ancestor with these types
            'function',
            'method',
            'table',
            'if_statement'
        },
        exclude = {'alpha', 'packer', 'NvimTree', 'qf'}
    }
end

function M.zenmode_conf()
    require('zen-mode').setup {
        window = {
            options = {
                signcolumn = 'no',
                number = false,
                relativenumber = false,
                cursorline = false,
                cursorcolumn = false,
                foldcolumn = '0'
            }
        },
        -- on_open = function()
        --     vim.api.nvim_command('TSContextDisable')
        --     vim.api.nvim_command('IndentBlanklineDisable')
        -- end,
        -- on_close = function()
        --     vim.api.nvim_command('TSContextEnable')
        --     vim.api.nvim_command('IndentBlanklineEnable')
        -- end
    }
end

function M.betterescape_conf()
    require('better_escape').setup {
        mapping = {'jk', 'kj'},
        timeout = vim.opt.timeoutlen:get(),
        clear_empty_lines = false,
        keys = '<Esc>'
    }
end

function M.hop_conf()
    require('hop').setup {keys = 'etovxqpdygfblzhckisuran'}
end

function M.eft_conf()
    vim.g.eft_index_function = {all = function() return true end}

    -- Mappings
    vim.api.nvim_set_keymap('n', 'f', '<Plug>(eft-f)', {silent = true})
    vim.api.nvim_set_keymap('x', 'f', '<Plug>(eft-f)', {silent = true})
    vim.api.nvim_set_keymap('n', 'F', '<Plug>(eft-F)', {silent = true})
    vim.api.nvim_set_keymap('x', 'F', '<Plug>(eft-F)', {silent = true})
    vim.api.nvim_set_keymap('n', 't', '<Plug>(eft-t)', {silent = true})
    vim.api.nvim_set_keymap('x', 't', '<Plug>(eft-t)', {silent = true})
    vim.api.nvim_set_keymap('n', 'T', '<Plug>(eft-T)', {silent = true})
    vim.api.nvim_set_keymap('x', 'T', '<Plug>(eft-T)', {silent = true})
    vim.api.nvim_set_keymap('n', ';', '<Plug>(eft-repeat)', {silent = true})
    vim.api.nvim_set_keymap('x', ';', '<Plug>(eft-repeat)', {silent = true})
end

function M.dial_conf()
    local dial = require('dial')

    -- Custom augends
    dial.augends['custom#boolean'] = dial.common.enum_cyclic{
        name = 'boolean',
        strlist = {'true', 'false'}
    }
    dial.augends['custom#boolean2'] = dial.common.enum_cyclic{
        name = 'boolean',
        strlist = {'True', 'False'}
    }

    dial.config.searchlist.normal = {
        'number#decimal#int',
        'number#decimal#fixed#zero',
        'number#hex',
        'number#binary',
        'date#[%Y/%m/%d]',
        'date#[%m/%d]',
        'date#[%Y-%m-%d]',
        'date#[%H:%M:%S]',
        'date#[%H:%M]',
        'date#[%jA]',
        'color#hex',
        'markup#markdown#header',
        'custom#boolean',
        'custom#boolean2'
    }
    dial.config.searchlist.visual = {
        'number#decimal#int',
        'number#decimal#fixed#zero',
        'number#hex',
        'number#binary',
        'date#[%Y/%m/%d]',
        'date#[%m/%d]',
        'date#[%Y-%m-%d]',
        'date#[%H:%M:%S]',
        'date#[%H:%M]',
        'date#[%jA]',
        'char#alph#small#word',
        'char#alph#capital#word',
        'color#hex'
    }

    -- Mappings
    vim.api.nvim_set_keymap('n', '<C-a>', '<Plug>(dial-increment)', {silent = true})
    vim.api.nvim_set_keymap('v', '<C-a>', '<Plug>(dial-increment)', {silent = true})
    vim.api.nvim_set_keymap('n', '<C-x>', '<Plug>(dial-decrement)', {silent = true})
    vim.api.nvim_set_keymap('v', '<C-x>', '<Plug>(dial-decrement)', {silent = true})
    vim.api.nvim_set_keymap('v', 'g<C-a>', '<Plug>(dial-increment-additional)', {silent = true})
    vim.api.nvim_set_keymap('v', 'g<C-x>', '<Plug>(dial-decrement-additional)', {silent = true})
end

function M.comment_conf()
    require('nvim_comment').setup {comment_empty = false}
end

function M.neogen_conf()
    require('neogen').setup {
        enabled = true,
        input_after_comment = true,
        jump_map = '<C-e>'
    }

    -- Mappings
    vim.api.nvim_set_keymap('n', '<leader>eg', ':lua require("neogen").generate()<CR>', {noremap = true, silent = true})
end

function M.project_conf()
    require('project_nvim').setup {
        manual_mode = false,
        detection_methods = {'lsp', 'pattern'},
        patterns = {'.git', '_darcs', '.hg', '.bzr', '.svn', 'Makefile', 'package.json', '*.pro', 'Dockerfile', '>Code'},
        show_hidden = true,
        silent_chdir = true,
        datapath = vim.fn.stdpath('data')
    }

    -- cd on local window changes with 'lcd' (more eager)
    -- see https://github.com/ahmedkhalf/project.nvim/issues/23
    -- _G.set_window_project_dir = function()
    --     local root, _ = require('project_nvim.project').get_project_root()
    --     if root then
    --         vim.api.nvim_command('lcd ' .. root)
    --     end
    -- end
    -- vim.api.nvim_command('autocmd BufEnter * lua set_window_project_dir()')
end

function M.gitlinker_conf()
    require('gitlinker').setup {
        opts = {
            remote = nil, -- force the use of a specific remote
            -- adds current line nr in the url for normal mode
            add_current_line_on_normal_mode = true,
            -- callback for what to do with the url
            action_callback = require('gitlinker.actions').copy_to_clipboard,
            -- print the url after performing the action
            print_url = true,
        },
        callbacks = {
            ['git.folliehiyuki.com'] = require('gitlinker.hosts').get_gitea_type_url,
            ['git.disroot.org'] = require('gitlinker.hosts').get_gitea_type_url,
            ['gitlab.alpinelinux.org'] = require('gitlinker.hosts').get_gitlab_type_url
        },
        -- default mapping to call url generation with action_callback
        mappings = '<leader>gy'
    }

    -- Mapping to get remote url
    vim.api.nvim_set_keymap('n', '<leader>gY', ':lua require("gitlinker").get_repo_url()<CR>', {noremap = true, silent = true})
end

return M
