local BoxRewardUI = class("BoxRewardUI", BaseUI)
local BOX_HERO_CELL = "app/ui/shop/cell/box_hero_cell"

local CELL_NUM = 4
local QLT_DELAY_TIME = {
    [1] = 0.3, -- 预留
    [2] = 0.3, -- 绿
    [3] = 0.3, -- 蓝
    [4] = 0.5, -- 紫
    [5] = 0.5, -- 预留
}
local FIRST_DELAY_TIME = 0
local FADE_TIME = 0.5
local MAX_SCREEN_CELL_COUNT = 8 -- 触发滑动的限制值
local SCROLL_MOVE_TIME = 0.5

local REWARD_CELL_WIDTH = 160
local REWARD_CELL_HEIGHT = 250

local BASE_CONTENT_HEIGHT = 600
local JUMP_TIME_SCALE = 1000

local POSITION_X_DATA = {
    [1] = {0},
    [2] = {-120, 120},
    [3] = {-200, 0, 200},
    [4] = {-240, -80, 80, 240}
}

function BoxRewardUI:ctor(params)
    self.params = params or {}
    self.rewards = params.rewards or {}
    self.actionStatus = {} -- 表现状态
    self.cellDelayTime = {} -- {idx,time}
    self.isPlayAni = true
    -- 前端用展示奖励
    self.fragmentRewards = {}
    self.coinNum = 0
    local fragmentMap = {}
    -- 将服务器格式转为前端用的格式
    for _, reward in ipairs(self.rewards) do
        if reward.type == GConst.REWARD_TYPE.ITEM and reward.item.id == GConst.ItemConst.ITEM_ID_GOLD then
            self.coinNum = self.coinNum + reward.item.count
        elseif reward.item.id ~= GConst.ItemConst.ITEM_ID_GEM then
            local id = reward.item.id
            local count = reward.item.count
            fragmentMap[id] = (fragmentMap[id] or 0) + count
        end
    end
    for id, count in pairs(fragmentMap) do
        table.insert(self.fragmentRewards, {id = id, count = count})
    end
end

function BoxRewardUI:isFullScreen()
    return true
end

function BoxRewardUI:getPrefabPath()
    return "assets/prefabs/ui/shop/box_reward_ui.prefab"
end

