local this = class("moduleSubtaskBox", require("ui.pages.task.moduleSubmitBase"))
local _commonItemTpl = L_GameTpl:getCommonItemTpl()
local _taskTargetTpl = L_GameTpl:getTaskTargetTpl()
local _taskStepTpl = L_GameTpl:getTaskStepTpl()
local _taskTpl = L_GameTpl:getTaskTpl()

function this:bind()
  return {
    activeEmpty = false,
    txtTarget = "",
    itemList = true,
    txtDesc = "",
    txtConditionObj = true,
    txtConditionDesc = "",
    submitBg = true,
    scrollList_goods = {
      moduleName = "modulePages/cellSubmitItem"
    },
    submitList = {
      moduleName = "modulePages/cellSubmitItem"
    }
  }
end

function this:methods()
  return {
    clickSubmit = function(self)
      self:submitItem()
    end
  }
end

function this:initUI()
  self.super.initUI(self)
  self:refreshBagItems()
  self:refreshSubmitItems()
  local tplTask = _taskTpl:getTplById(self.taskId)
  self.bind.txtTarget = _taskTpl:getName(tplTask)
  local stepId = L_TaskManager:GetTaskStepId(self.taskId, self.nodeId)
  local tplTaskStep = _taskStepTpl:getTplById(stepId)
  if tplTaskStep then
    self.bind.txtDesc = _taskStepTpl:getDesc(tplTaskStep)
  end
  if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
    self.bind.txtConditionObj = false
    self.bind.submitBg = true
  else
    self.bind.txtConditionObj = true
    self.bind.submitBg = false
    local infos = L_TaskManager:GetNodeInfoParam(self.taskId, self.nodeId)
    local tplTaskTarget = _taskTargetTpl:getTplById(infos[0].conditionInfoId)
    if tplTaskTarget then
      self.taskDesc = _taskTargetTpl:getDesc(tplTaskTarget)
      self:SetConditionDesc(self.taskDesc, 0, #self.modules.submitList)
    end
  end
end

function this:onBagItemClick(item)
  local clickWaitListRemoveHandle = handler(self, self.onWaitAddItemRemoveClick)
  if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
    if item.select then
      return
    end
    if self.canSubmit then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_task_submit_enough"))
      return
    end
    self.canSubmit = true
    local itemId = item.bind.itemId
    for _, v in pairs(self.modules.submitList) do
      if v.bind.itemId == itemId then
        local num = item:setSelect(true, v.bind.needCount)
        v:setCurCount(num)
        v:setSelect(true)
      end
      self.canSubmit = self.canSubmit and v.bind.curCount >= v.bind.needCount
    end
  elseif self.subType == L_Const.taskClientEvent.submitTypeItem or self.subType == L_Const.taskClientEvent.submitGroupItem then
    if self.canSubmit and not item.select then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_task_submit_enough"))
      return
    end
    local itemId = item.bind.itemId
    if item.bind.itemNum <= 0 then
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_task_submit_none"))
      return
    end
    for i, v in ipairs(self.modules.submitList) do
      if v.bind.itemId then
        if v.bind.itemId == itemId then
          local num = v:getSelectNum() + 1
          v.bind.itemNum = num
          local addNum = v:setSelect(true, num)
          v.bind.txtNum = tostring(addNum)
          v:setCurCount(addNum)
          v.bind.txtSelectNum = ""
          item.bind.itemNum = item.bind.itemNum - 1
          item.bind.txtNum = tostring(item.bind.itemNum)
          break
        end
      else
        local tpl = _commonItemTpl:getTplById(item.bind.itemId)
        local type = _commonItemTpl:getType(tpl)
        local option = {
          itemType = item.bind.itemType,
          itemId = item.bind.itemId,
          itemNum = 1,
          needCount = item.bind.needCount,
          curCount = 1,
          clickRemoveHandle = clickWaitListRemoveHandle,
          itemShowType = L_Const.submitItemShowType.select,
          itemSubType = type
        }
        v:resetData(option)
        v:refresh()
        v:setSelect(true, 1)
        v.bind.txtSelectNum = ""
        item.bind.itemNum = item.bind.itemNum - 1
        item.bind.txtNum = tostring(item.bind.itemNum)
        break
      end
    end
    local currentNum = 0
    for _, v in pairs(self.modules.submitList) do
      currentNum = currentNum + v:getSelectNum()
    end
    self:SetConditionDesc(self.taskDesc, currentNum, #self.modules.submitList)
    if currentNum >= #self.modules.submitList then
      self.canSubmit = true
    end
  end
end

function this:onWaitAddItemRemoveClick(item)
  if self.subType == L_Const.taskClientEvent.submitTypeItem or self.subType == L_Const.taskClientEvent.submitGroupItem then
    local itemId = item.bind.itemId
    for _, v in pairs(self.modules.scrollList_goods) do
      if v.bind.itemId and v.bind.itemId == itemId then
        local num = item:getSelectNum() - 1
        item.bind.itemNum = num
        item:setSelect(0 < num, num)
        item.bind.txtNum = tostring(num)
        v.bind.itemNum = v.bind.itemNum + 1
        v.bind.txtNum = tostring(v.bind.itemNum)
        if num <= 0 then
          do
            local option = {
              itemShowType = L_Const.submitItemShowType.waitAdd
            }
            item:resetData(option)
            item:refresh()
            item.bind.txtSelectNum = ""
          end
          break
        end
        item.bind.txtSelectNum = ""
        break
      end
    end
    local currentNum = 0
    for _, v in pairs(self.modules.submitList) do
      currentNum = currentNum + v:getSelectNum()
    end
    if currentNum >= #self.modules.submitList then
      self.canSubmit = true
    else
      self.canSubmit = false
    end
    self:SetConditionDesc(self.taskDesc, currentNum, #self.modules.submitList)
  end
end

function this:onBagItemRemoveClick(item)
  self.canSubmit = false
  if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
    local itemId = item.bind.itemId
    for _, v in pairs(self.modules.submitList) do
      if v.bind.itemId == itemId then
        item:setSelect(false)
        v:setCurCount(0)
        v:setSelect(false)
        break
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitTypeItem then
    local itemSubType = item.bind.itemSubType
    for _, v in pairs(self.modules.submitList) do
      if v.bind.itemSubType == itemSubType then
        local num = item:getSelectNum() - 1
        item:setSelect(0 < num, num)
        v.bind.curCount = v.bind.curCount - 1
        v:setCurCount(v.bind.curCount)
        v:setSelect(0 < v.bind.curCount)
        break
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitGroupItem then
    for _, v in pairs(self.modules.submitList) do
      if table.containsValue(v.bind.itemIds, item.bind.itemId) then
        local num = item:getSelectNum() - 1
        item:setSelect(0 < num, num)
        v.bind.curCount = v.bind.curCount - 1
        v:setCurCount(v.bind.curCount)
        v:setSelect(0 < v.bind.curCount)
        break
      end
    end
  end
end

function this:refreshBagItems()
  local items = {}
  local clickHandle = handler(self, self.onBagItemClick)
  local clickRemoveHandle = handler(self, self.onBagItemRemoveClick)
  if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
    self.bind.itemList = false
  elseif self.subType == L_Const.taskClientEvent.submitTypeItem then
    local itemTypes = {}
    for _, itemData in ipairs(self.subData.subTable) do
      itemTypes[itemData.itemType] = true
    end
    local allItems = L_BagStore:getAllItem()
    for _, bagItem in pairs(allItems) do
      local tpl = _commonItemTpl:getTplById(bagItem.itemID)
      if tpl then
        local inBag = _commonItemTpl:getInBag(tpl)
        local type = _commonItemTpl:getType(tpl)
        if inBag and itemTypes[type] then
          local cell = {
            itemType = L_Const.resType.commonItem,
            itemId = bagItem.itemID,
            itemNum = bagItem.itemNum,
            activeMask = false,
            quality = _commonItemTpl:getRarity(tpl),
            clickCallback = clickHandle,
            clickRemoveCallback = clickRemoveHandle,
            itemShowType = L_Const.submitItemShowType.select,
            itemSubType = type
          }
          table.insert(items, cell)
        end
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitGroupItem then
    for _, itemData in ipairs(self.subData.subTable) do
      for i = 1, #itemData.itemIds do
        local bagItem = L_BagStore:getItem(itemData.itemIds[i])
        if bagItem then
          local tpl = _commonItemTpl:getTplById(bagItem.itemID)
          if tpl then
            local type = _commonItemTpl:getType(tpl)
            local cell = {
              itemType = L_Const.resType.commonItem,
              itemId = bagItem.itemID,
              itemNum = bagItem.itemNum,
              activeMask = false,
              quality = _commonItemTpl:getRarity(tpl),
              clickCallback = clickHandle,
              clickRemoveCallback = clickRemoveHandle,
              itemShowType = L_Const.submitItemShowType.select,
              itemSubType = type
            }
            table.insert(items, cell)
          end
        end
      end
    end
  end
  table.sort(items, function(a, b)
    if a.activeMask ~= b.activeMask then
      return b.activeMask
    end
    if a.quality ~= b.quality then
      return a.quality < b.quality
    end
    return a.itemId < b.itemId
  end)
  self.bind.scrollList_goods:clear()
  if 0 < #items then
    local countPerLine = self.bindComponents.gridView.gridContentConstraint
    local lineNum = 2
    local minNum = countPerLine * lineNum
    local num = math.max(minNum, #items)
    num = num % countPerLine == 0 and num or num + countPerLine - num % countPerLine
    for i = #items + 1, num do
      items[i] = {
        itemShowType = L_Const.submitItemShowType.empty
      }
    end
    self.bind.scrollList_goods:insert_array(items)
  end
  self.bind.activeEmpty = #items == 0
end

function this:onSubmitItemClick(item)
  if not item.select then
    if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
      L_ItemTplManager:showInfoTip(item.bind.itemType, item.bind.itemId)
    end
    return
  end
  self.canSubmit = false
  item:setSelect(false)
  item:setCurCount(0)
  if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
    local itemId = item.bind.itemId
    for _, v in pairs(self.modules.scrollList_goods) do
      if v.select and v.bind.itemId == itemId then
        item:setSelect(false)
        v:setSelect(false)
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitTypeItem then
    local itemSubType = item.bind.itemSubType
    for _, v in pairs(self.modules.scrollList_goods) do
      if v.select and v.bind.itemSubType == itemSubType then
        item:setSelect(false)
        v:setSelect(false)
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitGroupItem then
    local itemIds = item.bind.itemIds
    for _, v in pairs(self.modules.scrollList_goods) do
      if v.select and table.containsValue(itemIds, v.bind.itemId) then
        item:setSelect(false)
        v:setSelect(false)
      end
    end
  end
end

function this:refreshSubmitItems()
  local items = {}
  local clickHandle = handler(self, self.onSubmitItemClick)
  if self.subType == L_Const.taskClientEvent.submitItem then
    self.canSubmit = true
    for _, itemData in ipairs(self.subData.subTable) do
      local tempData = L_ItemManager:parseCommonItem(itemData.itemId)
      local bagNum = 0
      local allItems = L_BagStore:getAllItem()
      for _, bagItem in pairs(allItems) do
        if bagItem.itemID == itemData.itemId then
          bagNum = bagItem.itemNum
          break
        end
      end
      local curCount = bagNum >= itemData.needCount and itemData.needCount or bagNum
      self.canSubmit = self.canSubmit and bagNum >= itemData.needCount
      local cell = {
        itemType = tempData.itemType,
        itemId = itemData.itemId,
        needCount = itemData.needCount,
        curCount = curCount,
        clickCallback = clickHandle,
        itemShowType = L_Const.submitItemShowType.submitTaget
      }
      table.insert(items, cell)
    end
  elseif self.subType == L_Const.taskClientEvent.submitTaskItem then
    local taskItemDic = L_TaskStore:getTaskPropDic()
    self.canSubmit = true
    for _, itemData in ipairs(self.subData.subTable) do
      local tempData = taskItemDic[itemData.itemId]
      local bagNum = 0
      local itemIds = {}
      for _, itemData in ipairs(self.subData.subTable) do
        itemIds[itemData.itemId] = true
      end
      local list = C_TaskManager.GetTaskItems()
      for i = 0, list.Count - 1 do
        if list[i].itemId == itemData.itemId then
          bagNum = list[i].itemNum
          break
        end
      end
      local curCount = bagNum >= itemData.needCount and itemData.needCount or bagNum
      self.canSubmit = self.canSubmit and bagNum >= itemData.needCount
      if tempData ~= nil then
        local cell = {
          itemType = L_Const.resType.taskItem,
          itemId = itemData.itemId,
          needCount = itemData.needCount,
          curCount = curCount,
          clickCallback = clickHandle,
          itemShowType = L_Const.submitItemShowType.submitTaget
        }
        table.insert(items, cell)
      end
    end
  elseif self.subType == L_Const.taskClientEvent.submitTypeItem or self.subType == L_Const.taskClientEvent.submitGroupItem then
    for _, itemData in ipairs(self.subData.subTable) do
      for i = 1, itemData.needCount do
        local cell = {
          itemShowType = L_Const.submitItemShowType.waitAdd
        }
        table.insert(items, cell)
      end
    end
  end
  self.bind.submitList:clear()
  self.bind.submitList:insert_array(items)
end

function this:submitItem()
  if self.canSubmit then
    if self.subType == L_Const.taskClientEvent.submitItem or self.subType == L_Const.taskClientEvent.submitTaskItem then
      L_TaskStore:req_creatSubmitItemData(self.subType, self.taskId, self.nodeId)
    elseif self.subType == L_Const.taskClientEvent.submitTypeItem then
      for _, itemData in ipairs(self.subData.subTable) do
        local subData = {}
        for _, v in pairs(self.modules.submitList) do
          if v.select and v.bind.itemSubType == itemData.itemType then
            local data = {}
            data.itemId = v.bind.itemId
            data.itemType = v.bind.itemType
            data.count = v.selectNum
            table.insert(subData, data)
            v.select = false
          end
        end
        L_TaskStore:req_creatSubmitItemData(self.subType, self.taskId, self.nodeId, itemData.index, subData)
      end
    elseif self.subType == L_Const.taskClientEvent.submitGroupItem then
      for _, itemData in ipairs(self.subData.subTable) do
        local subData = {}
        local itemIds = itemData.itemIds
        for _, v in pairs(self.modules.submitList) do
          if v.select and table.containsValue(itemIds, v.bind.itemId) then
            local data = {}
            data.itemId = v.bind.itemId
            data.itemType = v.bind.itemType
            data.count = v.selectNum
            table.insert(subData, data)
            v.select = false
          end
        end
        L_TaskStore:req_creatSubmitItemData(self.subType, self.taskId, self.nodeId, itemData.index, subData)
      end
    end
    L_UI:close("pageTaskSubmit")
  else
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_task_submit_not"))
  end
end

function this:SetConditionDesc(desc, curNum, maxNum)
  local colorKey = curNum < maxNum and "#ff878f" or "#a1ffd2"
  self.bind.txtConditionDesc = desc .. L_GameUtil.fillColor(string.format("  %s/%s", tostring(curNum), tostring(maxNum)), colorKey)
end

return this
