local BattlefieldDsbDuelManager = BaseClass("BattlefieldDsbDuelManager")
local Localization = CS.GameEntry.Localization
local BattlefieldInfoDsb = require("DataCenter.BattlefieldDsbDuel.Impl.BattlefieldInfoDsb")
local ActInfo = require("DataCenter.BattlefieldDsbDuel.BattlefieldDsbDuelActInfo")
local MyInfo = require("DataCenter.BattlefieldDsbDuel.BattlefieldDsbDuelMyInfo")
local csharpBattlefieldHandle = typeof(CS.BattlefieldHandle)

function BattlefieldDsbDuelManager:__init()
  self.actInfo = ActInfo.New()
  self.battleInfo = BattlefieldInfoDsb.New()
  self.myInfo = MyInfo.New()
  BattlefieldDsbDuelUtils.Log("Dsb inited.")
end

function BattlefieldDsbDuelManager:__delete()
  if self.battleInfo then
    self.battleInfo:Delete()
    self.battleInfo = nil
  end
  if self.actInfo then
    self.actInfo:Delete()
    self.actInfo = nil
  end
  BattlefieldDsbDuelUtils.Log("Dsb deleted.")
end

function BattlefieldDsbDuelManager:OnEnterGame()
  BattleFieldUtil.OnReconnect(BattleFieldType.DsbDuel)
end

function BattlefieldDsbDuelManager:OnGetActInfoMsg(t)
  self.actInfo:OnGetActInfoMsg(t)
  self.myInfo:UpdateFromActInfo(self.actInfo)
end

function BattlefieldDsbDuelManager:OnGetBattleInfoMsg(t)
  self.actInfo:OnGetBattleInfoMsg(t)
  self.myInfo:UpdateFromBattleInfo(self.actInfo)
end

function BattlefieldDsbDuelManager:OnHandleBattlePlayerInfoMsg(t)
  if self.battleInfo then
    self.battleInfo:OnHandleBattlePlayerInfo(t)
  end
  self.myInfo:UpdateFromBattlePlayerInfo(self.battleInfo)
end

function BattlefieldDsbDuelManager:TryJoinBattle()
  local actInfo = BattlefieldDsbDuelUtils.ActInfo
  if not actInfo then
    return
  end
  local errorCode = actInfo:CanEnterBattlefield()
  if errorCode then
    UIUtil.ShowTipsId(errorCode)
    return
  end
  local commonCheck = BattleFieldUtil.CheckCanEnterBattlefield(BattleFieldType.DsbDuel)
  if commonCheck then
    local myTeam = actInfo:GetSelfTeam()
    SFSNetwork.SendMessage(MsgDefines.DsbBattleEnter, myTeam)
  else
    UIManager:GetInstance():OpenWindow(UIWindowNames.UIDesertJumpTo, {anim = true}, BattleFieldType.DsbDuel)
    return
  end
end

function BattlefieldDsbDuelManager:TryWatchBattle(teamIndex, pointId)
  local actInfo = BattlefieldDsbDuelUtils.ActInfo
  if not actInfo then
    return
  end
  if not actInfo:IsInTeamBattlePhase() and not actInfo:IsInTeamBattleReadyPhase() then
    return
  end
  BattleFieldUtil.prePointId = pointId
  SFSNetwork.SendMessage(MsgDefines.DsbBattleWatch, teamIndex)
end

function BattlefieldDsbDuelManager:GetActInfo()
  return self.actInfo
end

function BattlefieldDsbDuelManager:GetCurGroup()
  if self.actInfo then
    return self.actInfo:GetCurGroup()
  end
end

function BattlefieldDsbDuelManager:GetBattleInfo()
  return self.battleInfo
end

function BattlefieldDsbDuelManager:GetMyInfo()
  return self.myInfo
end

function BattlefieldDsbDuelManager:GetBattleStartTimeSec()
  if self.battleInfo then
    return self.battleInfo:GetBattleStartTimeSec()
  end
  return 0
end

function BattlefieldDsbDuelManager:GetCfgValue(key, season)
  return BattleFieldUtil.GetBattleFieldCfgValue(BattleFieldType.DsbDuel, key, season)
end

function BattlefieldDsbDuelManager:GetBuildData(pointId)
  if self.battleInfo then
    return self.battleInfo:GetBuildData(pointId)
  end
end

function BattlefieldDsbDuelManager:CheckBattleStart()
  if not self.battleInfo then
    return false
  end
  return self.battleInfo:CheckBattleStart()