function BoxRewardUI:onLoadRootComplete()
    self.uiMap = self.root:genAllChildren()

    self.titleTx = self.uiMap["box_reward_ui.title.text"]
    self.titleTx:setText(I18N:getGlobalText(I18N.GlobalConst.SHOP_DESC_8)) -- 恭喜获得

    self.coinNode = self.uiMap["box_reward_ui.coin_node"]
    self.coinIcon = self.uiMap["box_reward_ui.coin_node.coin"]
    self.coinTx = self.uiMap["box_reward_ui.coin_node.text"]
    if self.coinNum > 0 then
        self.coinNode:setVisible(true)
        self.coinTx:setText(self.coinNum)
        GFunc.centerImgAndTx(self.coinIcon, self.coinTx, 5)
    else
        self.coinNode:setVisible(false)
    end

    self.closeTx = self.uiMap["box_reward_ui.close_tx"]
    self:refreshCloseText()

    self.mask = self.uiMap["box_reward_ui.mask"]
    self.mask:addClickListener(function()
        -- 动画期间不可关闭
        if self.isPlayAni then
            self:jump()
            return
        end
        self:closeUI()
        -- 如果宝箱等级提升了 则要弹出宝箱等级提升UI
        if DataManager.SummonData:checkNeedPopBoxLvUpUI() then
            DataManager.SummonData:clearNeedPopBoxLvUpUI()
            ModuleManager.ShopManager:showBoxLevelUpUI()
        end
    end)

    -- 关闭上一个界面
    EventManager:dispatchEvent(EventManager.CUSTOM_EVENT.CLOSE_BOX_OPEN_UI)

    -- 因为特殊表现 用普通scrollRect处理
    self.scrollRectContent = self.uiMap["box_reward_ui.scroll_rect.viewport.content"]
    self.scrollMask = self.uiMap["box_reward_ui.scroll_mask"]
    self.scrollMask:setVisible(true)
    self.baseCell = self.uiMap["box_reward_ui.scroll_rect.viewport.content.cell"]
    self.baseCell:setVisible(false)
    -- 已拥有的cell
    self.rewardCells = self.rewardCells or {}
    local contentTrans = self.scrollRectContent:getTransform()
    local alreadyCellCount = contentTrans.childCount - 1
    local rewardCount = #self.fragmentRewards
    if alreadyCellCount > 0 then
        for i = 1, alreadyCellCount do
            local prefab = contentTrans:GetChild(i).gameObject
            local UIPrefabObject = require "app/bf/unity/uiprefab_object"
            local prefabObject = UIPrefabObject:create()
            prefabObject:initWithPrefab(GConst.EMPTY_STRING, prefab)
            prefabObject:initPrefabHelper()
            -- 设定位置
            local index = i
            local rowIdx = (index - 1) % CELL_NUM + 1 -- 横排位置 1-4
            local cowIdx = (index - 1) // CELL_NUM + 1 
            if rewardCount <= CELL_NUM then -- 居中展示
                prefabObject:setAnchoredPosition(POSITION_X_DATA[rewardCount][rowIdx], 0)
            else
                prefabObject:setAnchoredPosition(POSITION_X_DATA[4][rowIdx], -(cowIdx - 1) * REWARD_CELL_HEIGHT)
            end
            table.insert(self.rewardCells, CellManager:addCellComp(prefabObject, BOX_HERO_CELL))
        end
    end
    local cellCount = #self.rewardCells
    local needCreateCount = rewardCount - cellCount
    -- 将cell扩充至与奖励等数量
    if needCreateCount > 0 then
        for i = 1, needCreateCount do 
            local prefab = CS.UnityEngine.Object.Instantiate(self.baseCell:getGameObject())
            local UIPrefabObject = require "app/bf/unity/uiprefab_object"
            local prefabObject = UIPrefabObject:create()
            prefabObject:initWithPrefab(GConst.EMPTY_STRING, prefab)
            prefabObject:initPrefabHelper()
            prefabObject:setParent(self.scrollRectContent, false)
            prefabObject:getTransform():SetAsLastSibling()
            prefabObject:setVisible(true)
            -- 设定位置
            local index = cellCount + i
            local rowIdx = (index - 1) % CELL_NUM + 1 -- 横排位置 1-4
            local cowIdx = (index - 1) // CELL_NUM + 1 
            if rewardCount <= CELL_NUM then -- 居中展示
                prefabObject:setAnchoredPosition(POSITION_X_DATA[rewardCount][rowIdx], 0)
            else
                prefabObject:setAnchoredPosition(POSITION_X_DATA[4][rowIdx], -(cowIdx - 1) * REWARD_CELL_HEIGHT)
            end
            table.insert(self.rewardCells, CellManager:addCellComp(prefabObject, BOX_HERO_CELL))
        end
    end
    -- 刷新
    cellCount = #self.rewardCells
    for i = 1, cellCount do
        if i <= rewardCount then
            self.rewardCells[i]:setVisible(true)
            self.rewardCells[i]:refresh(self.fragmentRewards[i])
            self.rewardCells[i]:disableAllEffect()
        else
            self.rewardCells[i]:setVisible(false)
        end
    end
    self.maxCow = (rewardCount - 1) // CELL_NUM + 1 -- 最大行数 1-4 = 1, 5-8 = 2,...
    self.maxScrollContentHeight = math.max(BASE_CONTENT_HEIGHT, self.maxCow * REWARD_CELL_HEIGHT)
    self.scrollRectContent:setAnchoredPositionY(0)
    self.scrollRectContent:setSizeDeltaY(self.maxScrollContentHeight)
    
    -- 如果超出屏蔽显示范围 初始化滑动数据
    if rewardCount > MAX_SCREEN_CELL_COUNT then
        self.showAction = true
        self.turnIdx = MAX_SCREEN_CELL_COUNT // CELL_NUM
        self.maxIdx = math.ceil(rewardCount / CELL_NUM)
    end
    -- 播放表现
    if not self.cellSeqs then
        self.cellSeqs = {}
    end
    for idx = 1, rewardCount do
        local cell = self.rewardCells[idx]
        self:playCellAction(cell, idx)
    end
end

