local this = class("playerUnit", L_EcsConst.unit)
local _unitData = require(L_EcsConst.unitDataType.player)

function this:ctor()
  this.super.ctor(self)
  self.unitData = _unitData.new()
  self.interactSystem = self:addSystem(L_EcsConst.systemType.interactSystem)
  self._lastMainControlCsEntityId = nil
  self._entityDic = {}
end

function this:onDestroy()
  self.unitData:onDestroy()
  this.super.onDestroy(self)
end

function this:onUpdate(scale)
  for _, entity in pairs(self._entityDic) do
    if entity then
      entity:onUpdate(scale)
    end
  end
end

function this:setMainControlEntity()
end

function this:getPlayerId()
  if AzurWorld.playerMgr.myPlayerUnitAdapter == nil then
    return 0
  end
  return AzurWorld.playerMgr.myPlayerUnitAdapter.playerId == 0 and AzurWorld.playerMgr:GetMainPlayerId() or AzurWorld.playerMgr.myPlayerUnitAdapter.playerId
end

function this:getUnitData()
  return self.unitData
end

function this:getCSPlayerData()
  return self.unitData.csPlayer.data
end

function this:getIdleBehaviorSystem()
  return self:getSystem(L_EcsConst.systemType.idleBehaviorSystem)
end

function this:getOperatorSendSystem()
  return self:getSystem(L_EcsConst.systemType.operatorSend)
end

function this:getInteractSystem()
  return self:getSystem(L_EcsConst.systemType.interactSystem)
end

function this:createLuaEntity(csEntityId, type)
  if type == 1 then
    local csEntity = C_EntityManager.GetEntity(csEntityId)
    local entity = require(L_EcsConst.aliveType.hero).new(L_EcsConst.aliveType.hero)
    self._entityDic[csEntityId] = entity
    entity:bindCsEntity(csEntity)
    local heroData = require(L_EcsConst.aliveDataType.hero).new()
    heroData.id = csEntity.data.UUID
    heroData.configId = csEntity.data.configId
    entity:initialize(heroData)
    L_EntityManager:registerEntityTriggerStack(entity)
  elseif type == 2 then
    local csEntity = C_EntityManager.GetEntity(csEntityId)
    local entity = require(L_EcsConst.aliveType.pet).new(L_EcsConst.aliveType.pet)
    self._entityDic[csEntityId] = entity
    entity:bindCsEntity(csEntity)
    local petData = require(L_EcsConst.aliveDataType.pet).new()
    petData.id = csEntity.data.UUID
    petData.configId = csEntity.data.configId
    entity:initialize(petData)
    L_PetStore:refreshPetEntityGuidToEntityId(true, csEntity.data.UUID, csEntity.data.entityId)
  elseif type == 3 then
    local csEntity = C_EntityManager.GetEntity(csEntityId)
    local entity = require(L_EcsConst.aliveType.pet).new(L_EcsConst.aliveType.pet)
    self._entityDic[csEntityId] = entity
    entity:bindCsEntity(csEntity)
    local petData = require(L_EcsConst.aliveDataType.pet).new()
    petData.id = csEntity.data.UUID
    petData.configId = csEntity.data.configId
    petData.mounted = true
    entity:initialize(petData)
  elseif type == 4 then
    local csEntity = C_EntityManager.GetEntity(csEntityId)
    local entity = require(L_EcsConst.aliveType.monster).new(L_EcsConst.aliveType.monster)
    self._entityDic[csEntityId] = entity
    entity:bindCsEntity(csEntity)
    local monsterData = require(L_EcsConst.aliveDataType.monster).new()
    monsterData.id = csEntity.data.UUID
    monsterData.configId = csEntity.data.configId
    entity:initialize(monsterData)
  end
end

function this:destroyLuaEntity(csEntityId)
  local csEntity = C_EntityManager.GetEntity(csEntityId)
  if csEntity then
    L_PetStore:refreshPetEntityGuidToEntityId(false, csEntity.data.UUID)
  end
  local entity = self._entityDic[csEntityId]
  if entity then
    L_EntityManager:unRegisterEntityTriggerStack(entity)
    entity:onDestroy()
    self._entityDic[csEntityId] = nil
  end
end

function this:setMainControl(csEntityId)
  local souEntity, method
  if self._lastMainControlCsEntityId and self._entityDic[self._lastMainControlCsEntityId] then
    souEntity = self._entityDic[self._lastMainControlCsEntityId]
  end
  local entity = self._entityDic[csEntityId]
  if entity then
    local mainControlType = self:getMainControlType()
    if mainControlType == C_EPlayerMainControlType.Formation then
      method = "onSetMainHero"
    elseif mainControlType == C_EPlayerMainControlType.Mount then
      method = "onSetMainMount"
    elseif mainControlType == C_EPlayerMainControlType.Monster then
      method = "onSetMainMonster"
    elseif mainControlType == C_EPlayerMainControlType.KiBoTransform then
      method = "onSetMainKiBoTransform"
    else
      method = "onSetMainGm"
    end
  end
  if method then
    self:callAllSystem(method, entity, souEntity)
  end
  self._lastMainControlCsEntityId = csEntityId
