local UIPrefabObject = require "app/bf/unity/uiprefab_object"
local ScrollRectBase = class("ScrollRectBase", LuaComponent)

function ScrollRectBase:init()
    self:initBFScrollRect()
    self.cellList = {}

    -- c#层实例化后调用
    self.bfScrollRect:SetOnInstantiateCellAction(function(gameObject)
        if self:isDestroyed() then
            ResourceManager:destroyPrefab(gameObject)
            return
        end
        local prefabObject = UIPrefabObject:create()
        prefabObject:initWithGameObject(gameObject)
        prefabObject:initPrefabHelper()
        prefabObject:genAllChildren()
        self.baseObject:addChildList(prefabObject)

        if self.needFade then
            local fadeTime = self.fadeTime or 0.3
            if fadeTime > 0 then
                local canvasGroup = prefabObject:getComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
                if not canvasGroup then
                    canvasGroup = prefabObject:addComponent(GConst.TYPEOF_UNITY_CLASS.CANVAS_GROUP)
                end
                canvasGroup.alpha = 0
                local tween = canvasGroup:DOFade(1, fadeTime)
                tween:SetEase(CS.DG.Tweening.Ease.InOutSine)
                tween:SetLink(gameObject)
            end
        end

        local cell = prefabObject:addLuaComponent(self.initCallback())
        if self.initFinishCallback then
            self.initFinishCallback(cell)
        end
        table.insert(self.cellList, cell)
    end)

    self.bfScrollRect:SetRefreshAction(function(dataIndex, cellIndex)
        if self:isDestroyed() then
            return
        end
        local cell = self.cellList[cellIndex]
        if self.refreshCallback and cell then
            cell:setIndex(dataIndex)
            self.refreshCallback(dataIndex, cell)
        end
    end)

    self.bfScrollRect:SetSelectedAction(function(isSelected, cellIndex)
        if self:isDestroyed() then
            return
        end
        local cell = self.cellList[cellIndex]
        if self.selectedCallback and cell then
            self.selectedCallback(isSelected, cell)
        end
    end)
    self.bfScrollRect:SetAnchoredPositionChange(function(x, y)
        if self:isDestroyed() then
            return
        end
        if self.anchoredPositionChangeCallback then
            self.anchoredPositionChangeCallback(x, y)
        end
    end)
end

function ScrollRectBase:initBFScrollRect()
    self.bfScrollRect = self.baseObject:getComponent(GConst.TYPEOF_UNITY_CLASS.BF_SCROLL_RECT)
end

---- 淡入参数  initCellTime(多久加载一个cell，当为0时会一帧加载一个),fadeTime(渐显时长)
function ScrollRectBase:setFadeArgs(initCellTime, fadeTime)
    self.initCellTime = initCellTime
    self.fadeTime = fadeTime
end

---- 添加init回调
function ScrollRectBase:addInitCallback(callback)
    self.initCallback = callback
end

---- 添加loadCell完成回调
function ScrollRectBase:addInitFinishCallback(callback)
    if self.cellList then
        for k, v in ipairs(self.cellList) do
            callback(v)
        end
    end
    self.initFinishCallback = callback
end

---- 添加refresh回调
function ScrollRectBase:addRefreshCallback(callback)
    self.refreshCallback = callback
end

---- 添加选中回调
function ScrollRectBase:addSelectedCallback(callback)
    self.selectedCallback = callback
end

---- 添加滑动回调
function ScrollRectBase:addAnchoredPositionChangeCallback(callback)
    self.anchoredPositionChangeCallback = callback
end

---- 设置scroll rect 总数量
function ScrollRectBase:setTotalCount(count)
    self.totalCount = count
    self.bfScrollRect:SetTotalCount(count)
end

function ScrollRectBase:getTotalCount()
    return self.totalCount
end

---- 设置选中的index
function ScrollRectBase:setSelected(selectIndex)
    self.bfScrollRect:SetSelected(selectIndex)
end

function ScrollRectBase:refreshAll()
    if self.sid then
        SchedulerManager:unscheduleGlobal(self.sid)
        self.sid = nil
        self.bfScrollRect:SetTotalCount(self.totalCount)
    end
    self.bfScrollRect:RefreshAll()
end

