local naughty    = require("naughty")
local wibox      = require("wibox")
local json       = require("lanxu/dkjson")
local gears      = require("gears")
local focused    = require("awful.screen").focused
local easy_async = require("awful.spawn").easy_async

local function factory(args)
  local args = args or {}
  local timeout     = args.timeout or 600
  local calluri     = args.uri or "https://masa.dy.fi/api/games/stats/minecraft/?type=server_status"
  local minecraft   = { widget = wibox.widget.textbox() }
  local settings    = args.settings or function() end
  local hideempty   = args.hideempty or false  
  local hideoffline = args.hideoffline or true
  local followtag   = args.followtag or true
  local notification_preset = args.notification_preset or { font = "Monospace 10" }

  minecraft.widget:set_markup("N/A")

  function minecraft.show(tout)
    minecraft.hide()

    if followtag then
      notification_preset.screen = focused()
    end

    minecraft.notification = naughty.notify({
        text = minecraft.notification_text,
        -- icon = minecraft.icon
        timeout = 0,
        preset = notification_preset,
      })
  end

  function minecraft.hide()
    if minecraft.notification then
      naughty.destroy(minecraft.notification)
    end
  end

  function minecraft.attach(obj)
    obj:connect_signal("mouse::enter", function()
      minecraft.show()
    end)

    obj:connect_signal("mouse::leave", function()
      minecraft.hide()
    end)

    obj:connect_signal("button::press", function()
      minecraft.update()
      minecraft.show()
    end)
  end

  function minecraft.update()
    local cmd = string.format("curl -s " .. "'" .. calluri .. "'")

    easy_async(cmd, function(response, stderr, reason, exit_code)
      local obj, pos, err = json.decode(response, 1, nil)

      totalplayers = 0

      if not err then
        -- First get the length of the longest server name, for proper column alignment
        local max_len = 6 -- Initialize to the length of "Server"
        for k, v in pairs(obj) do
          if (tonumber(v.num_players) > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
            local tmp = string.len(v.server_name)
            if tmp > max_len then
              max_len = tmp
            end
          end
        end

        local fmt = string.format("%%-%ds %%-8s %%-7s\n", max_len)
        local text = string.format(fmt, "Server", "Version", "Players")

        for k, v in pairs(obj) do
          local players = tonumber(v.num_players)

          if (players > 0 or not hideempty) and (v.status == "online" or not hideoffline) then
            text = text .. string.format(fmt, v.server_name, v.version, v.num_players)

            if v.players then
              for i, p in pairs(v.players) do
                text = text .. '  > ' .. p .. '\n'
              end
            end
          end

          totalplayers = totalplayers + players
        end

        minecraft.notification_text = text
        minecraft.totalplayers = totalplayers;
        widget = minecraft.widget
        settings()
      end
    end)
  end

  minecraft.attach(minecraft.widget)
  gears.timer {
    timeout   = timeout,
    autostart = true,
    callback  = minecraft.update
  }

  minecraft.update()

  return minecraft
end

return factory
