local tablex = require("core.tablex")
local consts = require("ui.consts")
local fsm = require("ui.fsm")
local hooks = require("ui.hooks")
local lamsConsts = require("ui.lamsConsts")
local questUtil = require("ui.questUtil")
local questConsts = require("ui.questConsts")
local util = require("ui.util")
local logManager = require("ui.logManager")
local sliderHoldFill = require("ui.sliderHoldFill")
local UnregisterUpButtonPressCallback = function(sequence)
  if sequence.sliderGO ~= nil then
    sequence.sliderGO:Deactivate()
  end
  sequence:UninstallHookTokens()
  game.UI.ClearUpHandlerShowing()
end
local ActivateCallback = function(sequence, callbackArgs, newStages)
  sequence._hookTokens = {}
  return true
end
local TerminateCallback = function(sequence, callbackArgs, newStages)
  UnregisterUpButtonPressCallback(sequence)
  sequence:UninstallHookTokens()
  if sequence.sliderGO ~= nil then
    sequence.sliderGO:OnSliderParentHide()
  end
  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 CinematicBegan = function(sequence)
  if sequence.sliderGO ~= nil then
    sequence.sliderGO:Reset()
    UnregisterUpButtonPressCallback(sequence)
    sequence.sliderGO:Hide()
    sequence.sliderGO:OnSliderParentHide()
  end
  if sequence.promptGO ~= nil then
    game.UI.AlphaFade(sequence.promptGO, 0, 0.5)
  end
end
local Stage_SetInfo_StartCallback = function(stage, args)
  for _, anim in ipairs(stage._anims) do
    if stage._sequence._fsmState.inCinematic then
      anim.Event = nil
      anim.EventData = nil
    end
    if anim.AddSequence ~= nil then
      anim.Sequence = stage._sequence
    end
  end
end
local Stage_ClearInfo_StartCallback = function(stage, args)
  UnregisterUpButtonPressCallback(stage._sequence)
  stage._sequence:UninstallHookTokens()
  if stage._sequence.sliderGO ~= nil then
    stage._sequence.sliderGO:OnSliderParentHide()
  end
end
local SetGOText = function(childGO, textStr)
  local txtHdl = util.GetTextHandle(childGO)
  if txtHdl ~= nil then
    game.UI.SetText(txtHdl, textStr)
  end
end
local Anim_SetTextLAMS_ProcessCallback = function(childGO, animTable)
  local textLams = animTable.TextLams
  local textStr = (textLams == nil or textLams == 0) and "LAMS ID " .. tostring(textLams) .. " Not Found" or util.GetLAMSMsg(textLams)
  SetGOText(childGO, textStr)
end
local Anim_SetText_ProcessCallback = function(childGO, animTable)
  local textStr = animTable.TextStr
  SetGOText(childGO, textStr)
end
local Anim_SetButton_ProcessCallback = function(childGO, animTable)
  if animTable.Event ~= nil then
    local textStr = animTable.TextStr
    SetGOText(childGO, textStr)
    local sequence = animTable.Sequence
    sequence.promptGO = childGO
  else
    SetGOText(childGO, "")
  end
