local statemachine = require("ai.statemachine")
local helper = require("son.helper")
local poilib = require("behavior.poi")
local followpointcloud = require("ai.followpointcloud")
local theaterofoperations = require("ai.theaterofoperations")
local DL = require("design.DesignerLibrary")
local positioning = require("behavior.positioning")
local FWP = require("behavior.followWayPoints")
TargetBrain = statemachine.StateMachine.New("TargetBrain")
local TargetLogic = TargetBrain:State("TargetLogic")
local NotInUse = TargetBrain:State("NotInUse")
function TargetBrain:SelectNextState(ai, global, constants)
  if global.POIInfo.useThisPOI and (not ai.OwnedPOI or not ai.OwnedPOI:FindLuaTableAttribute("AvailableDuringCombat")) and ai.OwnedPOI and ai.OwnedPOI:GetStageName() ~= "ApproachOrMovingBreakOut" then
    return NotInUse
  end
  if ai:IsInVehicle() then
    return NotInUse
  end
  return TargetLogic
end
function TargetLogic:OnBrainInit(ai, global, constants)
  global.sTargetMode = "RegularTarget"
end
function LuaHook_SetToReactionTarget(ai)
  _G.constants.sPreviousTargetMode = _G.global.sTargetMode
  _G.global.sTargetMode = "ReactionTarget"
  ai:SetCombatTarget(_G.global.reactionTarget)
end
function LuaHook_SetToPreviousTarget()
  _G.global.sTargetMode = _G.constants.sPreviousTargetMode
end
function LuaHook_UpdateManually(ai)
  ai:RequestHighPriorityUpdate()
end
function TargetLogic.Events:OnHitReaction(event, ai, global, constants)
  if event.source ~= game.Player.FindPlayer() then
    _G.global.reactionTarget = event.source
  end
end
function TargetLogic:Update(ai, global, constants)
  if global.targetOverride == true then
    return
  end
  local targetPos
  local player = global.Player
  local targetOfPlayer = helper.getPlayerTarget()
  local combatTarget
  if global.sTargetMode == "SpecialAim" then
    combatTarget = constants.targetOfPlayer
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "TargetKratos" then
    combatTarget = player
  elseif ai.OwnedPOI and ai.OwnedPOI:FindLuaTableAttribute("AvailableDuringCombat") then
    local thisEnemy = helper.FindClosestLivingEnemyExcludeMarker(ai, 40, "DoNotEvaluate")
    combatTarget = thisEnemy
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "KratosTarget" then
    combatTarget = targetOfPlayer
    if targetOfPlayer ~= nil then
      targetPos = targetOfPlayer:GetWorldPosition()
    end
  elseif global.sTargetMode == "TransferTarget" then
    combatTarget = constants.reactionTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "ReactionTarget" then
    combatTarget = global.reactionTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "TargetList" then
    combatTarget = global.combatTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "TargetFenrir" then
    for _, creature in ipairs(ai:FindFriendlies(100)) do
      if creature:GetID() == DL.HashCreatureID(ai, "FENRIR00") then
        combatTarget = creature
      end
    end
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "ParryTarget" then
    combatTarget = global.combatParryTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "TargetBroadcaster" then
    combatTarget = global.creatureBroadcaster
    targetPos = global.creatureBroadcaster:GetWorldPosition()
  elseif global.sTargetMode == "AcquireKratosTarget" then
    if global.goPlayerTarget ~= nil and global.goPlayerTarget:IsDead() == false then
      combatTarget = global.goPlayerTarget
    end
  elseif global.sTargetMode == "DodgeTarget" then
    combatTarget = constants.GO_dodgeObject
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "CloseCombatTarget" then
    combatTarget = constants.GO_closeCombatObject
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "FollowUpTarget" then
    combatTarget = global.FollowUpTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "KillTarget" then
    combatTarget = global.KillTarget
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "TargetSpecificEnemy" then
    local currentTarget = ai:GetTargetCreature()
    if currentTarget == nil or currentTarget ~= nil and currentTarget:HasMarker("KillTarget") == false then
      local targets = DL.FindLivingEnemies(player, 40, true)
      for _, i in ipairs(targets) do
        if i:HasMarker("KillTarget") then
          ai:SetCombatTarget(i)
          combatTarget = i
          break
        end
      end
    end
    if currentTarget ~= nil and currentTarget:HasMarker("KillTarget") == true then
      combatTarget = currentTarget
    end
  elseif global.sTargetMode == "TargetNonPlayerTarget" then
    for _, i in ipairs(global.potentialEnemyList) do
      if i ~= nil and i ~= global.Player:GetTargetCreature() then
        combatTarget = i
        break
      end
    end
    if combatTarget ~= nil and combatTarget ~= global.Player:GetTargetCreature() then
      targetPos = combatTarget:GetWorldPosition()
    end
  elseif global.sTargetMode == "RegularTarget" then
    local thisEnemy = helper.FindClosestLivingEnemyExcludeMarker(ai, 40, "DoNotEvaluate")
    combatTarget = thisEnemy
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  else
    local thisEnemy = helper.FindClosestLivingEnemyExcludeMarker(ai, 40, "DoNotEvaluate")
    combatTarget = thisEnemy
    if combatTarget ~= nil then
      targetPos = combatTarget:GetWorldPosition()
    end
  end
  if combatTarget == nil and global.sTargetMode ~= "SpecialAim" then
    local targets = helper.FindLivingEnemiesExludeMarked(player, 30, "DoNotEvaluate")
    if 0 < #targets then
      combatTarget = targets[1]
    end
  end
  if gVFSDebug.value and targetPos ~= nil then
    engine.DrawLine(ai:GetWorldPosition(), targetPos, 16711680)
    engine.DrawSphere(targetPos, 0.2, 16711680)
  end
  if combatTarget ~= nil and combatTarget.GetAI == nil and combatTarget:GetCreature() ~= nil then
    combatTarget = combatTarget:GetCreature():GetAI()
  end
  global.combatTarget = combatTarget
  if combatTarget ~= nil then
    ai:SetFocus(combatTarget)
  end
  ai:SetCombatTarget(combatTarget)
end
return TargetBrain
