-----------------------------------
--This file contains all the miscellaneous changes for Event Horizons's UI
-----------------------------------

(function()

  local topics = require('lib_ui_topics')
  --ocal utils = require('lib_utils')
  --local datasaver = require('lib_data_saver')

  --In pilot select also make sure the "select" text uses select positive rather than negative
  topics.pilotselect.initialize:bind(9999, function(message, context)
    local el = message.Document:GetElementById("playercommit_img").next_sibling
    el:SetClass("neg", false)
    el:SetClass("pos", true)
  end)

  --In control config change "targeting" to "controls"
  topics.controlconfig.initialize:bind(9999, function(message, context)
    local el = message.Document:GetElementById("target_img").next_sibling.first_child
    el.inner_rml = ba.XSTR("Controls", -1)
  end)


  -- Loading Screen Changes for Logo_Wide
  topics.loadscreen.initialize:bind(9999, function(message, context)
    local el = message.Document:GetElementById("logo_wide")
    el:SetClass("hidden", true)
    local el = message.Document:GetElementById("title")
    el:SetClass("hidden", true)
  end)

  -- Decide whether to show a mission in the campaign mission list based on the filename
  topics.simulator.listCampaign:bind(9999, function(message, context)
    local hidden_missions = {
      "LW_Mission_04_zbranch.fs2",
      "LW_Mission_05A_zbranch.fs2",
      "LW_Mission_05B_zbranch.fs2",
      "LW_Mission_07_zbranch.fs2",

      "SC_Mission_02_zbranch.fs2",
      "SC_Mission_04K_zbranch.fs2",
      "SC_Mission_04T_zbranch.fs2",
      "SC_Mission_05K_zbranch.fs2",
      "SC_Mission_05T_zbranch.fs2"
    }

    -- Loop through each mission name in the hidden_missions table
    for _, mission_name in ipairs(hidden_missions) do
        -- Check if the incoming message matches the current mission name
        if message == mission_name then
            -- If it's a match, set context to false and stop checking
            context.value = false
            break
        end
    end
  end)

  -- Map character names to portrait image names
    local portrait_defines = {
      ["Fox"] = "briefportrait_fox",
      ["Falco"] = "briefportrait_falco",
      ["Slippy"] = "briefportrait_slippy",
      ["Peppy"] = "briefportrait_peppy",
      ["Krystal"] = "briefportrait_krystal",
      ["-Krystal"] = "briefportrait_krystalwar",
      ["Fara"] = "briefportrait_fara",
      ["Bill"] = "briefportrait_bill",
      ["Katt"] = "briefportrait_katt",
      ["Tricky"] = "briefportrait_tricky",
      ["Kyte"] = "briefportrait_kyte",
      ["James"] = "briefportrait_james",
      ["General Pepper"] = "briefportrait_pepper",
      ["Randorn"] = "briefportrait_randorn",
    }

  -- Function to create or update the briefing portrait
  local function createBriefingPortrait(controller, name)
    --- @type Element
    local portrait_el = controller.Document:GetElementById("brief_portrait")

    if not name then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end
      return
    end

    local img

    local img = portrait_defines[name]

    if not img then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end

      return
    end

    if not portrait_el then
      portrait_el = ScpuiSystem:makeElementPanel(controller, "brief_portrait", img)
      local parent = controller.Document:GetElementById("main_background")
      parent:AppendChild(portrait_el)
    else
      local img_el = portrait_el.first_child.next_sibling
      img_el:SetAttribute("src", img)
    end

    portrait_el:SetClass("hidden", false)
  end

  -- In briefing create a portrait for the current speaker
  topics.briefcommon.stageChanged:bind(9999, function(message, context)
    local controller = message[1]
    if controller.BriefState  == controller.CONTROLLER_BRIEFING then

      local stage_idx = message[2]
      if stage_idx < 1 or stage_idx >= #controller.Stages_List then
        return
      end

      local stage = controller.Stages_List[stage_idx]

      if not stage then
        return
      end

      local name = string.match(stage.Text, "([^:]+)")
      if name then
        name = name:gsub("^%s*(.-)%s*$", "%1") -- trim whitespace
        createBriefingPortrait(controller, name)
      end
    end
  end)

  -- Function to create or update the briefing portrait
  local function createDebriefingPortrait(controller, name)
    --- @type Element
    local portrait_el = controller.Document:GetElementById("debrief_portrait")

    if controller.SelectedSection == controller.STATE_STATS then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end
      return
    end

    local img

    local img = portrait_defines[name]

    if not img then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end

      return
    end

    if not portrait_el then
      portrait_el = ScpuiSystem:makeElementPanel(controller, "debrief_portrait", img)
      local parent = controller.Document:GetElementById("main_background")
      parent:AppendChild(portrait_el)
    else
      local img_el = portrait_el.first_child.next_sibling
      img_el:SetAttribute("src", img)
    end

    portrait_el:SetClass("hidden", false)
  end

  -- In briefing create a portrait for the current speaker
topics.debrief.stateChanged:bind(9999, function(message, context)
    local controller = message

    local stage = controller.Stages[1]

    if not stage then
      return
    end

    local name = string.match(stage.Text, "([^:]+)")
    if name then
      name = name:gsub("^%s*(.-)%s*$", "%1") -- trim whitespace
      createDebriefingPortrait(controller, name)
    end
  end)

  -- Function to create or update the pilot portrait in ship/weapon select
  local function createPilotPortrait(controller, slot)
    --- @type Element
    local portrait_el = controller.Document:GetElementById("portrait")

    if not slot then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end
      return
    end

    local LoadoutHandler = require('lib_loadout_handler')
    local ship_info = LoadoutHandler:GetShipLoadout(slot)

    local img

    local pship = mn.ParsedShips[ship_info.Name]
    if pship:isPlayer() then
      img = "foxpilota"
    else
      local ship = pship:getShip()

      ---@type persona
      ---@diagnostic disable-next-line
	    local persona = ship.Persona

      if persona:hasCustomData() then
        local data = persona.CustomData
        if data then
          local img_string = data["portrait"]
          if img_string and img_string ~= "" then
            img = img_string
          end
        end
      end
    end

    if not img then
      if portrait_el then
        portrait_el:SetClass("hidden", true)
      end

      return
    end

    if not portrait_el then
      portrait_el = ScpuiSystem:makeElementPanel(controller, "portrait", img)
      local parent = controller.Document:GetElementById("main_background")
      parent:AppendChild(portrait_el)
    else
      local img_el = portrait_el.first_child.next_sibling
      img_el:SetAttribute("src", img)
    end

    portrait_el:SetClass("hidden", false)
  end

  -- In Ship Select create a portrait for the selected ship
  topics.shipselect.selectSlot:bind(9999, function(message, context)
    local controller = message[1]
    local slot = message[2]

    createPilotPortrait(controller, slot)

  end)

  -- In Weapon Select create a portrait for the selected weapon
  topics.weaponselect.selectSlot:bind(9999, function(message, context)
    local controller = message[1]
    local slot = message[2]

    createPilotPortrait(controller, slot)

  end)

  -- In Loadout Handler, add a List Priority to the weapon info data
  topics.loadouts.initWeaponInfo:bind(9999, function(message, context)
    local data = message
    if data and data.Index then
      local idx = data.Index
      local wep = tb.WeaponClasses[idx]

      if wep and wep:hasCustomData() then
        local c_data = wep.CustomData
        if c_data and c_data["LoadoutListPriority"] then
          data.ListPriority = tonumber(c_data["LoadoutListPriority"]) or -1
        end
      else
        data.ListPriority = -1
      end
    end
  end)

  -- In Loadout Handler, add a List Priority to the ship info data
  topics.loadouts.initShipInfo:bind(9999, function(message, context)
    local data = message
    if data and data.Index then
      local idx = data.Index
      local ship = tb.ShipClasses[idx]

      if ship and ship:hasCustomData() then
        local c_data = ship.CustomData
        if c_data and c_data["LoadoutListPriority"] then
          data.ListPriority = tonumber(c_data["LoadoutListPriority"]) or -1
        end
      else
        data.ListPriority = -1
      end
    end
  end)

  -- In Loadout Handler, sort the ship and weapon lists by List Priority
  topics.loadouts.initialize:bind(9999, function(message, context)

    local function sortByPriorityThenIndex(a, b)
      local pa = (a.ListPriority and a.ListPriority >= 0) and a.ListPriority or math.huge
      local pb = (b.ListPriority and b.ListPriority >= 0) and b.ListPriority or math.huge

      if pa ~= pb then
        return pa < pb
      end

      return a.Index < b.Index
    end

    table.sort(ScpuiSystem.data.Loadout.Ship_Info, sortByPriorityThenIndex)
    table.sort(ScpuiSystem.data.Loadout.Primary_Info, sortByPriorityThenIndex)
    table.sort(ScpuiSystem.data.Loadout.Secondary_Info, sortByPriorityThenIndex)
  end)

end)()