local config = nil
local internal = require("wikiplugin_internal")

local function setup(config_local)
    local function check_key_present(key)
        if config_local[key] == nil then
            error("wikiplugin setup config missing key '" .. key .. "'")
        end
    end
    check_key_present('home_path')
    check_key_present('note_id_timestamp_format')
    check_key_present('date_format')
    check_key_present('time_format')

    config = config_local

    local autocmd_fname_pattern = vim.fn.fnamemodify(config_local.home_path, ":p") .. "*" -- use :p to make sure that there is a / at the end because the autocommand wont work if the path has a double slash
    local augroup = vim.api.nvim_create_augroup("wikiplugin", {})
    vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead", "BufWritePre" }, {
        group = augroup,
        pattern = autocmd_fname_pattern,
        callback = function(ev)
            internal.regenerate_autogenerated_sections(config)
        end,
    })
end

local function insert_link_attach_mappings(prompt_bufnr, map)
    local actions = require "telescope.actions"
    local action_state = require "telescope.actions.state"

    actions.select_default:replace(function()
        actions.close(prompt_bufnr)
        local selection = action_state.get_selected_entry()
        local note_path
        if selection then
            note_path = selection.note_path or selection.path or nil
        else
            note_path = nil
        end

        internal.insert_link_to_path_at_cursor_or_create(config, note_path, nil)
    end)
    return true
end
local function search_by_title(attach_mappings, opts)
    local pickers = require "telescope.pickers"
    local finders = require "telescope.finders"
    local conf = require("telescope.config").values

    opts = opts or {}
    pickers.new(opts, {
        prompt_title = "search notes by title",

        finder = finders.new_table({
            results = internal.list_notes_and_titles_for_search(config),
            entry_maker = function(x) return x end,
        }),
        sorter = conf.generic_sorter(opts),
        previewer = conf.grep_previewer(opts),

        attach_mappings = attach_mappings,
    }):find()
end
local function search_by_content(attach_mappings, opts)
    local pickers = require "telescope.pickers"
    local finders = require "telescope.finders"
    local conf = require("telescope.config").values

    opts = opts or {}
    pickers.new(opts, {
        prompt_title = "search notes by content",

        finder = finders.new_table({
            results = internal.list_notes_lines_for_search(config),
            entry_maker = function(x) return x end,
        }),
        sorter = conf.generic_sorter(opts),
        previewer = conf.grep_previewer(opts),

        attach_mappings = attach_mappings,
    }):find()
end
local function insert_link_by_title()
    search_by_title(insert_link_attach_mappings)
end
local function insert_link_by_content()
    search_by_content(insert_link_attach_mappings)
end

return {
    setup = setup,

    new_note = function(directories, focus) internal.new_note(config, nil, directories, focus) end,
    new_note_from_template = function(template, directories, focus) internal.new_note(config, template, directories, focus) end,
    open_index = function() internal.open_index(config) end,
    new_note_and_insert_link = function() internal.new_note_and_insert_link(config, nil, {}) end, -- TODO: figure out a way to allow the user control over these arguments without having to put it everywhere
    delete_note = function() internal.delete_note(config) end,
    open_tag_index = function() internal.open_tag_index(config) end,
    follow_link = function() internal.follow_link(config) end,
    regenerate_autogenerated_sections = function() internal.regenerate_autogenerated_sections(config) end,
    search_by_title = search_by_title,
    search_by_content = search_by_content,
    insert_link_by_title = insert_link_by_title,
    insert_link_by_content = insert_link_by_content,
}
