local HeroComp = class("HeroComp", LuaComponent)

local HERO_LIST_CELL = "app/ui/hero/cell/hero_list_cell"
local OUT_SCREEN_X = 10000

function HeroComp:init()
	self.uiMap = self:getBaseObject():genAllChildren()
	self.scrollRect = self.uiMap["hero_ui.scrollrect"]:addLuaComponent(GConst.TYPEOF_LUA_CLASS.SCROLL_RECT_BASE)
    self.scrollRect:addInitCallback(function()
		return HERO_LIST_CELL
	end)
	self.scrollRect:addRefreshCallback(function(index, cell)
		cell:refresh(index, self.heroList, self.curFormation, self.allHeroCount, self.unlockCount, function(cell, heroId)
			self:onClickHero(cell, heroId)
		end)
	end)
	self.heroList = DataManager.HeroData:getAllHeroesSort()
	self.heroNodeList = {
		self.uiMap["hero_ui.formation.hero_1"],
		self.uiMap["hero_ui.formation.hero_2"],
		self.uiMap["hero_ui.formation.hero_3"],
		self.uiMap["hero_ui.formation.hero_4"],
		self.uiMap["hero_ui.formation.hero_5"],
	}
	self.heroAddImgList = {
		self.uiMap["hero_ui.formation.hero_1.add"],
		self.uiMap["hero_ui.formation.hero_2.add"],
		self.uiMap["hero_ui.formation.hero_3.add"],
		self.uiMap["hero_ui.formation.hero_4.add"],
		self.uiMap["hero_ui.formation.hero_5.add"],
	}
	self.heroBgSpineObj = {
		self.uiMap["hero_ui.formation.hero_1.ui_spine_obj"],
		self.uiMap["hero_ui.formation.hero_2.ui_spine_obj"],
		self.uiMap["hero_ui.formation.hero_3.ui_spine_obj"],
		self.uiMap["hero_ui.formation.hero_4.ui_spine_obj"],
		self.uiMap["hero_ui.formation.hero_5.ui_spine_obj"],
	}
	self.heroSpineList = {}
	self.largeHeroCell = CellManager:addCellComp(self.uiMap["hero_ui.scrollrect.viewport.content.large_hero_cell"], GConst.TYPEOF_LUA_CLASS.LARGE_HERO_CELL)
	self.txTitle = self.uiMap["hero_ui.top_bg.title_bg_img.title_tx"]
	self.rimgTopBG = self.uiMap["hero_ui.top_bg"]
	self.content = self.uiMap["hero_ui.scrollrect.viewport.content"]
	self.largeHeroCell:getBaseObject():setAnchoredPositionX(OUT_SCREEN_X)
	self.content:addClickListener(function()
		self.largeHeroCell:getBaseObject():setAnchoredPositionX(OUT_SCREEN_X)
	end)

	self.btnCollection = self.uiMap["hero_ui.btn_collect"]
	self.btnCollection:addClickListener(function()
		UIManager:showUI("app/ui/collection/collection_ui", GConst.CollectionConst.TYPE.HERO)
	end)
	self.uiMap["hero_ui.btn_collect.tx_collect"]:setText(I18N:getGlobalText(I18N.GlobalConst.COLLECTION_DESC_10))

	for index, obj in ipairs(self.heroNodeList) do
		obj:addClickListener(function()
			local heroId = self.curFormation[index]
			if heroId then
				local hero = DataManager.HeroData:getHeroById(heroId)
				if hero then
					ModuleManager.HeroManager:showHeroDetailUI(heroId, nil, nil, self.battleType)
				end
			end
		end)
		if self.heroBgSpineObj[index] then
			self.heroBgSpineObj[index]:playAnim("idle", true, false)
		end
	end

	self:bind(DataManager.CollectionData, "isDirty", function()
        self:refreshCollectEntrance()
    end)
	self:bind(DataManager.HeroData, "isDirty", function()
        self:refreshCollectEntrance()
    end)
	self:bind(DataManager.SkinData, "isDirty", function()
        self:refresh()
    end)
end

function HeroComp:refresh(battleType)
	self.battleType = battleType or self.battleType

	self:clearAdapt()
    self:adapt()
	self:refreshCollectEntrance()
	if self.battleType == GConst.BattleConst.FORMATION_TYPE.STAGE then
		self:refreshStageFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.ARENA_ATTACK then
		self:refreshArenaFightFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.ARENA_DEFEND then
		self:refreshArenaDefendFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.DUNGEON_WEAPON then
		self:refreshDungeonWeaponFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.DUNGEON_ARMOR then
		self:refreshDungeonArmorFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.BOSS_RUSH then
		self:refreshBossRushFormation()
	elseif self.battleType == GConst.BattleConst.FORMATION_TYPE.DUNGEON_RUNE then
		self:refreshDungeonRuneFormation()
	end
