local M = {}

function M.dashboard()
    math.randomseed(os.time()) -- For random footer

    local header = {
        type = 'text',
        val = {
            [[<-. (`-')_  (`-')  _                 (`-')  _     <-. (`-')  ]],
            [[   \( OO) ) ( OO).-/     .->        _(OO ) (_)       \(OO )_ ]],
            [[,--./ ,--/ (,------.(`-')----. ,--.(_/,-.\ ,-(`-'),--./  ,-.)]],
            [[|   \ |  |  |  .---'( OO).-.  '\   \ / (_/ | ( OO)|   `.'   |]],
            [[|  . '|  |)(|  '--. ( _) | |  | \   /   /  |  |  )|  |'.'|  |]],
            [[|  |\    |  |  .--'  \|  |)|  |_ \     /_)(|  |_/ |  |   |  |]],
            [[|  | \   |  |  `---.  '  '-'  '\-'\   /    |  |'->|  |   |  |]],
            [[`--'  `--'  `------'   `-----'     `-'     `--'   `--'   `--']],
        },
        opts = {
            position = 'center',
            -- wrap = 'overflow',
            hl = 'DashboardHeader',
        },
    }

    local footers = {
        [[☆*:.｡. o(≧▽≦)o .｡.:*☆]],
        [[°˖✧ ◝(⁰▿⁰)◜✧˖°]],
        [[✿  ♬ ﾟ+.(｡◡‿◡)♪.+ ﾟ♬ ✿ ]],
        [[— ฅ/ᐠ. ̫ .ᐟ\ฅ —]],
        [[/ᐠ_ ꞈ _ᐟ\ɴʏᴀ~]],
        [[૮₍˶ •. • ⑅₎ა]],
        [[︶꒷꒦︶ ๋࣭ ⭑ ૮₍˶• . • ⑅₎ა]],
        [[｡*ﾟ.*.｡(っ ᐛ )っ 𝖍𝖎]],
        [[ₓ ｡ 𐐪₍ᐢ. ̫ .⑅ᐢ₎𐑂↝]],
    }

    local footer = {
        type = 'text',
        val = footers[math.random(#footers)],
        opts = {
            position = 'center',
            hl = 'DashboardFooter',
        },
    }

    local button = function(sc, txt, keybind, keybind_opts)
        local sc_ = sc:gsub('%s', ''):gsub('SPC', '<leader>')

        local opts = {
            position = 'center',
            shortcut = sc,
            cursor = 5,
            width = 50,
            align_shortcut = 'right',
            hl = 'DashboardCenter',
            hl_shortcut = 'DashboardShortcut',
        }
        if keybind then
            keybind_opts = vim.F.if_nil(keybind_opts, { noremap = true, silent = true, nowait = true })
            opts.keymap = { 'n', sc_, keybind, keybind_opts }
        end

        local function on_press()
            local key = vim.api.nvim_replace_termcodes(sc_ .. '<Ignore>', true, false, true)
            vim.api.nvim_feedkeys(key, 'normal', false)
        end

        return {
            type = 'button',
            val = txt,
            on_press = on_press,
            opts = opts,
        }
    end

    local buttons = {
        type = 'group',
        val = {
            button('SPC f g', '  Find word'),
            button('SPC f f', '  Find file'),
            button('SPC f o', '  Recent files'),
            button('SPC f d', 'ﱮ  Recent directories'),
            button('SPC f m', '  Bookmarks'),
            button('SPC f p', '  Projects'),
            button('SPC s l', '  Load last session'),
        },
        opts = { spacing = 1 },
    }

    require('alpha').setup {
        layout = {
            { type = 'padding', val = 6 },
            header,
            { type = 'padding', val = 2 },
            buttons,
            footer,
        },
        opts = {
            margin = 5,
            noautocmd = true,
        },
    }
end

function M.statusline()
    -- Initialize the components table before defining it
    local comps = require('user.modules.ui.components')
    local components = {
        active = {},
        inactive = {},
    }

    table.insert(components.active, {})
    table.insert(components.active, {})
    table.insert(components.active, {})
    table.insert(components.inactive, {})
    table.insert(components.inactive, {})

    table.insert(components.active[1], comps.dummy)
    table.insert(components.active[1], comps.vi_mode)
    table.insert(components.active[1], comps.filesize)
    table.insert(components.active[1], comps.fileinfo)
    table.insert(components.active[1], comps.lineinfo)
    table.insert(components.active[1], comps.percent)
    -- table.insert(components.active[1], comps.gps)
    table.insert(components.active[3], comps.codeact)
    table.insert(components.active[3], comps.diagerr)
    table.insert(components.active[3], comps.diagwarn)
    table.insert(components.active[3], comps.diaghint)
    table.insert(components.active[3], comps.diaginfo)
    table.insert(components.active[3], comps.lspclient)
    table.insert(components.active[3], comps.format)
    table.insert(components.active[3], comps.encode)
    table.insert(components.active[3], comps.filetype)
    table.insert(components.active[3], comps.gitbranch)
    table.insert(components.active[3], comps.diffadd)
    table.insert(components.active[3], comps.diffchange)
    table.insert(components.active[3], comps.diffremove)
    table.insert(components.inactive[1], comps.dummy)
    table.insert(components.inactive[1], comps.fileinfo)
    table.insert(components.inactive[2], comps.filetype)

    require('feline').setup {
        theme = comps.normal_colors,
        components = components,
        vi_mode_colors = comps.vi_mode_colors,
        force_inactive = {
            filetypes = {
                'packer',
                'dashboard',
                'alpha',
                'NvimTree',
                'undotree',
                'DIFF',
                'TROUBLE',
                'Outline',
            },
            buftypes = { 'terminal', 'nofile' },
            bufnames = {},
        },
    }
end

function M.bufferline()
    require('bufferline').setup {
        options = {
            numbers = 'none',
            max_name_length = 16,
            max_prefix_length = 13,
            tab_size = 16,
            diagnostics = false,
            show_close_icon = false,
            show_buffer_icons = true,
            show_tab_indicators = true,
            enforce_regular_tabs = false,
            show_buffer_close_icons = false,
            always_show_bufferline = true,
            offsets = {
                { filetype = 'NvimTree', text = 'NvimTree', text_align = 'center' },
                { filetype = 'packer', text = 'Packer', text_align = 'center' },
            },
            separator_style = 'thin',
        },
        highlights = {
            fill = { guibg = { attribute = 'bg', highlight = 'TabLineFill' } },
            indicator_selected = { guifg = { attribute = 'fg', highlight = 'TabLineSel' } },
        },
    }
end

-- FIX: wait for config migration to setup()
function M.nvimtree()
    local global_options = {
        nvim_tree_indent_markers = 1,
        nvim_tree_git_hl = 1,
        nvim_tree_highlight_opened_files = 1,
        nvim_tree_respect_buf_cwd = 1,
        nvim_tree_icons = {
            default = '',
            symlink = '',
            git = {
                unstaged = '',
                staged = '',
                unmerged = '',
                renamed = '',
                untracked = 'ﱡ',
                deleted = '',
                ignored = '',
            },
            folder = {
                arrow_open = '',
                arrow_closed = '',
                default = '',
                open = 'ﱮ',
                empty = '',
                empty_open = '',
                symlink = '',
                symlink_open = 'ﱮ',
            },
        }
    }
    for key, val in pairs(global_options) do
        vim.g[key] = val
    end

    require('nvim-tree').setup {
        disable_netrw = true,
        open_on_setup = false,
        -- ignore_ft_on_setup  = {'dashboard', 'alpha'},
        auto_close = true,
        open_on_tab = false,
        hijack_cursor = true,
        update_cwd = true,
        hijack_unnamed_buffer_when_opening = false,
        hijack_directories = {
            enable = false,
            auto_open = true,
        },
        diagnostics = {
            enable = true,
            icons = {
                hint = '',
                info = '',
                warning = '',
                error = '',
            },
        },
        update_focused_file = {
            enable = true,
            update_cwd = true,
            ignore_list = {},
        },
        system_open = {
            cmd = 'xdg-open',
            args = {},
        },
        filters = {
            dotfiles = false,
            custom = { '.git', '.hg', '.svn', 'node_modules' },
        },
        git = {
            enable = true,
            ignore = false,
            timeout = 500,
        },
        view = {
            width = 35,
            hide_root_folder = false,
            side = 'left',
            preserve_window_proportions = false,
            number = false,
            relativenumber = false,
        },
        actions = {
            change_dir = {
                enable = true,
                global = false,
            },
            open_file = {
                quit_on_open = false,
                resize_window = false,
                window_picker = {
                    enable = true,
                    -- Match the characters of window-picker.nvim
                    chars = 'ALSKDJFHGWOEIRUTY',
                    exclude = {
                        filetype = { 'notify', 'packer', 'qf', 'diff', 'fugitive', 'fugitiveblame', },
                        buftype  = { 'nofile', 'terminal', 'help', },
                    },
                },
            },
        },
    }
end

return M
