local this = class("moduleProductNormalNew", G_UIModuleBase)
local _ProductsTpl = L_GameTpl:getProductsTpl()
local _HomeBuildingTpl = L_GameTpl:getHomeBuildingTpl()
local _HomeBuildingGroupTpl = L_GameTpl:getHomeBuildingGroupTpl()
local _HomeBuildingProductTpl = L_GameTpl:getHomeBuildingProductionTpl()
local _taskConditionTpl = L_GameTpl:getTaskConditionTpl()
local columnNum = 5
local columnNum_card = 2
local minLineNum = 5
local ProductItemType2InsertEndCheckFuncName = {
  [L_Const.resType.mountSaddle] = "checkIsNeedInsertEndSaddleType"
}

function this.bind()
  return {
    module_commonTab = {
      moduleName = "modulePages/tabList/modulePageProductTabList"
    },
    active_tab = false,
    formulaList_normal = {
      moduleName = "pages/product/cellProduceTarget"
    },
    active_formulaList_normal = false,
    formulaList_card = {
      moduleName = "pages/product/cellProduceTarget_card"
    },
    active_formulaList_card = false,
    formulaList_egg = {
      moduleName = "Pages/Pet/cellPetEggItem"
    },
    active_formulaList_egg = false
  }
end

function this.methods()
  return {
    formulaList_normal = {
      onClick_selectId = function(self, id)
        self:onSelectTarget(id, self.bind.formulaList_normal, L_HomeConst.SourceOfPlayModuleProductInfoAnimation.OnClickItem)
      end
    },
    formulaList_card = {
      onClick_selectId = function(self, id)
        self:onSelectTarget(id, self.bind.formulaList_card, L_HomeConst.SourceOfPlayModuleProductInfoAnimation.OnClickItem)
      end
    },
    formulaList_egg = {
      onClick_selectId = function(self, id)
        self:onSelectEgg(id, self.modules.formulaList_egg, L_HomeConst.SourceOfPlayModuleProductInfoAnimation.OnClickItem)
      end
    }
  }
end

function this:open()
  function self._refreshView()
    self:refreshList()
  end
  
  L_HomeStore:listenCallFunc(L_HomeStore.event.syncWorldMapHomeItem, self._refreshView)
  L_ProductStore:listenCallFunc(L_ProductStore.event.refreshHomeProduct, self._refreshView)
  L_TaskStore:listenCallFunc(L_TaskStore.event.refreshTask, self.refreshTraceTaskNode, self)
end

function this:close()
  L_HomeStore:unListenCallFunc(L_HomeStore.event.syncWorldMapHomeItem, self._refreshView)
  L_ProductStore:unListenCallFunc(L_ProductStore.event.refreshHomeProduct, self._refreshView)
  L_TaskStore:unListenCallFunc(L_TaskStore.event.refreshTask, self.refreshTraceTaskNode, self)
end

function this:initModule(guid)
  if not guid then
    return
  end
  self._guid = guid
  self._data = L_HomeStore:getHomeBuildingByGuid(guid)
  self._tpl = _HomeBuildingProductTpl:getTplById(self._data.build_id)
  self._type = L_HomeUtil.getBuildingType(guid)
  self:refreshtraceTaskId2TraceFormulaIdListDic()
  local tabs = _HomeBuildingProductTpl:getTab(self._tpl)
  local tabsNum = tabs and #tabs or 0
  self.bind.active_tab = 0 < tabsNum
  if 0 < tabsNum then
    local tabParam = {
      idList = tabs,
      tabType = "product",
      callback = function(tabId)
        self._selectedId = 0
        self._currTabId = tabId
        self:refreshList(L_HomeConst.SourceOfPlayModuleProductInfoAnimation.OnClickTab)
      end
    }
    local moduleTab = self.modules.module_commonTab
    moduleTab:setData(tabParam)
    self:refreshTabListTaskTraceNode()
  else
    self:refreshList()
  end
end

function this:refreshList(sourceOfPlayModuleProductInfoAnimation)
  if not self._guid then
    return
  end
  if self._type == L_Const.WorldMapBuildType.WMBT_HATCH then
    self.focusList = self.bind.formulaList_egg
    self.bind.active_formulaList_egg = true
    self:setEggProductList(self:getSortPetEggList(), sourceOfPlayModuleProductInfoAnimation)
  else
    self.listType = _HomeBuildingProductTpl:getProductListType(self._tpl)
    if self.listType == 2 then
      self.focusList = self.bind.formulaList_card
      self.bind.active_formulaList_card = true
    else
      self.focusList = self.bind.formulaList_normal
      self.bind.active_formulaList_normal = true
    end
    self:setProductList(L_ProductManager:getAllProductForBuilding(self._data.build_id, self._currTabId), sourceOfPlayModuleProductInfoAnimation)
  end
  self:refreshProductTaskTraceNode()
end

