local tablex = require("core.tablex")
local consts = require("ui.consts")
local fsm = require("ui.fsm")
local hooks = require("ui.hooks")
local questUtil = require("ui.questUtil")
local util = require("ui.util")
local lamsConsts = require("ui.lamsConsts")
local logManager = require("ui.logManager")
local sliderHoldFill = require("ui.sliderHoldFill")
local ActivateCallback = function(sequence, callbackArgs, newStages)
  sequence._hookTokens = {}
  return true
end
local TerminateCallback = function(sequence, callbackArgs, newStages)
  if sequence.sliderGO ~= nil then
    sequence.sliderGO:Deactivate()
    sequence.sliderGO:OnSliderParentHide()
  end
  sequence:UninstallHookTokens()
  game.UI.ClearUpHandlerShowing()
  return true
end
local PausedChanged = function(sequence, gamePaused, uiPaused)
  if uiPaused then
    game.UI.AlphaFade(sequence._parentGO, 0, 1)
  else
    game.UI.AlphaFade(sequence._parentGO, 1, 1)
  end
end
local AddStageCallback = function(sequence, callbackArgs, newStages)
  for _, stageData in ipairs(newStages) do
    if stageData.StageName == "SetInfo" then
      for _, anim in ipairs(stageData.Anims) do
        if anim.AddSequence ~= nil then
          anim.Sequence = sequence
        end
      end
      return
    end
  end
  return true
end
local Stage_SetInfo_StartCallback = function(stage, args)
  assert(args, "Unable to find QuestID, arguments table was nil")
  assert(args.QuestID, "Unable to find QuestID, table did not contain key-value")
  stage._sequence.QuestID = args.QuestID
end
local Stage_FadeOut_StartCallback = function(stage)
  stage._sequence.QuestID = nil
end
local InternalSetText = function(text, childGO)
  local txtHdl = util.GetTextHandle(childGO)
  if txtHdl ~= nil then
    game.UI.SetText(txtHdl, text)
  end
end
local CinematicBegan = function(sequence)
  if sequence.sliderGO ~= nil then
    sequence.sliderGO:Reset()
    sequence:UninstallHookTokens()
    game.UI.ClearUpHandlerShowing()
    sequence.sliderGO:Hide()
    sequence.sliderGO:OnSliderParentHide()
  end
  if sequence.promptGO ~= nil then
    InternalSetText("", sequence.promptGO)
  end
end
local Anim_Icon_ProcessCallback = function(childGO, animTable)
  local questID = animTable.QuestID
  local iconMatName = questUtil.GetQuestIcon(questID)
  childGO:SetMaterialSwap(iconMatName)
end
local Anim_Category_ProcessCallback = function(childGO, animTable)
  local textStr = util.GetLAMSMsg(animTable.Category)
  InternalSetText(textStr, childGO)
end
local Anim_Header_ProcessCallback = function(childGO, animTable)
  local textStr = util.GetLAMSMsg(animTable.Header)
  InternalSetText(textStr, childGO)
end
local Anim_Row_ProcessCallback = function(childGO, animTable)
  local textStr = animTable.BodyStr
  InternalSetText(textStr, childGO)
end
local Anim_Button_ProcessCallback = function(childGO, animTable)
  local buttonText = ""
  local questID = animTable.QuestID
  local sequence = animTable.Sequence
  if questUtil.IsTrackableSideQuest(questID) then
    if not questUtil.IsQuestTracked(questID) then
      buttonText = "[UpButton] " .. util.GetLAMSMsg(lamsConsts["Track Favor"])
      local currentlyTracked = questUtil.FindCurrentlyTrackedSideQuestID()
      if questUtil.IsValidID(currentlyTracked) then
        buttonText = buttonText .. [[

 ]] .. util.GetLAMSMsg(lamsConsts["Track Favor Ext"])
      end
    end
  elseif questUtil.IsTreasureMapQuest(questID) and not sequence._fsmState.inCinematic then
    buttonText = "[UpButton] " .. util.GetLAMSMsg(lamsConsts.ShowJournal)
  end
  InternalSetText(buttonText, childGO)
  sequence.promptGO = childGO