end

-- 展示主线章节阵容
function HeroComp:refreshStageFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.MAIN_BTN_2))
	self.rimgTopBG:setTexture("assets/arts/textures/background/hero/hero_bg_1.png")
	self.curFormation = DataManager.FormationData:getStageFormation()

	self.onClickUseFunc = function(id, type)
		ModuleManager.FormationManager:upHeroToStageFormation(id, type)
	end

	self:refreshScrollRect()
end

-- 展示竞技场进攻阵容
function HeroComp:refreshArenaFightFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.ARENA_DESC_10))
	self.rimgTopBG:setTexture("assets/arts/textures/background/arena/arena_bg_2.png")
	self.curFormation = DataManager.FormationData:getArenaAttackFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshArenaFightFormation()
	end

	self:refreshScrollRect()
end

-- 展示竞技场防守阵容
function HeroComp:refreshArenaDefendFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.ARENA_DESC_9))
	self.rimgTopBG:setTexture("assets/arts/textures/background/arena/arena_bg_2.png")
	self.curFormation = DataManager.FormationData:getArenaDefendFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshArenaDefendFormation()
	end

	self:refreshScrollRect()
end

-- 展示武器副本
function HeroComp:refreshDungeonWeaponFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.DUNGEON_WEAPON_DESC_15))
	self.rimgTopBG:setTexture("assets/arts/textures/background/hero/hero_bg_1.png")
	self.curFormation = DataManager.FormationData:getDungeonWeaponFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshDungeonWeaponFormation()
	end

	self:refreshScrollRect()
end

-- 展示支线副本
function HeroComp:refreshDungeonArmorFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.DUNGEON_ARMOR_DESC_4))
	self.rimgTopBG:setTexture("assets/arts/textures/background/hero/hero_bg_1.png")
	self.curFormation = DataManager.FormationData:getDungeonArmorFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshDungeonArmorFormation()
	end

	self:refreshScrollRect()
end

function HeroComp:refreshBossRushFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.ACT_BOSS_RUSH_DESC_9))
	self.rimgTopBG:setTexture("assets/arts/textures/background/hero/hero_bg_1.png")
	self.curFormation = DataManager.FormationData:getBossRushFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshBossRushFormation()
	end

	self:refreshScrollRect()
end

function HeroComp:refreshDungeonRuneFormation()
	self.txTitle:setText(I18N:getGlobalText(I18N.GlobalConst.DUNGEON_RUNE_TITLE))
	self.rimgTopBG:setTexture("assets/arts/textures/background/hero/hero_bg_1.png")
	self.curFormation = DataManager.FormationData:getDungeonRuneFormation()

	self.onClickUseFunc = function(id, type)
		DataManager.FormationData:upHeroToFormation(self.battleType, type, id)
		self:refreshDungeonRuneFormation()
	end

	self:refreshScrollRect()
end

function HeroComp:refreshScrollRect()
	self.heroList = DataManager.HeroData:getAllHeroesSort(self.battleType) -- 每次都重新算一次

	for i = 1, 5 do
		local heroId = self.curFormation[i]
		local hero = DataManager.HeroData:getHeroById(heroId)
		if hero and hero:getLv() > 0 then
			self.heroAddImgList[i]:setVisible(false)
			if self.heroSpineList[i] and self.heroSpineList[i]:getModelId() == hero:getModelId() then
				self.heroSpineList[i]:setActive(true)
				self.heroSpineList[i]:playAnimation("idle", true)
			else
				SpineManager:loadHeroAsync(hero:getModelId(), self.heroNodeList[i], function(spineObject)
					if heroId ~= self.curFormation[i] then
						return
					end
					if self.heroSpineList[i] then
						self.heroSpineList[i]:destroy()
					end
					spineObject:playAnimation("idle", true)
					spineObject:setLocalScale(0.7, 0.7, 0.7)
					self.heroSpineList[i] = spineObject
					self.heroSpineList[i]:setLocalPosition(0, -60, 0)
				end)
			end
		else
			self.heroAddImgList[i]:setVisible(true)
			if self.heroSpineList[i] then
				self.heroSpineList[i]:setActive(false)
			end
		end
	end

	self.allHeroCount = #self.heroList
	self.unlockCount = DataManager.HeroData:getUnlockHeroCount()
	local lockCount = self.allHeroCount - self.unlockCount
	local cellCount = 0
	if self.unlockCount > 0 then
		cellCount = cellCount + math.ceil(self.unlockCount / 4)
	end
	if lockCount > 0 then
		cellCount = cellCount + math.ceil(lockCount / 4)
	end
	local currCount = self.scrollRect:getTotalCount()
	if cellCount == currCount and not DataManager.TutorialData:getIsInTutorial() then -- 引导的时候强制重新填充
		self.scrollRect:refreshAll()
	else
		self.scrollRect:clearCells()
		self.scrollRect:refillCells(cellCount)
	end
