--This file should have all functions that are in the public api and either set
--or read the state of this source.

local utils = require("neo-tree.utils")
local renderer = require("neo-tree.ui.renderer")
local items = require("neo-tree.sources.git_status.lib.items")
local events = require("neo-tree.events")
local manager = require("neo-tree.sources.manager")

---@class neotree.sources.GitStatus : neotree.Source
local M = {
  name = "git_status",
  display_name = " 󰊢 Git ",
}

local wrap = function(func)
  return utils.wrap(func, M.name)
end

local get_state = function()
  return manager.get_state(M.name)
end

---Navigate to the given path.
---@param path string Path to navigate to. If empty, will navigate to the cwd.
M.navigate = function(state, path, path_to_reveal, callback, async)
  state.path = path or state.path
  state.dirty = false
  if path_to_reveal then
    renderer.position.set(state, path_to_reveal)
  end
  items.get_git_status(state)

  if type(callback) == "function" then
    vim.schedule(callback)
  end
end

M.refresh = function()
  manager.refresh(M.name)
end

---@class neotree.Config.GitStatus.Renderers : neotree.Config.Renderers

---@class (exact) neotree.Config.GitStatus : neotree.Config.Source
---@field bind_to_cwd boolean?
---@field renderers neotree.Config.GitStatus.Renderers?

---Configures the plugin, should be called before the plugin is used.
---@param config neotree.Config.GitStatus Configuration table containing any keys that the user
--wants to change from the defaults. May be empty to accept default values.
M.setup = function(config, global_config)
  if config.before_render then
    --convert to new event system
    manager.subscribe(M.name, {
      event = events.BEFORE_RENDER,
      handler = function(state)
        local this_state = get_state()
        if state == this_state then
          config.before_render(this_state)
        end
      end,
    })
  end

  if global_config.enable_refresh_on_write then
    manager.subscribe(M.name, {
      event = events.VIM_BUFFER_CHANGED,
      handler = function(args)
        if utils.is_real_file(args.afile) then
          M.refresh()
        end
      end,
    })
  end

  if config.bind_to_cwd then
    manager.subscribe(M.name, {
      event = events.VIM_DIR_CHANGED,
      handler = M.refresh,
    })
  end

  if global_config.enable_diagnostics then
    manager.subscribe(M.name, {
      event = events.STATE_CREATED,
      handler = function(state)
        state.diagnostics_lookup = utils.get_diagnostic_counts()
      end,
    })
    manager.subscribe(M.name, {
      event = events.VIM_DIAGNOSTIC_CHANGED,
      handler = wrap(manager.diagnostics_changed),
    })
  end

  --Configure event handlers for modified files
  if global_config.enable_modified_markers then
    manager.subscribe(M.name, {
      event = events.VIM_BUFFER_MODIFIED_SET,
      handler = wrap(manager.opened_buffers_changed),
    })
  end

  manager.subscribe(M.name, {
    event = events.GIT_EVENT,
    handler = M.refresh,
  })
end

return M
