local OPCODE = 206
local state = { offers = {}, accountTokens = 0, depotTokens = 0 }

local function send(action, data)
  local protocol = g_game.getProtocolGame()
  if protocol then
    protocol:sendExtendedOpcode(OPCODE, json.encode({ action = action, data = data or {} }))
  end
end

local function publishState(message)
  if modules.game_market and modules.game_market.Market then
    modules.game_market.Market.setReperaTokenOffers(state.offers or {}, state.accountTokens or 0,
      state.depotTokens or 0)
  end
  if message and message:len() > 0 then
    g_logger.info('[ReperaMarket] ' .. message)
  end
end

local function onOpcode(protocol, opcode, buffer)
  local ok, msg = pcall(json.decode, buffer)
  if not ok or type(msg) ~= 'table' then return end
  if msg.action == 'sync' then
    state = msg.data or state
    publishState(msg.message)
  end
end

local function onGameStart()
  scheduleEvent(function() send('init') end, 700)
end

local function onGameEnd()
  state = { offers = {}, accountTokens = 0, depotTokens = 0 }
end

function init()
  ProtocolGame.registerExtendedOpcode(OPCODE, onOpcode)
  connect(g_game, { onGameStart = onGameStart, onGameEnd = onGameEnd })
  if g_game.isOnline() then onGameStart() end
end

function terminate()
  disconnect(g_game, { onGameStart = onGameStart, onGameEnd = onGameEnd })
  ProtocolGame.unregisterExtendedOpcode(OPCODE)
end

function refresh()
  send('refresh')
end

function createOffer(itemId, amount, price, clientId, name)
  send('create', {
    itemId = tonumber(itemId), clientId = tonumber(clientId), amount = tonumber(amount),
    price = tonumber(price), currency = 1, name = tostring(name or '')
  })
end

function buyOffer(id, amount)
  send('buy', { id = tonumber(id), amount = tonumber(amount) or 1 })
end

function cancelOffer(id)
  send('cancel', { id = tonumber(id) })
end

function show()
  if modules.game_market and modules.game_market.marketWindow then
    modules.game_market.marketWindow:show()
    refresh()
  end
end

function hide()
  if modules.game_market and modules.game_market.Market then modules.game_market.Market.close() end
end

function toggle() show() end
