local lookAtConsts = require("game.lookAtConsts")
local function GetRefnodeParent(obj)
  if obj.IsRefNode then
    return obj
  else
    return GetRefnodeParent(obj.Parent)
  end
end
function SetupPOIStates(POIState)
  local poiSearchParameters_Auto = {
    FindArgs = {
      "BANDIT",
      "AUTO",
      MatchAll = true
    },
    Filter = function(poi, ads, ai, global, constants)
      return true
    end
  }
  local poiSearchParameters_Precombat = {
    FindArgs = {
      "BANDIT",
      "PRECOMBAT",
      MatchAll = true
    },
    Filter = function(poi, ads, ai, global, constants)
      return global.aggroState ~= "INAGGRO" and global.aggroState ~= "INCOMBAT"
    end
  }
  local poiSearchParameters_WeaponRack = {
    FindArgs = {
      "BANDIT",
      "WEAPONRACK",
      MatchAll = true
    },
    Radius = 20,
    Filter = function(poi, ads, ai, global, constants)
      if not ai:PickupIsAcquired("GruntShield") and ai:IsInNavigationMove() then
        return true
      else
        return false
      end
    end
  }
  local poiSearchParameters_BanditAlarm = {
    FindArgs = {
      "BANDIT",
      "BANDITALARM",
      MatchAll = true
    },
    Radius = 20,
    Filter = function(poi, ads, ai, global, constants)
      if not ai:PickupIsAcquired("GruntShield") and ai:IsInNavigationMove() and global.aggroState == "INCOMBAT" then
        return true
      else
        return false
      end
    end
  }
  local poiSearchParameters_BanditHelfire = {
    FindArgs = {
      "BANDIT",
      "HELFIRE",
      MatchAll = true
    },
    Radius = 25,
    Filter = function(poi, ads, ai, global, constants)
      local gameObj = GetRefnodeParent(poi:GetGameObject().Parent.Parent)
      if global.previousUsedPOIObject ~= nil and global.previousUsedPOIObject ~= gameObj then
        global.usedPOITimer = global.usedPOITimer - ai:GetFrameTime()
        if global.usedPOITimer <= 0 then
          global.previousUsedPOIObject = nil
        end
        return false
      end
      if not ai:PickupIsAcquired("BanditHelfireShip") or ai:PickupGetStage("BanditHelfireShip") == 0 then
        return false
      end
      return true
    end
  }
  function POIState:GetSearchParameters(ai, global, constants)
    local parameters = {}
    table.insert(parameters, poiSearchParameters_Precombat)
    table.insert(parameters, poiSearchParameters_BanditHelfire)
    table.insert(parameters, poiSearchParameters_WeaponRack)
    table.insert(parameters, poiSearchParameters_BanditAlarm)
    table.insert(parameters, poiSearchParameters_Auto)
    return parameters
  end
  local POI_PreCombat = POIState:TypeHandler("POI_PreCombat")
  function POI_PreCombat:IsAvailable(poi, ai, global, constants)
    return poi ~= nil and poi.Type == "PreCombat"
  end
  function POI_PreCombat:Enter(poi, ai, global, constants)
    self.poiPos = poi:GetWorldPosition()
    self.thisPOI = poi
  end
  function POI_PreCombat.Events:OnHitReaction(event, ai, global, constants)
    if self.thisPOI ~= nil then
      self.thisPOI:SendEvent("kEHitReaction")
    end
  end
  function POI_PreCombat:Update(poi, ai, global, constants)
    POIState:OnUpdateAwareness(ai, global, constants)
    self:ApproachPOI(ai, global, constants)
    if global.aggroState == "INAGGRO" or global.aggroState == "INCOMBAT" then
      poi:SendEvent("EndPOI")
    end
  end
  local statemachine = require("ai.statemachine")
  local POI_Helfire = POIState:TypeHandler("POI_Helfire")
  statemachine.AddTags(POI_Helfire, "DoNotSearchPOI")
  function POI_Helfire:OnBrainInit(ai, global, constants)
    global.usedPOITimer = 0
  end
  function POI_Helfire:IsAvailable(poi, ai, global, constants)
    return poi ~= nil and poi.FeatureEvent == "HELFIRE"
  end
  function POI_Helfire:Enter(poi, ai, global, constants)
    self.poiPos = poi:GetWorldPosition()
    self.thisPOI = poi
    global.previousUsedPOIObject = GetRefnodeParent(poi:GetGameObject().Parent.Parent)
    global.usedPOITimer = 1
    ai:ClearFocus()
    ai:SetFocus(poi:GetWorldPosition())
    _G.lookAtPriorityOverrides.Hero = ai:AddLookAtPriorityOverride(lookAtConsts.TargetType.Hero, lookAtConsts.Priority.Ignore)
    _G.lookAtPriorityOverrides.Kid = ai:AddLookAtPriorityOverride(lookAtConsts.TargetType.Kid, lookAtConsts.Priority.Ignore)
  end
  function POI_Helfire.Events:OnHitReaction(event, ai, global, constants)
    if self.thisPOI ~= nil then
      self.thisPOI:SendEvent("kEHitReaction")
      global.usePOICooldown = 2.85
    end
  end
  function POI_Helfire:Update(poi, ai, global, constants)
    POIState:OnUpdateAwareness(ai, global, constants)
    self:ApproachPOI(ai, global, constants)
  end
  function POI_Helfire:Exit(poi, ai, global, constants)
    global.usePOICooldown = 0.15
  end
  local POI_DogPileDraugr = POIState:TypeHandler("POI_DogPileDraugr")
  function POI_DogPileDraugr:IsAvailable(poi, ai, global, constants)
    return poi ~= nil and poi.Type == "DogPileDraugr"
  end
  function POI_DogPileDraugr:Enter(poi, ai, global, constants)
    self.thisPOI = poi
    self.aggroRange = poi:FindLuaTableAttribute("aggroRange")
    self.activateRange = poi:FindLuaTableAttribute("activeRange")
    if self.activateRange < self.aggroRange then
      self.aggroRange = self.activateRange / 2
    end
  end
  function POI_DogPileDraugr.Events:OnHitReaction(event, ai, global, constants)
    if self.thisPOI ~= nil then
      self.thisPOI:SendEvent("kEHitReaction")
    end
  end
  function POI_DogPileDraugr:Update(poi, ai, global, constants)
    self:ApproachPOI(ai, global, constants)
    if game.AIUtil.Distance(poi, game.Player.FindPlayer()) < self.aggroRange then
      poi:SendEvent("kEExitDogPile")
    elseif game.AIUtil.Distance(poi, game.Player.FindPlayer()) <= self.activateRange then
      poi:SendEvent("kEStartDogPileDead")
    end
    if global.aggroState == "INAGGRO" or global.aggroState == "INCOMBAT" then
      poi:SendEvent("kEExitDogPile")
    end
  end
end
return {
  SetupPOIStates = SetupPOIStates
}
