local nio = require("nio")
local git = require("functions.git")
local fs = require("functions.fs")

vim.api.nvim_create_user_command("Optolith", function()
  local LAUNCH_COMMAND = vim.fs.normalize("~/.local/share/appimages/OptolithInsider.AppImage")
  local OPTOLITH_DIRECTORY = "~/.config/Optolith Insider"

  local picker = Snacks.picker.get({ source = "explorer" })
  local currentHeroFile = picker[1]:current().file

  if currentHeroFile:find(".opto$") == nil then
    vim.notify("Invalid hero", "error", {
      title = "Optolith",
    })
    return
  end

  local absOptolithDirectory = vim.fs.normalize(OPTOLITH_DIRECTORY)
  if vim.fn.isdirectory(absOptolithDirectory) == 0 then
    vim.notify("Can't find folder. Please start the application once.\nFolder: " .. OPTOLITH_DIRECTORY, "error", {
      title = "Optolith",
    })
    return
  end

  local heroesPath = vim.fs.joinpath(absOptolithDirectory, "heroes.json")
  local heroesGlob = vim.fn.glob(heroesPath)
  local heroesFileExists = vim.fn.empty(heroesGlob) == 0
  if heroesFileExists and vim.fn.filewritable(heroesPath) == 0 then
    vim.notify("Can't modify heroes file... Can't inject hero.", "error", {
      title = "Optolith",
    })
    return
  end

  local swapFileExists = vim.fn.empty(vim.fn.glob(heroesPath .. ".swp")) == 0
  if swapFileExists then
    vim.notify("Swap file already exists. To prevent data loss, please restore the swap file.", "error", {
      title = "Optolith",
    })
    return
  end
  if heroesFileExists then
    local mvCommand = os.execute(string.format('mv "%s" "%s.swp"', heroesPath, heroesPath))
    if mvCommand ~= 0 then
      vim.notify("Can not move heroes file.", "error", {
        title = "Optolith",
      })
      return
    end
    swapFileExists = true
  end

  local linkCommand = os.execute(string.format('ln -s "%s" "%s"', currentHeroFile, heroesPath))
  if linkCommand ~= 0 then
    vim.notify("Can't create link...", "error", {
      title = "Optolith",
    })
    return
  end

  -- If the file is just one character, its not a valid heroes.json file.
  -- So we need to create a valid file.
  local file = table.concat(vim.fn.readfile(currentHeroFile))
  local fileData = vim.fn.json_decode(file)
  if fileData["id"] ~= nil then
    local newData = {}
    newData[fileData["id"]] = fileData
    vim.fn.writefile({ vim.fn.json_encode(newData) }, currentHeroFile)
  end

  local task = nio.run(function()
    local process = nio.process.run({
      cmd = LAUNCH_COMMAND,
    })

    process.result()
  end, function()
    os.remove(heroesPath)
    if swapFileExists then
      os.execute(string.format('mv "%s.swp" "%s"', heroesPath, heroesPath))
    end

    git.commitFile(currentHeroFile)
  end)
end, {})
