local LD = require("design.LevelDesignLibrary")
local timers = require("level.timer")
local thisObj, thisLevel
local RoadLoreBanter = {}
local isPlayingBanter = false
local currentRoadLore
local attemptedToPlayRecently = {}
local numRoadBanter = 0
function OnScriptLoaded(level, obj)
  thisObj = obj
  thisLevel = level
  InitializeBanterStates()
  game.SubObject.Sleep(obj)
  game.SubObject.SetForgetOnCheckpoint(obj)
end
function InitializeBanterStates()
  RoadLoreBanter = {
    BaldurFactFinding = {
      Banter = "BaldurFactFinding",
      MinCine = 330,
      MaxCine = 400,
      Priority = 1,
      Lore = "BaldurFactFinding_Lore"
    },
    MimirTalksMagniModi = {
      Banter = "MimirTalksMagniModi",
      MinCine = 330,
      MaxCine = 355,
      Priority = 2,
      Lore = "MimirTalksMagniModi_Lore"
    },
    WhatOdinWants1 = {
      Banter = "WhatOdinWants1",
      MinCine = 330,
      MaxCine = 570,
      Priority = 3,
      Lore = "WhatOdinWants1_Lore"
    },
    WhatOdinWants2 = {
      Banter = "WhatOdinWants2",
      MinCine = 330,
      MaxCine = 570,
      Priority = 4,
      Lore = "WhatOdinWants2_Lore"
    },
    OdinVsTheFuture = {
      Banter = "OdinVsTheFuture",
      MinCine = 330,
      MaxCine = 9999,
      Priority = 5,
      Lore = "OdinVsTheFuture_Lore"
    },
    SerpentHistory = {
      Banter = "SerpentHistory",
      MinCine = 340,
      MaxCine = 9999,
      Priority = 6,
      Lore = "SerpentHistory_Lore"
    },
    GiantsGone = {
      Banter = "GiantsGone",
      MinCine = 360,
      MaxCine = 440,
      Priority = 7,
      Lore = "GiantsGone_Lore"
    },
    OldestEnemies = {
      Banter = "OldestEnemies",
      MinCine = 360,
      MaxCine = 9999,
      Priority = 8,
      Lore = "OldestEnemies_Lore"
    },
    OdinWorldTree = {
      Banter = "OdinWorldTree",
      MinCine = 360,
      MaxCine = 9999,
      Priority = 9,
      Lore = "OdinWorldTree_Lore"
    },
    NothingIsWritten = {
      Banter = "NothingIsWritten",
      MinCine = 360,
      MaxCine = 9999,
      Priority = 10,
      Lore = "NothingIsWritten_Lore"
    },
    InnerLight = {
      Banter = "InnerLight",
      MinCine = 494,
      MaxCine = 9999,
      Priority = 11,
      Lore = "InnerLight_Lore"
    },
    FreyaStoppedBy = {
      Banter = "FreyaStoppedBy",
      MinCine = 610,
      MaxCine = 9999,
      Priority = 2,
      Lore = "FreyaStoppedBy_Lore"
    },
    FriggRevealed = {
      Banter = "FriggRevealed",
      MinCine = 494,
      MaxCine = 570,
      Priority = 1,
      Lore = "FriggRevealed_Lore"
    },
    SeriouslyWhatTheHell = {
      Banter = "SeriouslyWhatTheHell",
      MinCine = 330,
      MaxCine = 390,
      Priority = 1,
      Lore = "SeriouslyWhatTheHel_Lore"
    },
    MjolnirLore = {
      Banter = "MjolnirLore",
      MinCine = 330,
      MaxCine = 580,
      Priority = 1,
      Lore = "MjolnirLore_Lore"
    },
    HuldraBrothers = {
      Banter = "HuldraBrothers",
      MinCine = 330,
      MaxCine = 580,
      Priority = 1,
      Lore = "HuldraBrothers_Lore"
    },
    BladeDeflection = {
      Banter = "BladeDeflection",
      MinCine = 440,
      MaxCine = 470,
      Priority = 1,
      Lore = "BladeDeflection_Lore"
    },
    LaufeyTheJust = {
      Banter = "LaufeyTheJust",
      MinCine = 330,
      MaxCine = 9999,
      Priority = 1,
      Lore = "LaufeyTheJust_Lore"
    }
  }
  for _, _ in pairs(RoadLoreBanter) do
    numRoadBanter = numRoadBanter + 1
  end
  ResetAttemptedToPlayRecently()
