local OPCODE = 207
local window
local controlWindow
local permissionRows={}
local activeCastleId=1

local function ui(id) return window and window:recursiveGetChildById(id) end
local function cui(id) return controlWindow and controlWindow:recursiveGetChildById(id) end
local function formatNumber(value)
  local text=tostring(value or 0)
  while true do local changed;text,changed=text:gsub('^(-?%d+)(%d%d%d)','%1,%2');if changed==0 then break end end
  return text
end
local function send(action, amount)
  local protocol=g_game.getProtocolGame()
  if not protocol then return end
  local option=ui('currency'):getCurrentOption()
  protocol:sendExtendedOpcode(OPCODE,json.encode({action=action,castleId=activeCastleId,data={
    amount=tonumber(amount) or 0,currency=option and option.data or 'gold'}}))
end
local function onOpcode(protocol,opcode,buffer)
  local ok,msg=pcall(json.decode,buffer)
  if not ok or type(msg)~='table' then return end
  local data=msg.data or {}
  activeCastleId=tonumber(msg.castleId) or 1
  if msg.action=='control' then
    permissionRows={}
    local list=cui('memberList');list:destroyChildren()
    for _,member in ipairs(data.members or {}) do
      local row=g_ui.createWidget('CastlePermissionRow',list)
      row.memberName:setText(member.name or ('Player #'..tostring(member.id)))
      row.bank:setChecked(member.bank==true)
      row.depot:setChecked(member.depot==true)
      row.playerId=member.id
      permissionRows[#permissionRows+1]=row
    end
    cui('notice'):setText(msg.message or '')
    controlWindow:show();controlWindow:raise();controlWindow:focus()
    return
  end
  if msg.action~='sync' then return end
  ui('guildName'):setText((data.guild or 'Guild')..' - Castle Bank')
  ui('goldBalance'):setText('Guild Gold Balance: '..formatNumber(data.gold))
  ui('tokenBalance'):setText('Guild RP Balance: '..formatNumber(data.tokens)..' Repera Tokens')
  ui('carried'):setText('You carry: '..formatNumber(data.playerGold)..' gold | '..formatNumber(data.playerTokens)..' RP')
  ui('notice'):setText(msg.message or '')
  window:show();window:raise();window:focus()
end
function init()
  ProtocolGame.registerExtendedOpcode(OPCODE,onOpcode)
  window=g_ui.displayUI('castle_bank');window:hide()
  controlWindow=g_ui.displayUI('castle_control');controlWindow:hide()
  ui('currency'):addOption('Gold (GP)','gold')
  ui('currency'):addOption('Repera Tokens (RP)','token')
  ui('deposit').onClick=function() send('deposit',ui('depositAmount'):getText()) end
  ui('withdraw').onClick=function() send('withdraw',ui('withdrawAmount'):getText()) end
  ui('close').onClick=hide
  cui('save').onClick=function()
    local members={}
    for _,row in ipairs(permissionRows) do members[#members+1]={id=row.playerId,bank=row.bank:isChecked(),depot=row.depot:isChecked()} end
    local protocol=g_game.getProtocolGame();if protocol then protocol:sendExtendedOpcode(OPCODE,json.encode({action='save_permissions',castleId=activeCastleId,data={members=members}})) end
  end
  cui('close').onClick=hideControl
end
function terminate()
  ProtocolGame.unregisterExtendedOpcode(OPCODE)
  if window then window:destroy();window=nil end
  if controlWindow then controlWindow:destroy();controlWindow=nil end
end
function hideControl() if controlWindow then controlWindow:hide() end end
function hide()
  if window then window:hide() end
  local protocol=g_game.getProtocolGame();if protocol then protocol:sendExtendedOpcode(OPCODE,json.encode({action='close',castleId=activeCastleId})) end
end