function ScrollRectBase:refillCells(totalCount, needFade, targetIndex, fadeCount)
    self.totalCount = totalCount or self.totalCount
    self.needFade = needFade

    if targetIndex then
        self.needFade = false
    end

    if self.sid then
        SchedulerManager:unscheduleGlobal(self.sid)
        self.sid = nil
    end

    -- 1个C#计算有个bug 不能直接用SetTotalCount
    if totalCount == 1 then
        self.bfScrollRect:RefillCells(totalCount)
        return
    end
    if self.needFade then
        -- self.bfScrollRect:RefillCells(0)
        self.bfScrollRect:SetTotalCount(0)
        local curCount = 0
        local delay = self.initCellTime or 0.1
        self.sid = SchedulerManager:scheduleGlobal(function()
            if curCount == self.totalCount then
                self.sid = nil
                self.needFade = false
                return true
            else
                if self.baseObject:isDestroyed() then
                    self.sid = nil
                    self.needFade = false
                    return true
                end
                if fadeCount and fadeCount == curCount then
                    self.needFade = false
                    if self.sid then
                        SchedulerManager:unscheduleGlobal(self.sid)
                        self.sid = nil
                    end
                    self.bfScrollRect:SetTotalCount(self.totalCount)
                else
                    curCount = curCount + 1
                    self.bfScrollRect:SetTotalCount(curCount)
                end
            end
        end, delay)
    else
        self.bfScrollRect:RefillCells(self.totalCount, targetIndex or 0)
    end
end

function ScrollRectBase:updateAllCellByIdx(idx)
    for i = 1, #self.cellList do
        local cell = self.cellList[i]
        if self.refreshCallback and cell and cell:getIndex() == idx then
            local dataIndex = cell:getIndex()
            self.refreshCallback(dataIndex, cell)
        end
    end
end

function ScrollRectBase:updateAllCell()
    for i = 1, #self.cellList do
        local cell = self.cellList[i]
        if self.refreshCallback and cell then
            local dataIndex = cell:getIndex()
            if dataIndex <= self.totalCount then
                self.refreshCallback(dataIndex, cell)
            end
        end
    end
end

function ScrollRectBase:getAllCellAndIndex(callback)
    for i = 1, #self.cellList do
        local cell = self.cellList[i]
        if cell then
            local dataIndex = cell:getIndex()
            if dataIndex <= self.totalCount and dataIndex > 0 then
                callback(dataIndex, cell)
            end
        end
    end
end

function ScrollRectBase:moveToIndex(targetIndex)
    targetIndex = targetIndex or 0
    self.bfScrollRect:MoveToIndex(targetIndex)
end

---- 清除cell
function ScrollRectBase:clearCells()
    self.bfScrollRect:ClearCells()
end

function ScrollRectBase:removeCell(index)
    self.bfScrollRect:RemoveCell(index)
end

function ScrollRectBase:setTopRecoveryOffset(offset)
    self.bfScrollRect:SetTopRecoveryOffset(offset)
end

function ScrollRectBase:getTopRecoveryOffset()
    return self.bfScrollRect:GetTopRecoveryOffset()
end

function ScrollRectBase:setDownRecoveryOffset(offset)
    self.bfScrollRect:SetDownRecoveryOffset(offset)
end

function ScrollRectBase:getDownRecoveryOffset()
    return self.bfScrollRect:GetDownRecoveryOffset()
end

function ScrollRectBase:getBFScrollRect()
    return self.bfScrollRect
end

function ScrollRectBase:StopMovement()
    self.bfScrollRect:StopMovement()
end

function ScrollRectBase:onDestroy()
    LuaComponent.onDestroy(self)
    if self.sid then
        SchedulerManager:unscheduleGlobal(self.sid)
        self.sid = nil
    end
end

function ScrollRectBase:getListCellByIndex(index)
    for _, value in ipairs(self.cellList) do
        if value:getIndex() == index then
            return value
        end
    end
end

function ScrollRectBase:getListCell()
    return self.cellList
end

function ScrollRectBase:setCellHeight(height)
    self.bfScrollRect:SetCellHeight(height)
end

function ScrollRectBase:setCellWidth(width)
    self.bfScrollRect:SetCellWidth(width)
end

function ScrollRectBase:setPerLineNum(num)
    self.bfScrollRect:SetPerLineNum(num)
end

function ScrollRectBase:getCellWidth()
    return self.bfScrollRect.CellWidth
end

function ScrollRectBase:getCellHeight()
    return self.bfScrollRect.CellHeight
end

return ScrollRectBase