end
local Anim_SetSlider_ProcessCallback = function(childGO, animTable)
  local event = animTable.Event
  local data = animTable.EventData
  if event ~= nil and data ~= nil then
    game.UI.SetUpHandlerShowing()
    local sequence = animTable.Sequence
    local slider = sliderHoldFill.SliderHoldFill.New(sequence._fsmState, {
      Name = "PromptSlider",
      SliderObject = childGO,
      HoldSound = "SND_UX_HUD_Jump_To_Journal_Hold",
      SuccessSound = "SND_UX_HUD_Jump_To_Journal_Success",
      StopSound = "SND_UX_HUD_Jump_To_Journal_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)
        UnregisterUpButtonPressCallback(sequence)
        return
      end
      game.UI.SetUpHandled()
      sequence._fsmState:StartTimer("GoToJournalFlourishDelay", 0.5, function()
        sequence.sliderGO:Deactivate(true)
        UnregisterUpButtonPressCallback(sequence)
        sequence._fsmState:SendEventToUIFsm("globalMenu", event, unpack(data))
      end)
    end)
    slider:Activate(true)
  end
end
local InitSequenceArgs = {
  ParentGOName = "JournalLog",
  InitStages = {
    {
      StageName = "Reset",
      Timer = 0,
      Anims = {
        {
          GOPath = "log",
          FadeValue = 0,
          FadeTime = 0,
          AnimRate = 0,
          AnimStart = 0
        },
        {
          GOPath = "blur",
          FadeValue = 0,
          FadeTime = 0,
          AnimRate = 0,
          AnimStart = 0
        }
      }
    }
  },
  ActivateCallback = ActivateCallback,
  TerminateCallback = TerminateCallback,
  PausedChanged = PausedChanged,
  CinematicBegan = CinematicBegan
}
local CreateSequenceStages = function(args)
  if args.Event == nil then
  end
  if args.Event == nil then
  end
  local newSequenceStages = {
    {
      StageName = "SetInfo",
      Timer = 0,
      Anims = {
        {
          GOPath = "log|log_icon",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          Quest = args.Quest,
          Icon = args.Icon,
          ProcessCallback = function(childGO, animTable)
            local quest = animTable.Quest
            local icon = animTable.Icon
            if icon == nil and quest ~= nil then
              icon = questUtil.GetQuestIcon(quest)
            end
            if icon ~= nil then
              childGO:SetMaterialSwap(icon)
            end
          end
        },
        {
          GOPath = "log|log_text_header",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          TextLams = args.Header,
          ProcessCallback = Anim_SetTextLAMS_ProcessCallback
        },
        {
          GOPath = "log|log_text_row0",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          TextStr = args.BodyStr,
          ProcessCallback = Anim_SetText_ProcessCallback
        },
        {
          GOPath = "log|log_text_row0|log_text_button_prompt",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          TextStr = "[UpButton] " .. util.GetLAMSMsg(lamsConsts[args.ShowText]),
          Event = args.Event,
          EventData = args.EventData,
          AddSequence = true,
          ProcessCallback = Anim_SetButton_ProcessCallback
        },
        {
          GOPath = "log|PromptSlider",
          FadeValue = 0,
          FadeTime = 0,
          DoAnimate = false,
          Event = args.Event,
          EventData = args.EventData,
          AddSequence = true,
          ProcessCallback = Anim_SetSlider_ProcessCallback
        }
      },
      StartCallback = Stage_SetInfo_StartCallback
    },
    {
      StageName = "AnimIn",
      Timer = 1,
      Anims = {
        {
          GOPath = "log",
          FadeTime = 1,
          Sound = args.Sound
        },
        {
          GOPath = "log|log_icon",
          FadeValue = 1,
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_header",
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_row0",
          FadeTime = 1
        },
        {
          GOPath = "log|log_text_row0|log_text_button_prompt",
          FadeValue = args.Event == nil and 0 or 1,
          FadeTime = 1
        },
        {
          GOPath = "log|PromptSlider",
          FadeValue = args.Event == nil and 0 or 1,
          FadeTime = 1
        },
        {GOPath = "blur", FadeTime = 1}
      }
    },
    {
      StageName = "Idle",
      Timer = 5,
      UnlockTimer = 2.5
    },
    {
      StageName = "FadeOut",
      Timer = 2,
      Anims = {
        {
          GOPath = "log",
          FadeValue = 0,
          FadeTime = 1,
          AnimStyle = consts.AS_Reverse,
          AnimStart = 1,
          AnimEnd = 0
        },
        {
          GOPath = "blur",
          FadeValue = 0,
          FadeTime = 1,
          AnimStyle = consts.AS_Reverse,
          AnimStart = 1,
          AnimEnd = 0
        }
      }
    },
    {
      StageName = "ClearInfo",
      Timer = 0,
      Anims = {},
      StartCallback = Stage_ClearInfo_StartCallback
    }
  }
  return newSequenceStages
end
return {InitSequenceArgs = InitSequenceArgs, CreateSequenceStages = CreateSequenceStages}