end

function BattlefieldDsbDuelManager:FillBuildBtnList(point, btnList)
  if self.battleInfo then
    return self.battleInfo:FillBuildBtnList(point, btnList)
  end
end

function BattlefieldDsbDuelManager:UpdateMapBR()
  local baseObj = BattleFieldUtil.GetMapObj(BattleFieldType.DsbDuel)
  if IsNull(baseObj) then
    return
  end
  local battleInfo = self:GetBattleInfo()
  if not battleInfo then
    return
  end
  local mapHandle = baseObj:GetComponent(csharpBattlefieldHandle)
  if mapHandle then
    for role = BattlefieldDsbConst.RoleType.MIN, BattlefieldDsbConst.RoleType.MAX do
      local index = role - 1
      local color = BattlefieldDsbDuelUtils.GetColorByRoleType(role, true)
      if color then
        local renderer = mapHandle:GetRenderer(index)
        if IsNotNull(renderer) then
          renderer.sharedMaterial = mapHandle:GetMaterial(color.bfMaterialIndex)
        end
      end
    end
  end
end

function BattlefieldDsbDuelManager:HandleBuildingHpChange(msg)
  if self.battleInfo then
    self.battleInfo:UpdateFromBuildingHpChangeMsg(msg)
  end
end

function BattlefieldDsbDuelManager:BuildOpenCheck(buildInfo)
  if self.battleInfo then
    return self.battleInfo:BuildOpenCheck(buildInfo)
  end
  return false
end

function BattlefieldDsbDuelManager:OnHandleEnterMessage(msg, watcher)
  if self.battleInfo then
    self.battleInfo:Delete()
    self.battleInfo = nil
  end
  self.battleInfo = BattlefieldInfoDsb.New(BattleFieldType.DsbDuel)
  self.battleInfo:UpdateFromEnterMsg(msg, watcher)
  self.myInfo:UpdateFromEnterMsg(self.battleInfo)
  local cb = function()
    self.actInfo:OnEnterBattlefield(watcher)
  end
  self.battleInfo:Enter()
  BattleFieldUtil.HandleEnterWorld(BattleFieldType.DsbDuel, msg, cb)
end

function BattlefieldDsbDuelManager:OnPushBattleScore(msg)
  local errCode = msg.errorCode
  if errCode ~= nil then
    UIUtil.ShowTipsId(errCode)
  elseif self.battleInfo then
    self.battleInfo:UpdateFromScoreUpdateMsg(msg)
    self.myInfo:UpdateFromScoreUpdateMsg(self.battleInfo)
  end
end

function BattlefieldDsbDuelManager:OnLeaveBattle(msg)
  if msg.errorCode then
    BattlefieldDsbDuelUtils.LogError("dsb.battle.leave failed. %s", msg.errorCode)
    UIUtil.ShowTipsId(msg.errorCode)
    return
  end
  if self.actInfo then
    self.actInfo:OnLeaveBattlefield()
  end
end

function BattlefieldDsbDuelManager:GetBuildBestMarch(buildUUID)
  if not self.battleInfo then
    return
  end
  local topInfo = self.battleInfo:GetBuilding(buildUUID)
  local marchUuid = topInfo ~= nil and topInfo.marchUUID or nil
  local bestMarch = marchUuid ~= nil and DataCenter.WorldMarchDataManager:GetMarch(marchUuid) or nil
  return bestMarch, topInfo
end

function BattlefieldDsbDuelManager:GetBuilding(buildUUID)
  if not self.battleInfo then
    return
  end
  return self.battleInfo:GetBuilding(buildUUID)
end

function BattlefieldDsbDuelManager:CanMultiAssistance()
  return BattleFieldUtil.CanMultiAssistance(BattleFieldType.DsbDuel)
end

function BattlefieldDsbDuelManager:CheckTargetInSafeArea(pointId)
  local t = BattleFieldUtil.GetBlockRangeValue(pointId, BattleFieldType.DsbDuel)
  local myInfo = self:GetMyInfo()
  local curSide = myInfo and myInfo.selfRoleId or BattlefieldDsbConst.RoleType.None
  if t < 2 then
    return false
  end
  if curSide ~= t - 1 then
    return true
  end
  return false
end

function BattlefieldDsbDuelManager:GetClosestPos(pos)
  if self.battleInfo then
    return self.battleInfo:GetClosestPos(pos)
  end
end

function BattlefieldDsbDuelManager:GetBuildUpEffInfo()
  if self.battleInfo then
    return self.battleInfo:GetBuildUpEffInfo()
  end
  return false, 0