function BoxRewardUI:playCellAction(cell, idx)
	if self.actionStatus[idx] then
		return
	end

    local delayTime = FIRST_DELAY_TIME
    if idx > 1 then
        delayTime = self:getCellDelayTime(idx - 1)
    end

	local canvasGroup = cell.baseObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
	if not canvasGroup then
		canvasGroup = cell.baseObject:addComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
	end
	canvasGroup.alpha = 0

	local seq = cell.baseObject:createBindTweenSequence()
    table.insert(self.cellSeqs, seq)

	-- local tween = canvasGroup:DOFade(1, FADE_TIME)
    seq:AppendInterval(delayTime)
	-- tween:SetEase(CS.DG.Tweening.Ease.InOutSine)
    seq:AppendCallback(function()
        cell:setSpineVisible(false) -- 防止spine因透明度变化导致的闪白
    end)
	-- seq:Append(tween)
	seq:AppendCallback(function()
        if not self:isClosed() then
            -- 恢复显示
            canvasGroup.alpha = 1
            -- 特效
            if self.isPlayAni then
                cell:playEffect()
            else
                cell:disableAllEffect()
            end
            -- 如果需要spine 则显示
            local heroEntity = DataManager.HeroData:getHeroById(self.fragmentRewards[idx].id)
            if heroEntity and heroEntity:canLvUp() then
                cell:setSpineVisible(true)
            end

            self.actionStatus[idx] = true
            self:turnToNext(idx)
            -- 最后一个表现完毕
            if idx == #self.fragmentRewards then
                self.isPlayAni = false
                self:refreshCloseText()
                self.scrollMask:setVisible(false)
            end
        end
	end)
end

function BoxRewardUI:turnToNext(idx)
    if self:isClosed() then
        return
    end
    if not self.isPlayAni then
        return
    end
	if not self.showAction or idx ~= self.turnIdx * CELL_NUM then
		return
	end
    if self.contentSeq then
        self.contentSeq:Kill()
        self.contentSeq = nil
    end
    self.contentSeq = self.root:createBindTweenSequence()
    self.contentSeq:Append( 
        self.scrollRectContent:getTransform():DOLocalMoveY(math.min(self.maxScrollContentHeight - BASE_CONTENT_HEIGHT, (self.turnIdx + 1) * REWARD_CELL_HEIGHT - BASE_CONTENT_HEIGHT), SCROLL_MOVE_TIME)
    )
    self.contentSeq:AppendCallback(
        function()
            self.turnIdx = self.turnIdx + 1
            if self.turnIdx >= self.maxIdx then
                self.showAction = false
            end
        end
    )
end

function BoxRewardUI:getCellDelayTime(idx)
    if not self.cellDelayTime[idx] then
        local reward = self.fragmentRewards[idx]
        local id = reward.id
        local qlt = 2 -- 默认品质
        local heroCfgInfo = ConfigManager:getConfig("hero")[id]
        if heroCfgInfo then
            qlt = heroCfgInfo.qlt
        end
        local cellDelayTime = QLT_DELAY_TIME[qlt] -- 这个cell的延迟时间
        if idx == 1 then 
            self.cellDelayTime[idx] = cellDelayTime
        else
            self.cellDelayTime[idx] = cellDelayTime + self:getCellDelayTime(idx - 1)
        end
    end
    return self.cellDelayTime[idx]
end

function BoxRewardUI:jump()
    self.isPlayAni = false

    if self.cellSeqs then
        for _, cellSeq in ipairs(self.cellSeqs) do
            cellSeq.timeScale = JUMP_TIME_SCALE 
        end
    end
    if self.contentSeq then
        self.contentSeq.timeScale = JUMP_TIME_SCALE 
    end
    
    -- 强制刷新一次表现
    local rewardCount = #self.fragmentRewards
    for idx = 1, rewardCount do
        local cell = self.rewardCells[idx]
        local canvasGroup = cell.baseObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
        if not canvasGroup then
            canvasGroup = cell.baseObject:addComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
        end
        canvasGroup.alpha = 1
        cell:disableAllEffect()
    end
    self.scrollRectContent:setAnchoredPositionY(self.maxScrollContentHeight - BASE_CONTENT_HEIGHT)
    self.turnIdx = self.maxIdx
    self.showAction = false
    self:refreshCloseText()
end

function BoxRewardUI:refreshCloseText()
    if self.isPlayAni then
        self.closeTx:setText(I18N:getGlobalText(I18N.GlobalConst.SUMMON_SKIP))
    else
        self.closeTx:setText(I18N:getGlobalText(I18N.GlobalConst.CLICK_CLOSE_DESC))
    end
end

return BoxRewardUI