local statemachine = require("ai.statemachine")
local tablex = require("core.tablex")
local picklelib = require("core.pickle")
local DL = require("design.DesignerLibrary")
local globalLuaHooks = require("design.GlobalLuaHooks")
globalLuaHooks.InstallHooks()
local traverselink = require("creature.traverselink")
traverselink.InstallHooks()
local timer = require("level.timer")
local components = require("design.components")
Brain_Core = require("behavior.corebrain")
constants = {}
global = {}
attachments = {}
global.turretModeBreak = false
global.turretModeBreakRange = 0
local powerLevel = "1"
local pLevelInt = 0
local variantType
function LuaHook_ClearArrow(ai, data)
  game.Combat.RemoveArrows(ai)
end
function LuaHook_Fanatic_TurretMode(ai)
  global.turretMode = true
  if ai:PickupIsAcquired("TurretMode") == false then
    ai:PickupAcquire("TurretMode")
    global.navBank = constants.navBankTurret
    ai:SetNavBank(global.navBank)
  end
end
function LuaHook_Fanatic_TurretModeOff(ai)
  global.turretMode = false
  global.useLeashing = true
  if ai:PickupIsAcquired("TurretMode") then
    ai:PickupRelinquish("TurretMode")
    global.navBank = constants.navBankDefault
    ai:SetNavBank(global.navBank)
  end
end
function LuaHook_Fanatic_DetonateCoverWall(ai)
  if global.coverWall ~= nil then
    global.coverWall:CallScript("StartDestroyObj")
    local concussionParams = {
      Tweak = "CNC_RUNE_FROST_BLAST_COVER_WALL",
      WorldLocation = global.coverWall:GetWorldPosition(),
      GameObject = ai,
      EnemyId = ai:GetID()
    }
    game.Combat.PlayConcussion(concussionParams)
  end
  global.canDetonateCoverWall = false
  global.coverWall = nil
  LuaHook_Fanatic_TurretModeOff(ai)
end
function LuaHookDecision_HasWallSpawned(ai, data)
  if global.coverWall ~= nil then
    return data:FindOutcomeBranchesEntry("Yes")
  else
    return data:FindOutcomeBranchesEntry("No")
  end
end
function LuaHookDecision_CheckCanSpawnWall(ai, data)
  local retVal = true
  local nearbyCreatures = ai:FindFriendlies(3)
  for _, creature in ipairs(nearbyCreatures) do
    if creature ~= ai and creature:GetHitPoints() > 0 then
      retVal = false
    end
  end
  return retVal
end
function LuaHook_AddBlood_Cleave_Impact(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kHead, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kLeftFrontLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kLeftBackLeg, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.1)
end
function LuaHook_AddBlood_Fanatic_RageEnter(ai, data)
  local player = game.Player.FindPlayer()
  player:AddBlood(game.GameObject.eRegionId.kLeftChest, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightChest, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kFrontAbdomen, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontUpperArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLowerArm, 0.6)
  player:AddBlood(game.GameObject.eRegionId.kRightFrontLeg, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kLeftBack, 0.1)
  player:AddBlood(game.GameObject.eRegionId.kRightBack, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kBackAbdomen, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackUpperArm, 0.2)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLowerArm, 0.4)
  player:AddBlood(game.GameObject.eRegionId.kRightBackLeg, 0.1)
end
function SetCoverWallObject(ai, coverWall)
  global.coverWall = coverWall
end
function RequestCoverWallDetonation(ai, coverWall)
  global.coverWall = coverWall
  global.canDetonateCoverWall = true
end
function OnAIPostSpawn(ai)
  setupCharacter(ai)
end
function Brain_Core:OnSetPowerlevelOverrideCustom(ai, global, constants, level, isElite, forced)
  powerLevel = level
  ToggleCharacterConfig(ai, forced)