end

function this:getHero(guid)
  local allHero = self:getAllHero()
  return allHero[guid]
end

function this:getEntityByCEntityId(id)
  return self._entityDic[id]
end

function this:getMainHero()
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId())
  if formationHero then
    local csEntityId = formationHero.heroEntityId
    if self._entityDic[csEntityId] then
      return self._entityDic[csEntityId]
    end
  end
end

function this:getMainPet()
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId())
  if formationHero then
    local csEntityId = formationHero.petEntityId
    if self._entityDic[csEntityId] then
      return self._entityDic[csEntityId]
    end
  end
end

function this:getAllHero()
  local result = {}
  local formationHeroList = AzurWorld.playerMgr:GetAllFormationHero(self:getPlayerId())
  for i, v in pairs(formationHeroList or {}) do
    local csEntityId = v.heroEntityId
    if self._entityDic[csEntityId] then
      if L_WorldManager:getCurModule() ~= L_Const.worldModule.bigBattleWorld then
        result[v.createData.heroGuid] = self._entityDic[csEntityId]
      else
        table.insert(result, self._entityDic[csEntityId])
      end
    end
  end
  return result
end

function this:getMainHeroEntity_cs()
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId())
  if formationHero then
    return formationHero:GetHeroEntity()
  end
end

function this:getMainPetEntity_cs()
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId())
  if formationHero then
    return formationHero:GetPetEntity()
  end
end

function this:getHeroEntityByPosIndex_cs(index)
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId(), index)
  if formationHero then
    return formationHero:GetHeroEntity()
  end
end

function this:getPetEntityByPosIndex_cs(index)
  local formationHero = AzurWorld.playerMgr:GetFormationHero(self:getPlayerId(), index)
  if formationHero then
    return formationHero:GetPetEntity()
  end
end

function this:getMainControlType()
  local mainControlComponent = AzurWorld.playerMgr:GetMainControlComponent(self:getPlayerId())
  if mainControlComponent then
    return mainControlComponent.mainControlType
  end
end

function this:getMainControlEntityPosition()
  local mainControlComponent = AzurWorld.playerMgr:GetMainControlComponent(self:getPlayerId())
  if mainControlComponent == nil then
    return L_Vector3.zero
  end
  local mainControlEntity = mainControlComponent:GetMainControlEntity()
  return L_Vector3.getRelativePos(mainControlEntity.transform.gameObject.transform)
end

function this:getMainControlEntityRotation()
  local mainControlComponent = AzurWorld.playerMgr:GetMainControlComponent(self:getPlayerId())
  if mainControlComponent == nil then
    return L_Vector3.zero
  end
  local mainControlEntity = mainControlComponent:GetMainControlEntity()
  return L_Vector3.getRot(mainControlEntity.transform.gameObject.transform)
end

function this:getMainControlEntity()
  local mainControlComponent = AzurWorld.playerMgr:GetMainControlComponent(self:getPlayerId())
  if mainControlComponent == nil then
    return
  end
  local mainControlEntityId = mainControlComponent.mainControlEntityId
  return self._entityDic[mainControlEntityId]
end

function this:getIsRidingMount()
  local mainControlComponent = AzurWorld.playerMgr:GetMainControlComponent(self:getPlayerId())
  if mainControlComponent == nil then
    return false
  end
  return mainControlComponent:GetIsRidingMount()
end

function this:getMountStatus()
  local mountComponent = AzurWorld.playerMgr:GetMountComponent(self:getPlayerId())
  if mountComponent == nil then
    return
  end
  return mountComponent.mountStatus
end

function this:getMountCDTime()
  local mountComponent = AzurWorld.playerMgr:GetMountComponent(self:getPlayerId())
  if mountComponent == nil then
    return 0
  end
  return mountComponent:GetMountCDTime()
end

function this:getIsMountCD()
  local mountComponent = AzurWorld.playerMgr:GetMountComponent(self:getPlayerId())
  if mountComponent == nil then
    return false
  end
  return mountComponent:GetIsMountCD()
end

function this:getMountEntityId()
  local mountComponent = AzurWorld.playerMgr:GetMountComponent(self:getPlayerId())
  if mountComponent == nil then
    return
  end
  return mountComponent.mountEntityId
end

return this
