local tablex = require("core.tablex")
local consts = require("ui.consts")
local lamsConsts = require("ui.lamsConsts")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local resourceConsts = require("ui.resourceConsts")
local resourceUtil = require("ui.resourceUtil")
local uiCalls = require("ui.uicalls")
local util = require("ui.util")
local Audio = game.Audio
local logManager = require("ui.logManager")
local terminateCallback
local AddToItemCardQueue = function(queue, stages)
  for _, stage in ipairs(stages) do
    tablex.FastInsert(queue, stage, #queue + 1)
  end
end
local DispatchNextArgs = function(sequence)
  if #sequence._itemCardQueue > 0 then
    local nextArgs = table.remove(sequence._itemCardQueue, 1)
    local closuredReturn = true
    local function PreStreamTimer()
      sequence._fsmState:StartTimer("ItemCardPreStreamTimer", 0, function()
        local pickupName = nextArgs.ItemCardArgs.ResourceName
        local kratosOrSonTag = pickupUtil.HasTag(pickupName, pickupConsts.TAG_PICKUP_KRATOS) and pickupConsts.TAG_PICKUP_KRATOS or pickupConsts.TAG_PICKUP_SON
        local creatureForTag = pickupUtil.GetCreatureFromCharacter(kratosOrSonTag)
        local pickupSlot = pickupUtil.GetSlotName(pickupName)
        local pickupStage = pickupUtil.GetProfileStage(pickupName)
        game.Pickup.RequestLoadHighMips(pickupUtil.GetPickupGO(kratosOrSonTag, creatureForTag, pickupSlot), pickupName, pickupStage)
        if closuredReturn then
          PreStreamTimer()
        end
      end)
    end
    if nextArgs.ItemCardArgs.ResourceType == "Pickup" then
      PreStreamTimer()
    end
    local CorrectTerminateCallback = function()
      closuredReturn = false
      if terminateCallback ~= nil then
        terminateCallback()
      end
    end
    uiCalls.SendItemCardDesignerMessage({
      ItemCardArgs = nextArgs.ItemCardArgs,
      FooterButtonInfo = nextArgs.FooterButtonInfo,
      formattedArgs = nextArgs.FormattedArgs,
      AdvanceType = nextArgs.AdvanceType,
      TerminateCallback = CorrectTerminateCallback,
      ClearedOutCallback = CorrectTerminateCallback
    })
  else
    sequence._manager:Handle_SequenceFinished(sequence)
  end
end
local ItemCardDone = function(sequence)
  DispatchNextArgs(sequence)
end
local ActivateCallback = function(sequence, args, stages)
  if sequence._itemCardQueue == nil then
    sequence._itemCardQueue = {}
    function terminateCallback()
      ItemCardDone(sequence)
    end
  end
  AddToItemCardQueue(sequence._itemCardQueue, stages)
  DispatchNextArgs(sequence)
  return false
end
local AddStageCallback = function(sequence, args, stages)
  AddToItemCardQueue(sequence._itemCardQueue, stages)
  return false
end
local InitSequenceArgs = {
  ParentGOName = "DummyObjectForLogs",
  InitStages = {},
  ActivateCallback = ActivateCallback,
  AddStageCallback = AddStageCallback
}
local GetTutorialFooter = function(tutorialName, isVendorOpen, openMenuCallTable)
  if isVendorOpen then
    return nil
  end
  local result = {
    {
      Text = "[StartButton] " .. util.GetLAMSMsg(lamsConsts.Continue),
      EventHandlers = {
        {
          Events = {
            "EVT_Options_Release"
          },
          Handler = nil,
          UICalls = {
            openMenuCallTable,
            {
              CallName = "UI_Event_Setup_Tutorial",
              ArgTable = {tutorialName}
            }
          }
        }
      }
    }
  }
  return result
end
local GetEquipFooter = function(creature, pickupName, stage)
  local callTable
  if pickupUtil.IsWeaponSpecial(pickupName) or pickupUtil.IsWeaponComponent(pickupName) then
    local pickupSlot = pickupUtil.GetSlotName(pickupName)
    local axeOrBladesOrBow = pickupConsts.Axe
    if pickupUtil.IsBladesSpecialOrComponent(pickupName) then
      axeOrBladesOrBow = pickupConsts.Blades
    elseif pickupSlot == pickupConsts.Slot_SonSpecial then
      axeOrBladesOrBow = pickupConsts.SonBow
    end
    callTable = {
      CallName = "UI_Event_Open_Weapon_Menu",
      ArgTable = {
        axeOrBladesOrBow,
        pickupSlot,
        pickupName
      }
    }
  else
    if pickupUtil.HasTag(pickupName, pickupConsts.TAG_PICKUP_SON) and util.SonUI_ShouldDisable() then
      return nil
    end
    local pickupSlot = pickupUtil.GetSlotName(pickupName)
    callTable = {
      CallName = "UI_Event_Open_Stats_Menu",
      ArgTable = {pickupSlot, pickupName}
    }
  end
  return {
    {
      Text = "[SquareButton] " .. util.GetLAMSMsg(lamsConsts.ViewInMenu) .. " [AdvanceButton] " .. util.GetLAMSMsg(lamsConsts.Close),
      EventHandlers = {
        {
          Events = {
            "EVT_Advance_Release"
          }
        },
        {
          Events = {
            "EVT_Square_Release"
          },
          UICalls = {callTable}
        }
      }
    }
  }
end
local CheckAndSetTutorialVariable = function(tutorialType)
  local varName = "TUT_Shown" .. tutorialType .. "Tutorial"
  if not game.Level.GetVariable(varName) then
    game.Level.SetVariable(varName, true)
    return true
  end
  return false
end
local SetupTutorialFooterForItem = function(item, isVendorOpen)
  if resourceUtil.HasFlag(item, resourceConsts.RESOURCE_FLAG_ARMOR_TRINKET) and CheckAndSetTutorialVariable("Talisman") then
    return nil
  elseif item == "FrostSpecialAxeQuickClear" and CheckAndSetTutorialVariable("WeaponSpecial") then
    local openMenuCallTable = {
      CallName = "UI_Event_Open_Weapon_Menu",
      ArgTable = {
        "Axe",
        "PrimaryWeapon"
      }
    }
    return GetTutorialFooter("Pause_RunicAttackGem", isVendorOpen, openMenuCallTable)
  elseif resourceUtil.HasFlag(item, resourceConsts.RESOURCE_FLAG_WEAPON_SPECIAL_SON) and CheckAndSetTutorialVariable("SonSpecial") and util.SonUI_ShouldShow() and not util.SonUI_ShouldDisable() then
    local openMenuCallTable = {
      CallName = "UI_Event_Open_Weapon_Menu",
      ArgTable = {"SonBow", "SonSpecial"}
    }
    return GetTutorialFooter("Pause_SpiritSummons", isVendorOpen, openMenuCallTable)
  elseif resourceUtil.HasFlag(item, resourceConsts.RESOURCE_FLAG_WEAPON_COMPONENT) or resourceUtil.HasFlag(item, resourceConsts.RESOURCE_FLAG_WEAPON_COMPONENT_BLADES) and CheckAndSetTutorialVariable("WeaponComponent") then
    return nil
  end
  return nil
end
local CreateItemCardArgs = function(args, isVendorOpen)
  local isRune = args.ResourceType == resourceConsts.RESOURCE_FLAG_RUNE
  local footerButtonInfo
  if not isRune then
    footerButtonInfo = SetupTutorialFooterForItem(args.ResourceName, isVendorOpen)
  end
  local advanceType = uiCalls.msgParam.ADVANCE_PRESS
  if footerButtonInfo ~= nil then
    advanceType = uiCalls.msgParam.ADVANCE_PRESS_FORCEPAUSE
  elseif args.ResourceType == resourceConsts.RESOURCE_FLAG_PICKUP and (pickupUtil.IsArmor(args.ResourceName) or pickupUtil.IsWeaponSpecial(args.ResourceName) or pickupUtil.IsWeaponComponent(args.ResourceName)) then
    footerButtonInfo = GetEquipFooter(game.Player.FindPlayer(), args.ResourceName)
  end
  local newItemCardArgs = {
    {
      ItemCardArgs = {
        ResourceName = args.ResourceName,
        ResourceType = args.ResourceType
      },
      FooterButtonInfo = footerButtonInfo,
      AdvanceType = advanceType
    }
  }
  if not isRune and (resourceUtil.HasFlag(args.ResourceName, resourceConsts.RESOURCE_HEALTH_UPGRADE) or resourceUtil.HasFlag(args.ResourceName, resourceConsts.RESOURCE_RAGE_UPGRADE)) then
    local sequenceCount = game.Wallets.GetResourceValue(resourceConsts.WALLET_KRATOS, args.ResourceName) % 3
    if sequenceCount == 0 then
      sequenceCount = 3
    end
    newItemCardArgs[1].FormattedArgs = {sequenceCount}
  end
  return newItemCardArgs
end
return {InitSequenceArgs = InitSequenceArgs, CreateItemCardArgs = CreateItemCardArgs}