end
function setupCharacter(ai)
  local spawnContext = ai:GetContext()
  if StartConfig ~= nil then
    if StartConfig.Variant ~= nil then
      variantType = StartConfig.Variant
    end
    if StartConfig.EliteDifficulty ~= nil and StartConfig.EliteDifficulty and not ai:PickupIsAcquired("Fanatic00_Elite") then
      ai:PickupAcquire("Fanatic00_Elite")
    end
    if StartConfig.TurretMode then
      ai:PickupAcquire("TurretMode")
      global.navBank = constants.navBankTurret
      global.TurretMode = true
      if StartConfig.TurretModeBreakRange ~= nil then
        global.turretModeBreakRange = StartConfig.TurretModeBreakRange
        if global.turretModeBreakRange > 0 then
          global.turretModeBreak = true
        end
      end
      if global.turretModeBreak == false and ai:PickupIsAcquired("HealthThreshold") then
        ai:PickupRelinquish("HealthThreshold")
      end
    end
  end
  ToggleCharacterConfig(ai, not game.CHECK_FEATURE("PREEMPT_SPAWN_CONFIG"))
  if ai.SetDirectAimingModeIsEnabled then
    ai:SetDirectAimingModeIsEnabled(true)
  end
  if ai:AttributeGetValue("Difficulty") == 4 then
    local cineVar = game.Level.GetVariable("CompletedCineNumber")
    if ai:PickupIsAcquired("Fanatic00_PowerLevel") and (180 <= cineVar and ai:PickupGetStage("Fanatic00_PowerLevel") <= 1 or 250 <= cineVar and ai:PickupGetStage("Fanatic00_PowerLevel") <= 2 or 380 <= cineVar and ai:PickupGetStage("Fanatic00_PowerLevel") <= 3 or 490 <= cineVar and 4 >= ai:PickupGetStage("Fanatic00_PowerLevel")) and (ai.GroundLevel == nil or ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Msp") == nil) then
      ai:PickupAcquire("PowerLevelBoost")
    end
  end
  if ai.GroundLevel ~= nil and string.find(ai.GroundLevel.Name, "Msp100_") ~= nil and ai:GetWorldPosition().y < 30 then
    ai:PickupAcquire("MuspelheimPenalty")
  end
  DL.NewGamePlusLevelBoost(ai, "Fanatic00_PowerLevel")
end
function ToggleCharacterConfig(ai, override)
  if powerLevel == "1" then
    pLevelInt = 1
  elseif powerLevel == "2" then
    pLevelInt = 2
  elseif powerLevel == "3" then
    pLevelInt = 3
  elseif powerLevel == "4" then
    pLevelInt = 4
  elseif powerLevel == "5" then
    pLevelInt = 5
  elseif powerLevel == "6" then
    pLevelInt = 6
  elseif powerLevel == "7" then
    pLevelInt = 7
  elseif powerLevel == "8" then
    pLevelInt = 8
  else
    pLevelInt = powerLevel
  end
  if variantType ~= nil then
    if variantType == "Default-Bomber" then
      if not ai:PickupIsAcquired("Fanatic_Default") then
        ai:PickupAcquire("Fanatic_Default")
      end
      if override ~= nil and override == true then
        ai:SetCharacterConfig("fanatic00")
      end
      game.Audio.SetWwiseSwitch(ai, "CHR_Type", "Helwalker")
    elseif variantType == "Seidr-Bomber" then
      if not ai:PickupIsAcquired("Fanatic_Default") then
        ai:PickupAcquire("Fanatic_Default")
      end
      if override ~= nil and override == true then
        if pLevelInt <= 2 then
          ai:SetCharacterConfig("Fanatic00_seidr")
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          ai:SetCharacterConfig("Fanatic00_seidr_hard")
        elseif 5 <= pLevelInt then
          ai:SetCharacterConfig("Fanatic00_seidr_veryhard")
        end
      end
      game.Audio.SetWwiseSwitch(ai, "CHR_Type", "Seidr")
    elseif variantType == "Helwalker-Archer" then
      if not ai:PickupIsAcquired("Fanatic_HelwalkerArcher") then
        ai:PickupAcquire("Fanatic_HelwalkerArcher")
      end
      if override ~= nil and override == true then
        if pLevelInt <= 2 then
          ai:SetCharacterConfig("Fanatic00_hel")
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          ai:SetCharacterConfig("Fanatic00_hel_hard")
        elseif 5 <= pLevelInt then
          ai:SetCharacterConfig("Fanatic00_hel_veryhard")
        end
      end
      game.Audio.SetWwiseSwitch(ai, "CHR_Type", "Helwalker")
    elseif variantType == "Helwalker-Bomber" then
      if not ai:PickupIsAcquired("Fanatic_HelwalkerBomber") then
        ai:PickupAcquire("Fanatic_HelwalkerBomber")
      end
      if override ~= nil and override == true then
        if pLevelInt <= 2 then
          ai:SetCharacterConfig("Fanatic00_hel")
        elseif 3 <= pLevelInt and pLevelInt <= 4 then
          ai:SetCharacterConfig("Fanatic00_hel_hard")
        elseif 5 <= pLevelInt then
          ai:SetCharacterConfig("Fanatic00_hel_veryhard")
        end
      end
      game.Audio.SetWwiseSwitch(ai, "CHR_Type", "Helwalker")
    end
  end
  if global.TurretMode and not global.turretModeBreak then
    if ai:PickupIsAcquired("Fanatic_Default") then
      ai:PickupSetStage("Fanatic_Default", 1)
    elseif ai:PickupIsAcquired("Fanatic_HelwalkerArcher") then
      ai:PickupSetStage("Fanatic_HelwalkerArcher", 1)
    elseif ai:PickupIsAcquired("Fanatic_HelwalkerBomber") then
      ai:PickupSetStage("Fanatic_HelwalkerBomber", 1)
    end
  end
end
function OnAIUpdate(ai)
  if Brain_Core:GetDebugTable(ai) then
    local variant = "Default"
    if ai:PickupIsAcquired("Fanatic_HelwalkerArcher") then
      variant = "Helwalker Archer"
    elseif ai:PickupIsAcquired("Fanatic_HelwalkerBomber") then
      variant = "Helwalker Bomber"
    end
    local debugTable = {}
    table.insert(debugTable, {"Variant:", variant})
    table.insert(debugTable, {
      "Turret Mode:",
      global.turretMode
    })
    table.insert(debugTable, {
      "NavBank:",
      global.navBank
    })
    Brain_Core:AddCustomDebugTable(debugTable)
  end
  components.UpdateComponents(ai, attachments)
  traverselink.OnUpdate(ai)
end
function _G.OnAICreateLuaState(ai)
  _G.OnAICreateLuaState = nil
end
function TryToDestroyWall(ai)
  if ai:PickupIsAcquired("Fanatic_HelwalkerBomber") and ai:PickupGetStage("Fanatic_HelwalkerBomber") ~= 1 then
    LuaHook_Fanatic_DetonateCoverWall(ai)
  end
end
function Brain_Core:OnDeath(ai, attacker, deathByDespawn)
  TryToDestroyWall(ai)
end
function Brain_Core:OnHitReaction(event, ai, global, constants)
  if event.enemyId ~= DL.HashCreatureID(ai, "SON00") and ai:HasHitFlag("HIT_ARROW", event.hitFlags) == false then
    TryToDestroyWall(ai)
  end
end
function Brain_Core:OnUpdateCombat(ai, global, constants)
  if global.canDetonateCoverWall and (ai:IsInNavigationMove() or ai:HasMarker("CanDetonateCoverWall")) then
    ai:ForceMove("BRA_DetonateCoverWall")
  end
end
function Brain_Core:OnUpdateMotion(ai, global, constants, actuatorData)
end
picklelib.Install()
function Pickle(GO)
  return {
    global = global
  }
end
function Unpickle(GO, t)
  global = t.global
end