end

function BattlefieldDsbDuelManager:GetWorldCamp(role)
  if not role or role == 0 then
    return WorldCamp.Neutral
  end
  return BattlefieldDsbDuelUtils.GetMyRoleId() == role and WorldCamp.Self or WorldCamp.Enemy
end

function BattlefieldDsbDuelManager:GetAttackInfo(mainIndex, allianceId)
  if self.battleInfo then
    return self.battleInfo:GetAttackInfo(mainIndex, allianceId)
  end
end

function BattlefieldDsbDuelManager:SendDragonHospitalFinishMsg()
  if self.battleInfo then
    return self.battleInfo:SendDragonHospitalFinishMsg()
  end
end

function BattlefieldDsbDuelManager:SendDragonHospitalViewMsg()
  if self.battleInfo then
    return self.battleInfo:SendDragonHospitalViewMsg()
  end
end

function BattlefieldDsbDuelManager:GetTreatmentSpeed()
  if self.battleInfo then
    return self.battleInfo:GetTreatmentSpeed()
  end
  return 0
end

function BattlefieldDsbDuelManager:GetAccumulativeTreatmentSoldierNum()
  if self.battleInfo then
    return self.battleInfo:GetAccumulativeTreatmentSoldierNum()
  end
  return 0
end

function BattlefieldDsbDuelManager:GetTreatmentSoldierDataList()
  if self.battleInfo then
    return self.battleInfo:GetTreatmentSoldierDataList()
  end
  return
end

function BattlefieldDsbDuelManager:GetTreatmentFinishSoldierNum()
  if self.battleInfo then
    return self.battleInfo:GetTreatmentFinishSoldierNum()
  end
  return 0
end

function BattlefieldDsbDuelManager:ReqBattleEffect()
  if not self.battleInfo then
    return
  end
  local team = self.battleInfo:GetTeam()
  if not team then
    return
  end
  SFSNetwork.SendMessage(MsgDefines.EpidemicZoneBattleEffect, BattleFieldType.DsbDuel, team)
end

function BattlefieldDsbDuelManager:CanShowEnter()
  local actInfo = self:GetActInfo()
  if not actInfo then
    return
  end
  if not actInfo:IsInTeamBattlePhase() and not actInfo:IsInTeamBattleReadyPhase() then
    return
  end
  local lastTime = actInfo.lastEnterBattleTime or 0
  return 0 < lastTime
end

function BattlefieldDsbDuelManager:HandleEffects(msg)
  if self.battleInfo then
    return self.battleInfo:HandleEffects(msg)
  end
end

function BattlefieldDsbDuelManager:CheckCanEnterBattlefield(checkType)
  if self.actInfo then
    return self.actInfo:CheckCanEnterBattlefield(checkType)
  end
  return nil
end

function BattlefieldDsbDuelManager:Description()
  local sb = StringBuilder.New()
  sb:AppendLine("---DSB---")
  sb:AppendLine("\230\136\145\231\154\132\228\191\161\230\129\175(MyInfo)")
  local myInfo = self:GetMyInfo()
  sb:AppendLine(myInfo and myInfo:Description() or "\231\169\186")
  sb:AppendLine("\230\180\187\229\138\168\228\191\161\230\129\175(ActInfo)")
  local actInfo = self:GetActInfo()
  sb:AppendLine(actInfo and actInfo:Description() or "\231\169\186")
  sb:AppendLine()
  sb:AppendLine("\230\136\152\229\156\186\228\191\161\230\129\175(BattleInfo)")
  local battleInfo = self:GetBattleInfo()
  sb:AppendLine(battleInfo and battleInfo:Description() or "\231\169\186")
  sb:AppendLineFormat("\232\129\138\229\164\169\230\136\191\233\151\180(\230\136\145\230\150\185):%s", BattlefieldDsbDuelUtils.TryGetSelfBattleRoomId() or "")
  sb:AppendLine("\230\136\152\229\156\186\229\163\171\229\133\181\228\191\161\230\129\175")
  sb:AppendLineFormat(BattleFieldUtil.GetSoldierDescription())
  local txt = sb:ToString()
  Logger.Log(txt)
  return txt
end

Implement(BattlefieldDsbDuelManager, InterfaceConfig.BattlefieldManager, InterfaceConfig.BattlefieldTreatment, InterfaceConfig.BattlefieldEnterCheck)
return BattlefieldDsbDuelManager