end

function HeroComp:onClickHero(cell, heroId)
	if not cell or not heroId then
		self.largeHeroCell:getBaseObject():setAnchoredPositionX(OUT_SCREEN_X)
		return
	end

	local entity = DataManager.HeroData:getHeroById(heroId)
	if entity then
		if entity:isActived() and not DataManager.FormationData:heroInFormation(self.battleType, heroId) then
			local targetPos = cell:getBaseObject():getTransform().position
			local sPoint = UIManager:getUICameraComponent():WorldToScreenPoint(targetPos)
			targetPos = CS.BF.Utils.RectTransformScreenPointToLocalPointInRectangle(self.content:getTransform(), sPoint.x, sPoint.y, UIManager:getUICameraComponent())
			self.largeHeroCell:getBaseObject():setAnchoredPosition(targetPos.x, targetPos.y)
			self.largeHeroCell:getBaseObject():getTransform():SetAsLastSibling()
			self.largeHeroCell:refresh(entity, not entity:isActived(), self.onClickUseFunc)
			self.largeHeroCell:showCheck(self.curFormation[entity:getMatchType()] == heroId)
		else
			ModuleManager.HeroManager:showHeroDetailUI(heroId, nil, nil, self.battleType)
			self.largeHeroCell:getBaseObject():setAnchoredPositionX(OUT_SCREEN_X)
		end
	else
		self.largeHeroCell:getBaseObject():setAnchoredPositionX(OUT_SCREEN_X)
	end
end

function HeroComp:adapt()
    local addH = GFunc.calculateFitSizeY()
    local uiMap = self:getBaseObject():genAllChildren()
    local scrollRect = uiMap["hero_ui.scrollrect"]
    local viewport = uiMap["hero_ui.scrollrect.viewport"]
    if not self.rectDefaultSize then
        self.rectDefaultSize = scrollRect:getSizeDelta()
    end
    if not self.viewDefaultSize then
        self.viewDefaultSize = viewport:getSizeDelta()
    end
    scrollRect:setSizeDelta(self.rectDefaultSize.x, self.rectDefaultSize.y + addH)
    viewport:setSizeDelta(self.viewDefaultSize.x, self.viewDefaultSize.y + addH)
end

function HeroComp:clearAdapt()
    local uiMap = self:getBaseObject():genAllChildren()
    local scrollRect = uiMap["hero_ui.scrollrect"]
    local viewport = uiMap["hero_ui.scrollrect.viewport"]
    if not self.rectDefaultSize then
        self.rectDefaultSize = scrollRect:getSizeDelta()
    end
    if not self.viewDefaultSize then
        self.viewDefaultSize = viewport:getSizeDelta()
    end
    scrollRect:setSizeDelta(self.rectDefaultSize.x, self.rectDefaultSize.y)
    viewport:setSizeDelta(self.viewDefaultSize.x, self.viewDefaultSize.y)
end

function HeroComp:getHeroCell(heroId)
	if not self.scrollRect then
		return
	end
	local targetCell
	for index, cell in pairs(self.scrollRect:getListCell()) do
		local heroCell = cell:getHeroCellByHeroId(heroId)
		if heroCell then
			targetCell = heroCell
			break
		end
	end
	return targetCell
end

-- 刷新图鉴入口
function HeroComp:refreshCollectEntrance()
	if self.battleType == GConst.BattleConst.FORMATION_TYPE.STAGE then
		self.btnCollection:setVisible(DataManager.CollectionData:isOpen())
		if DataManager.CollectionData:hasRedPoint() then
			self.btnCollection:addRedPoint(25, 30, 0.6)
		else
			self.btnCollection:removeRedPoint()
		end
	else
		self.btnCollection:setVisible(false)
	end
end

return HeroComp