function this:setProductList(targetProductDatas, sourceOfPlayModuleProductInfoAnimation)
  local datas = self:sortTargetProductDatas(targetProductDatas)
  local list = self.focusList or self.bind.formulaList_normal
  if #datas <= 0 then
    list:clear()
    self:onSelectTarget(0, list, sourceOfPlayModuleProductInfoAnimation)
    return
  end
  local colNum = self.listType == 2 and columnNum_card or columnNum
  local lineNum = math.ceil(#datas / colNum)
  lineNum = math.max(lineNum, minLineNum)
  for i = 1, lineNum * colNum - #datas do
    table.insert(datas, {isFood = false, itemData = false})
  end
  if #datas ~= #list then
    list:clear()
    list:insert_array(datas)
  else
    for i = 1, #list do
      list:change(i, datas[i])
    end
  end
  if math.isEmpty(self._selectedId) then
    if 0 < #list then
      self:onSelectTarget(list:getValue(1, "id"), list, sourceOfPlayModuleProductInfoAnimation)
    else
      self:onSelectTarget(0, list, sourceOfPlayModuleProductInfoAnimation)
    end
  elseif not math.isEmpty(self._selectedId) then
    local selectIdIsInList = false
    for i = 1, #list do
      local itemId = list:getValue(i, "id")
      if itemId == self._selectedId then
        selectIdIsInList = true
      end
    end
    self:onSelectTarget(selectIdIsInList and self._selectedId or list:getValue(1, "id"), list, sourceOfPlayModuleProductInfoAnimation)
  end
end

function this:setEggProductList(targetProductDatas, sourceOfPlayModuleProductInfoAnimation)
  local list = self.focusList or self.bind.formulaList_egg
  local listModule = self.modules.formulaList_egg
  local lineNum = math.ceil(#targetProductDatas / columnNum)
  lineNum = math.max(lineNum, minLineNum)
  if lineNum * columnNum ~= #list then
    list:clear()
    list:insert_array(L_DataUtil.getEmptyModuleDatas(lineNum * columnNum))
  end
  for i, module in ipairs(listModule) do
    module:refreshView(targetProductDatas[i] and targetProductDatas[i].guid, self._guid)
  end
  if 0 < #targetProductDatas then
    self:onSelectEgg(targetProductDatas[1].guid, listModule, sourceOfPlayModuleProductInfoAnimation)
  else
    self:onSelectEgg(0, listModule, sourceOfPlayModuleProductInfoAnimation)
  end
end

function this:sortTargetProductDatas(targetProductDatas)
  local datas
  local frontList = {}
  local endList = {}
  for _, targetProductData in pairs(targetProductDatas) do
    if targetProductData.itemData and targetProductData.itemData.itemType then
      local targetProductItemType = targetProductData.itemData.itemType
      local funcName = ProductItemType2InsertEndCheckFuncName[targetProductItemType]
      local isNeedInsertEnd = false
      if funcName then
        isNeedInsertEnd = self[funcName](self, targetProductData)
      end
      if isNeedInsertEnd == false then
        table.insert(frontList, targetProductData)
      else
        table.insert(endList, targetProductData)
      end
    else
      table.insert(frontList, targetProductData)
    end
  end
  for _, productData in pairs(endList) do
    table.insert(frontList, productData)
  end
  datas = frontList
  return datas
end

function this:checkIsNeedInsertEndSaddleType(saddleTypeProductData)
  local itemId = saddleTypeProductData.itemData.itemId
  local isHas = AzurWorld.mountMgr:GetIdMountSaddleUnlock(itemId)
  return isHas
end

function this:refreshBuildingProductTargetList(force)
  local products = L_ProductManager:getTargetProductForBuilding(self._data.build_id, self._currTabId)
  if #products <= 0 then
    self.bind.active_gridEmpty = true
    self:onSelectDecoTarget(0)
    return
  end
  self.bind.active_gridEmpty = false
  local lineNum = math.ceil(#products / columnNum)
  lineNum = math.max(lineNum, minLineNum)
  self.bindComponents.decorationList.disableScroll = lineNum <= minLineNum
  for i = 1, lineNum * columnNum - #products do
    table.insert(products, {isFood = false, itemData = false})
  end
  if #products ~= #self.bind.list_decoration then
    self.bind.list_decoration:clear()
    self.bind.list_decoration:insert_array(products)
  else
    for i = 1, #self.bind.list_decoration do
      self.bind.list_decoration:change(i, products[i])
    end
  end
  if math.isEmpty(self._selectedId) and 0 < #self.bind.list_decoration then
    self:onSelectDecoTarget(self.modules.list_decoration[1].bind.id)
  elseif math.isEmpty(self._selectedId) then
    self:onSelectDecoTarget(0)
  end
end

function this:onSelectTarget(id, list, isOnClickTab)
  if not list then
    return
  end
  self._selectedId = id
  for i = 1, #list do
    list:change(i, {
      selectIconActive = list:getValue(i, "id") == id
    })
  end
  local isMultiQuality = false
  for i = 1, #list do
    if list:getValue(i, "id") == id and list:getValue(i, "isFood") == true then
      isMultiQuality = true
    end
  end
  self.parent:onSelectId(id, isMultiQuality, isOnClickTab)
end

function this:onSelectEgg(guid, list, isOnClickTab)
  if not list then
    return
  end
  self._selectedGuid = guid
  for i, module in ipairs(list) do
    module:setSelect(guid == module.guid)
  end
  self.parent:onSelectId(guid, isOnClickTab)
end

function this:onSelectDecoTarget(id)
  self._selectedId = id
  for i = 1, #self.bind.list_decoration do
    self.bind.list_decoration:change(i, {
      selectIconActive = self.bind.list_decoration:getValue(i, "id") == id
    })
  end
  self.parent:onSelectId(id)
end

function this:getSortPetEggList()
  local petEggsDic = L_PetStore:getPetEggList()
  local petEggsList = {}
  for _, v in pairs(petEggsDic) do
    if self:checkPetEggShow(v.guid) then
      table.insert(petEggsList, v)
    end
  end
  table.sort(petEggsList, function(a, b)
    local productGuidA = L_ProductManager:getProductGuidBySpecialGuid(self._guid, a.guid)
    local stateA = L_ProductManager:getProductState(self._guid, productGuidA)
    local productGuidB = L_ProductManager:getProductGuidBySpecialGuid(self._guid, b.guid)
    local stateB = L_ProductManager:getProductState(self._guid, productGuidB)
    local eggHatchTimeA = L_PetStore:getEggIncubationTime(a.configId)
    local eggHatchTimeB = L_PetStore:getEggIncubationTime(b.configId)
    local weightA = stateA * 10000000 - eggHatchTimeA * 100 - L_PetStore:getEggElementId(a.configId)
    local weightB = stateB * 10000000 - eggHatchTimeB * 100 - L_PetStore:getEggElementId(b.configId)
    if weightA == weightB then
      return a.guid < b.guid
    end
    return weightA > weightB
  end)
  return petEggsList
end

function this:checkPetEggShow(eggUid)
  local eggInfo = L_PetStore:getPetEggItem(eggUid)
  if eggInfo and eggInfo.hatch_state == 0 then
    return true
  end
  return false
end

function this:refreshTraceTaskNode()
  if not self._guid then
    return
  end
  self:refreshtraceTaskId2TraceFormulaIdListDic()
  self:refreshTabListTaskTraceNode()
  self:refreshProductTaskTraceNode()
end

function this:refreshtraceTaskId2TraceFormulaIdListDic()
  self.traceTaskIdAndTraceFormulaIdListInfo = {traceTaskId = nil, traceFormulaIdList = nil}
  local traceTaskId2TaskTraceInfosDic = C_TaskManager.GetAllTaskTraceInfos()
  local Keys = traceTaskId2TaskTraceInfosDic.Keys
  for traceTaskId, taskTraceInfos in pairs(traceTaskId2TaskTraceInfosDic) do
    for j = 0, taskTraceInfos.Count - 1 do
      local traceInfo = taskTraceInfos[j]
      local taskConditionTpl = _taskConditionTpl:getTplById(traceInfo.TriggerData.targetId)
      if taskConditionTpl ~= nil and _taskConditionTpl:getFormulaId(taskConditionTpl) ~= 0 then
        local traceFormulaId = _taskConditionTpl:getFormulaId(taskConditionTpl)
        self.traceTaskIdAndTraceFormulaIdListInfo.traceTaskId = traceTaskId
        self.traceTaskIdAndTraceFormulaIdListInfo.traceFormulaIdList = self.traceTaskIdAndTraceFormulaIdListInfo.traceFormulaIdList or {}
        table.insert(self.traceTaskIdAndTraceFormulaIdListInfo.traceFormulaIdList, traceFormulaId)
      end
    end
  end
end

function this:refreshTabListTaskTraceNode()
  if self.bind.active_tab then
    self.modules.module_commonTab:refreshTabItemTraceNode(self.traceTaskIdAndTraceFormulaIdListInfo)
  end
end

function this:refreshProductTaskTraceNode()
  local traceTaskId = self.traceTaskIdAndTraceFormulaIdListInfo.traceTaskId
  local traceFormulaIdList = self.traceTaskIdAndTraceFormulaIdListInfo.traceFormulaIdList
  local list = self.focusList or self.bind.formulaList_normal
  if list == self.bind.formulaList_egg then
    return
  end
  for i = 1, #list do
    local cellProduceTarget = list:getItemCls(i)
    if traceTaskId == nil or traceFormulaIdList == nil then
      cellProduceTarget:hideTraceTaskNode()
    else
      local needShowTraceTaskNode = false
      for _, traceFormulaId in pairs(traceFormulaIdList) do
        local traceProductId = traceFormulaId
        if cellProduceTarget:checkNeedShowTraceTaskNodeByTraceProductId(traceProductId) == true then
          needShowTraceTaskNode = true
          break
        end
      end
      if needShowTraceTaskNode then
        cellProduceTarget:refreshTraceTaskNode(traceTaskId)
      else
        cellProduceTarget:hideTraceTaskNode()
      end
    end
  end
end

return this