end
local Anim_Slider_ProcessCallback = function(childGO, animTable)
  local questID = animTable.QuestID
  local sequence = animTable.Sequence
  local showPrompt = questUtil.IsTrackableSideQuest(questID) and not questUtil.IsQuestTracked(questID) or questUtil.IsTreasureMapQuest(questID) and not sequence._fsmState.inCinematic
  if showPrompt then
    game.UI.SetUpHandlerShowing()
    local slider = sliderHoldFill.SliderHoldFill.New(sequence._fsmState, {
      Name = "PromptSlider",
      SliderObject = childGO,
      HoldSound = "SND_UX_HUD_Jump_To_Quest_Hold",
      SuccessSound = "SND_UX_HUD_Jump_To_Quest_Success",
      StopSound = "SND_UX_HUD_Jump_To_Quest_Hold_Reset_LP",
      StopWhenFull = true,
      IncAnimRate = 1.8,
      DecAnimRate = 2.6,
      PressEvent = "EVT_Up_Press",
      ReleaseEvent = "EVT_Up_Release",
      InputDisabled = function()
        return sequence._manager:IsInputDisabled()
      end
    })
    sequence.sliderGO = slider
    slider:SetOnComplete(function()
      sequence.promptGO:Hide()
      if sequence._manager:IsInputDisabled() then
        sequence.sliderGO:Deactivate(true)
        TerminateCallback(sequence)
        return
      end
      game.UI.SetUpHandled()
      sequence._fsmState:StartTimer("GoToJournalFlourishDelay", 0.5, function()
        sequence.sliderGO:Deactivate(true)
        if questUtil.IsTrackableSideQuest(questID) then
          questUtil.TrackSideQuest(questID)
        elseif questUtil.IsTreasureMapQuest(questID) then
          sequence._fsmState:SendEventToUIFsm("globalMenu", "EVT_GO_TO_QUEST", questID)
        end
        TerminateCallback(sequence)
      end)
    end)
    slider:Activate(true)
  end
end
local SetCompassMarkers_StartCallback = function(stage, startCallbackArgs)
  local questID = startCallbackArgs.QuestID
  questUtil.AddMarkersToCompassFromSequence(questID)
end
local InitSequenceArgs = {
  ParentGOName = "QuestLog",
  InitStages = {},
  ActivateCallback = ActivateCallback,
  TerminateCallback = TerminateCallback,
  AddStageCallback = AddStageCallback,
  PausedChanged = PausedChanged,
  CinematicBegan = CinematicBegan
}
local CreateSequenceStages = function(args)
  local newSequenceStages = {
    {
      StageName = "SetInfo",
      Timer = 0,
      StartCallback = Stage_SetInfo_StartCallback,
      StartCallbackArgs = {
        QuestID = args.Quest
      },
      Anims = {
        {
          GOPath = "log",
          FadeValue = 0,
          FadeTime = 0,
          AnimName = args.Quest and game.QuestManager.QuestHasFlag(args.Quest, "GoldBanner") and "QuestTicker_Gold" or "QuestTicker_Blue",
          Sound = args.State == "Activate" and "SND_UX_HUD_Quest_Start" or args.State == "Complete" and "SND_UX_HUD_Quest_Complete" or "SND_UX_HUD_Quest_Update"
        },
        {
          GOPath = "log|log_icon",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          QuestID = args.Quest,
          ProcessCallback = Anim_Icon_ProcessCallback
        },
        {
          GOPath = "log|log_text_category",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          Category = args.Category,
          ProcessCallback = Anim_Category_ProcessCallback
        },
        {
          GOPath = "log|log_text_header",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          Header = args.Header,
          ProcessCallback = Anim_Header_ProcessCallback
        },
        {
          GOPath = "log|log_text_row0",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          BodyStr = args.BodyStr,
          ProcessCallback = Anim_Row_ProcessCallback
        },
        {
          GOPath = "log|log_text_row0|log_text_button_prompt",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          QuestID = args.Quest,
          AddSequence = true,
          ProcessCallback = Anim_Button_ProcessCallback
        },
        {
          GOPath = "log|PromptSlider",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          QuestID = args.Quest,
          AddSequence = true,
          ProcessCallback = Anim_Slider_ProcessCallback
        }
      }
    },
    {
      StageName = "AnimIn",
      Timer = 0.5,
      Anims = {
        {
          GOPath = "log",
          FadeValue = 1,
          FadeTime = 0
        }
      }
    },
    {
      StageName = "FadeIn_Info",
      Timer = 0.5,
      Anims = {
        {
          GOPath = "log|log_icon",
          FadeValue = 1,
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_category",
          FadeValue = 1,
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_header",
          FadeValue = 1,
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_row0",
          FadeValue = 1,
          FadeTime = 1
        },
        {
          GOPath = "log|PromptSlider",
          FadeValue = 1,
          FadeTime = 1
        }
      }
    },
    {
      StageName = "FadeIn_Row",
      Timer = 0.5,
      Anims = {
        {
          GOPath = "log|log_text_row0|log_text_button_prompt",
          FadeValue = 1,
          FadeTime = 0.5
        }
      }
    },
    {
      StageName = "Idle",
      Timer = 5,
      UnlockTimer = 3,
      StartCallback = SetCompassMarkers_StartCallback,
      StartCallbackArgs = {
        QuestID = args.Quest
      }
    },
    {
      StageName = "FadeOut",
      Timer = 0.33,
      StartCallback = Stage_FadeOut_StartCallback,
      Anims = {
        {
          GOPath = "log",
          FadeValue = 0,
          FadeTime = 0.33,
          DoAnimate = false
        }
      }
    }
  }
  return newSequenceStages
end
return {InitSequenceArgs = InitSequenceArgs, CreateSequenceStages = CreateSequenceStages}