end
function GetRoadLoreToPlay()
  local BanterToPlay
  local cineNum = game.Level.GetVariable("CompletedCineNumber")
  for k, v in pairs(RoadLoreBanter) do
    local newProposedBanterToPlay
    if not attemptedToPlayRecently[k] and cineNum >= v.MinCine and cineNum < v.MaxCine then
      if v.Requirement ~= nil then
        if v.Requirement() then
          newProposedBanterToPlay = k
        end
      else
        newProposedBanterToPlay = k
      end
      if newProposedBanterToPlay and game.Audio.CanBanterConversationPlay(newProposedBanterToPlay) then
        if BanterToPlay then
          if RoadLoreBanter[newProposedBanterToPlay].Priority < RoadLoreBanter[BanterToPlay].Priority then
            BanterToPlay = newProposedBanterToPlay
          end
        else
          BanterToPlay = newProposedBanterToPlay
        end
      end
    end
  end
  return BanterToPlay
end
local numTimesTriedToPlayRoadLore = 0
local onRoadLoreFiredCallback, onRoadLoreFinishedCallback
local PlayRoadLore = function()
  if AllRoadLorePlayed() then
    RoadLoreFinished()
    return
  end
  if not isPlayingBanter then
    if LD.GetEntityVariable("NAR_RoadLoreAllowed") and numTimesTriedToPlayRoadLore < numRoadBanter then
      currentRoadLore = GetRoadLoreToPlay()
      if currentRoadLore then
        numTimesTriedToPlayRoadLore = numTimesTriedToPlayRoadLore + 1
        game.Audio.PlayBanterNonCritical(RoadLoreBanter[currentRoadLore].Banter, function()
          RoadLoreFinished()
        end, nil, true, function()
          RoadLoreStarted()
        end)
        attemptedToPlayRecently[currentRoadLore] = true
      end
    else
      RoadLoreFinished()
    end
  end
end
function TryToPlayRoadLore(onFinishedCallback, onFiredCallback)
  onRoadLoreFinishedCallback = onFinishedCallback
  onRoadLoreFiredCallback = onFiredCallback
  timers.StartLevelTimer(0.5, function()
    PlayRoadLore()
  end)
end
function RoadLoreStarted()
  isPlayingBanter = true
  if onRoadLoreFiredCallback then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, onRoadLoreFiredCallback, "Road Lore Started Callback")
    onRoadLoreFiredCallback = nil
  end
end
function RoadLoreFinished()
  if isPlayingBanter and RoadLoreBanter[currentRoadLore].Lore and game.Wallets.HasResource("HERO_SAVEONLY", RoadLoreBanter[currentRoadLore].Lore) == false then
    LD.UpdateJournal(RoadLoreBanter[currentRoadLore].Lore, 7)
  end
  isPlayingBanter = false
  currentRoadLore = nil
  if onRoadLoreFinishedCallback then
    LD.ExtractAndExecuteCallbacksForEvent(thisLevel, thisObj, onRoadLoreFinishedCallback, "Road Lore Finished Callback")
    onRoadLoreFinishedCallback = nil
  end
end
function ResetAttemptedToPlayRecently()
  numTimesTriedToPlayRoadLore = 0
  for k, _ in pairs(RoadLoreBanter) do
    attemptedToPlayRecently[k] = false
  end
end
function AllRoadLorePlayed()
  return GetRoadLoreToPlay() == nil
end
function BanterStateDebug()
  if engine.IsDebug() then
    local debugTable = {}
    debugTable.X = 0
    debugTable.Y = 20
    debugTable.Title = "RoadLoreBanter"
    table.insert(debugTable, {
      "currentRoadLore",
      currentRoadLore
    })
    table.insert(debugTable, {
      "RoadLoreAllowed",
      LD.GetEntityVariable("NAR_RoadLoreAllowed")
    })
    table.insert(debugTable, {
      "numRoadBanter",
      numRoadBanter
    })
    table.insert(debugTable, {
      "CompletedCineNumber",
      game.Level.GetVariable("CompletedCineNumber")
    })
    table.insert(debugTable, {
      "isPlayingBanter",
      isPlayingBanter
    })
    table.insert(debugTable, {
      "NumTimesTriedToPlayRoadLore",
      numTimesTriedToPlayRoadLore
    })
    local attemptedDebugTable = {
      "attemptedToPlayRecently"
    }
    for k, v in pairs(attemptedToPlayRecently) do
      if v then
        table.insert(attemptedDebugTable, k)
      end
    end
    table.insert(debugTable, attemptedDebugTable)
    for k, v in pairs(RoadLoreBanter) do
      local insertTable = {}
      table.insert(insertTable, k)
      table.insert(insertTable, "CanPlay: " .. tostring(game.Audio.CanBanterConversationPlay(k)))
      for l, w in pairs(v) do
        table.insert(insertTable, l .. ":")
        table.insert(insertTable, w)
      end
      table.insert(debugTable, insertTable)
    end
    engine.DrawDebugTable(debugTable)
  end
end
