local M = {}
local colors = require('user.themes.' .. vim.g.colors_name .. '.colors')
local vi_mode_utils = require('feline.providers.vi_mode')

local function file_osinfo()
    local os = vim.bo.fileformat:upper()
    local icon = {}
    if os == 'UNIX' then
        icon = ' '
    elseif os == 'MAC' then
        icon = ' '
    else
        icon = ' '
    end
    return icon .. os
end

local function buffer_not_empty()
    if vim.fn.empty(vim.fn.expand('%:t')) ~= 1 then
        return true
    end
    return false
end

local function is_lsp_attached()
    return next(vim.lsp.buf_get_clients(0)) ~= nil
end

local function lsp_active_clients()
    local clients = {}

    -- Typical lsp clients
    for _, client in pairs(vim.lsp.buf_get_clients(0)) do
        if client.name ~= 'null-ls' then
            table.insert(clients, client.name)
        end
    end

    -- null-ls sources
    local sources = {}
    local null_ls_sources = require('null-ls.sources')
    local ft = vim.api.nvim_buf_get_option(0, 'ft')
    for _, source in ipairs(null_ls_sources.get_available(ft)) do
        table.insert(sources, source.name)
    end
    -- filter duplicated entries
    local sources_post = {}
    for i = 1, #sources do
        if not sources_post[sources[i]] then
            table.insert(clients, sources[i])
            sources_post[sources[i]] = true
        end
    end

    return table.concat(clients, ', ')
end

-- Default colors for statusline --
M['normal_colors'] = { bg = colors.grey1, fg = colors.fg }
M['vi_mode_colors'] = {
    NORMAL = colors.green,
    OP = colors.green,
    INSERT = colors.blue,
    VISUAL = colors.yellow,
    LINES = colors.yellow,
    BLOCK = colors.yellow,
    REPLACE = colors.red,
    ['V-REPLACE'] = colors.red,
    ENTER = colors.cyan,
    MORE = colors.cyan,
    SELECT = colors.orange,
    COMMAND = colors.purple,
    SHELL = colors.green,
    TERM = colors.green,
    NONE = colors.white2,
}

-- Components --
M['dummy'] = {
    provider = '▊',
    hl = { fg = colors.blue },
    right_sep = ' ',
}

M['vi_mode'] = {
    provider = ' ',
    hl = function()
        return {
            name = vi_mode_utils.get_mode_highlight_name(),
            fg = vi_mode_utils.get_mode_color(),
        }
    end,
    right_sep = ' ',
}

M['filesize'] = {
    provider = 'file_size',
    enabled = buffer_not_empty,
    hl = { fg = colors.fg, style = 'bold' },
    right_sep = ' ',
}

M['fileinfo'] = {
    provider = {
        name = 'file_info',
        opts = {
            file_modified_icon = ' ',
            file_readonly_icon = ' ',
            type = 'base-only',
        },
    },
    enabled = buffer_not_empty,
    hl = { fg = colors.blue, style = 'bold' },
    right_sep = ' ',
}

M['lineinfo'] = {
    provider = 'position',
    hl = { fg = colors.fg },
    right_sep = ' ',
}

M['percent'] = {
    provider = 'line_percentage',
    hl = { fg = colors.fg, style = 'bold' },
    right_sep = '  ',
}

-- M['gps'] = {
--     provider = function()
--         return require('nvim-gps').get_location()
--     end,
--     enabled = function()
--         local gps_present, gps = pcall(require, 'nvim-gps')
--         if gps_present then
--             return gps.is_available()
--         else
--             return false
--         end
--     end,
--     hl = { fg = colors.cyan },
-- }

M['codeact'] = {
    provider = function()
        return require('nvim-lightbulb').get_status_text()
    end,
    enabled = function()
        local lightbulb_present, _ = pcall(require, 'nvim-lightbulb')
        return lightbulb_present
    end,
    hl = { fg = colors.green, style = 'bold' },
}

M['diagerr'] = {
    provider = 'diagnostic_errors',
    icon = ' ',
    enabled = is_lsp_attached,
    hl = { fg = colors.red },
    left_sep = ' ',
}

M['diagwarn'] = {
    provider = 'diagnostic_warnings',
    icon = ' ',
    enabled = is_lsp_attached,
    hl = { fg = colors.yellow },
    left_sep = ' ',
}

M['diaghint'] = {
    provider = 'diagnostic_hints',
    icon = ' ',
    enabled = is_lsp_attached,
    hl = { fg = colors.cyan },
    left_sep = ' ',
}

M['diaginfo'] = {
    provider = 'diagnostic_info',
    icon = ' ',
    enabled = is_lsp_attached,
    hl = { fg = colors.blue },
    left_sep = ' ',
}

M['lspclient'] = {
    provider = lsp_active_clients,
    enabled = is_lsp_attached,
    icon = ' LSP:',
    hl = { fg = colors.purple, style = 'bold' },
    left_sep = '  ',
}

M['format'] = {
    provider = file_osinfo,
    hl = { fg = colors.cyan },
    left_sep = '  ',
}

M['encode'] = {
    provider = 'file_encoding',
    hl = { fg = colors.fg },
    left_sep = ' ',
}

M['filetype'] = {
    provider = 'file_type',
    hl = { fg = colors.blue, style = 'bold' },
    left_sep = '  ',
}

M['gitbranch'] = {
    provider = 'git_branch',
    icon = ' ',
    hl = { fg = colors.green, style = 'bold' },
    left_sep = '  ',
}

M['diffadd'] = {
    provider = 'git_diff_added',
    icon = ' ',
    hl = { fg = colors.green },
    left_sep = ' ',
}

M['diffchange'] = {
    provider = 'git_diff_changed',
    icon = '柳',
    hl = { fg = colors.yellow },
    left_sep = ' ',
}

M['diffremove'] = {
    provider = 'git_diff_removed',
    icon = ' ',
    hl = { fg = colors.red },
    left_sep = ' ',
}

return M
