local this = {}
local _systemSorttypeTpl = L_GameTpl:getSystemSorttypeTpl()
local _accessoryTpl = L_GameTpl:getAccessoryTpl()
local _spiritronTpl = L_GameTpl:getSpiritronTpl()
local _petTpl = L_GameTpl:getPetTpl()
local _commonItemTpl = L_GameTpl:getCommonItemTpl()
local _foodTpl = L_GameTpl:getFoodTpl()
local _heroTpl = L_GameTpl:getHeroTpl()
local Type2Func_sort = {
  [L_Const.resType.accessory] = "getAccessorySortKey",
  [L_Const.resType.spiritron] = "getSpiritronSortKey",
  [L_Const.resType.pet] = "getPetSortKey",
  [L_Const.resType.commonItem] = "getCommonItemSortKey",
  [L_Const.resType.hero] = "getHeroSortKey"
}

function this:getSortKey(itemType, keyList, itemId, guid)
  if Type2Func_sort[itemType] then
    return self[Type2Func_sort[itemType]](self, keyList, itemId, guid)
  else
    errorf("\232\181\132\230\186\144\229\164\167\231\177\187\229\158\139" .. itemType .. "\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
  end
end

function this:getAccessorySortKey(keyList, itemId, guid)
  local serverData = guid and L_AccessoryStore:getAccessory(guid) or {}
  local tpl_item = _accessoryTpl:getTplById(itemId)
  local res = {}
  for i, keyTypeId in ipairs(keyList) do
    local tpl_sortKey = _systemSorttypeTpl:getTplById(keyTypeId)
    local sortType, sortPara = table.unpack(_systemSorttypeTpl:getSortPara(tpl_sortKey))
    local value
    if sortType == L_SortFilterConst.SortType.Level then
      value = serverData.level
    elseif sortType == L_SortFilterConst.SortType.Quality then
      value = _accessoryTpl:getRarity(tpl_item)
    elseif sortType == L_SortFilterConst.SortType.EquipSetId then
      value = _accessoryTpl:getSetId(tpl_item)
    elseif sortType == L_SortFilterConst.SortType.ConfigId then
      value = itemId
    elseif sortType == L_SortFilterConst.SortType.ServerId then
      value = guid
    elseif sortType == L_SortFilterConst.SortType.EquipBattleInfo then
      value = L_AccessoryManager:getMergeAttDic(serverData)[sortPara] or 0
      local keyName = string.concat(L_SortFilterConst.SortTypeKeyName[sortType], sortPara)
      res[keyName] = value
    elseif sortType == L_SortFilterConst.SortType.isEquipped then
      value = math.isEmpty(serverData.wearHero) and 1 or 0
    elseif sortType == L_SortFilterConst.SortType.isEquippedBySelf then
      value = serverData.wearHero == L_AccessoryManager:getCurSelectHeroUid() and 1 or 0
    end
    if value == nil then
      errorf("\230\142\146\229\186\143\231\177\187\229\158\139" .. sortType .. "\229\156\168\232\163\133\229\164\135\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
    end
    res[L_SortFilterConst.SortTypeKeyName[sortType]] = value or 0
  end
  return res
end

function this:getSpiritronSortKey(keyList, itemId, guid)
  local serverData = guid and L_SpiritronStore:getSpiritronItem(guid) or {}
  local tpl_item = _spiritronTpl:getTplById(itemId)
  local res = {}
  for i, keyTypeId in ipairs(keyList) do
    local tpl_sortKey = _systemSorttypeTpl:getTplById(keyTypeId)
    local sortType, sortPara = table.unpack(_systemSorttypeTpl:getSortPara(tpl_sortKey))
    local value
    if sortType == L_SortFilterConst.SortType.Level then
      value = serverData.spiritronLv
    elseif sortType == L_SortFilterConst.SortType.Quality then
      value = _spiritronTpl:getRarity(tpl_item)
    elseif sortType == L_SortFilterConst.SortType.ConfigId then
      value = itemId
    elseif sortType == L_SortFilterConst.SortType.ServerId then
      value = guid
    elseif sortType == L_SortFilterConst.SortType.Star then
      value = serverData.star
    end
    if value == nil then
      errorf("\230\142\146\229\186\143\231\177\187\229\158\139" .. sortType .. "\229\156\168\231\129\181\229\173\144\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
    end
    res[L_SortFilterConst.SortTypeKeyName[sortType]] = value or 0
  end
  return res
end

function this:getHeroSortKey(keyList, itemId, guid)
  local serverData = guid and L_HeroStore:getHero(guid) or {}
  local tpl_item = _heroTpl:getTplById(itemId)
  local res = {}
  for i, keyTypeId in ipairs(keyList) do
    local tpl_sortKey = _systemSorttypeTpl:getTplById(keyTypeId)
    local sortType, sortPara = table.unpack(_systemSorttypeTpl:getSortPara(tpl_sortKey))
    local value
    if sortType == L_SortFilterConst.SortType.Level then
      value = L_HeroStore:getHeroLevel(serverData)
    elseif sortType == L_SortFilterConst.SortType.Rank then
      value = L_HeroStore:getHeroRank(serverData)
    elseif sortType == L_SortFilterConst.SortType.Quality then
      value = _heroTpl:getRarity(tpl_item)
    elseif sortType == L_SortFilterConst.SortType.ConfigId then
      value = itemId
    elseif sortType == L_SortFilterConst.SortType.ServerId then
      value = guid
    elseif sortType == L_SortFilterConst.SortType.DisplayPos then
      local page = L_UI:getPage("pageDisplayHero")
      value = table.keyOf(page.cls:getSelectHero(), guid) or math.maxinteger
    elseif sortType == L_SortFilterConst.SortType.CurEditPosIndex then
      local curEditPosIndex = L_FormationManager:getFocusIndex()
      local heroPosInFormation = L_FormationStore:getHeroPlaceInTeam(L_FormationManager:getRuntimeFormationType(), L_FormationManager:getRuntimeFormationIndex(), guid)
      value = curEditPosIndex == heroPosInFormation and 1 or 0
    end
    if value == nil then
      errorf("\230\142\146\229\186\143\231\177\187\229\158\139" .. sortType .. "\229\156\168\232\139\177\233\155\132\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
    end
    res[L_SortFilterConst.SortTypeKeyName[sortType]] = value or 0
  end
  return res
end

function this:getPetSortKey(keyList, itemId, guid)
  local serverData = guid and L_PetStore:getPetItem(guid) or {}
  local tpl_item = _petTpl:getTplById(itemId)
  local res = {}
  for i, keyTypeId in ipairs(keyList) do
    local tpl_sortKey = _systemSorttypeTpl:getTplById(keyTypeId)
    local sortType, sortPara = table.unpack(_systemSorttypeTpl:getSortPara(tpl_sortKey))
    local value
    if sortType == L_SortFilterConst.SortType.Level then
      value = serverData.lv
    elseif sortType == L_SortFilterConst.SortType.ConfigId then
      value = itemId
    elseif sortType == L_SortFilterConst.SortType.ServerId then
      value = guid
    elseif sortType == L_SortFilterConst.SortType.Satiety then
      value = serverData.satiety
    elseif sortType == L_SortFilterConst.SortType.MountSpeed then
      value = L_MountManager:getMountSpeed(guid)
    elseif sortType == L_SortFilterConst.SortType.MountMaxSpeed then
      value = L_MountManager:getMountSpeed(guid, 1)
    elseif sortType == L_SortFilterConst.SortType.MountRouletteSlotId then
      value = serverData.roulette_pos
    elseif sortType == L_SortFilterConst.SortType.IsInMountRoulette then
      value = math.isEmpty(serverData.roulette_pos) and 0 or 1
    elseif sortType == L_SortFilterConst.SortType.IsUnlock then
      local isRideUnlock = L_MountManager:getIsMountUnlock(guid)
      value = isRideUnlock and 1 or 0
    elseif sortType == L_SortFilterConst.SortType.QiBoGrade then
      value = L_PetStore:getPetGradeNew(guid)
    elseif sortType == L_SortFilterConst.SortType.CurEditPosIndex then
      local curEditPosIndex = L_FormationManager:getFocusIndex()
      local petPosInFormation = L_FormationStore:getPetPlaceInTeam(L_FormationManager:getRuntimeFormationType(), L_FormationManager:getRuntimeFormationIndex(), guid)
      value = curEditPosIndex == petPosInFormation and 1 or 0
    elseif sortType == L_SortFilterConst.SortType.MountGamePlayStatus then
      local status = serverData:getGameplayStatus()
      if status == L_Const.PetState.PET_WORKING or status == L_Const.PetState.PET_RESTING then
        value = 1
      elseif status == L_Const.PetState.PET_HERO then
        value = 2
      elseif status == L_Const.PetState.PET_NORMAL then
        value = 3
      else
        value = 0
      end
    end
    if value == nil then
      errorf("\230\142\146\229\186\143\231\177\187\229\158\139" .. sortType .. "\229\156\168\229\174\160\231\137\169\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
    end
    res[L_SortFilterConst.SortTypeKeyName[sortType]] = value or 0
  end
  return res
end

function this:getCommonItemSortKey(keyList, itemId, guid)
  local tpl_item = _commonItemTpl:getTplById(itemId)
  local res = {}
  for i, keyTypeId in ipairs(keyList) do
    local tpl_sortKey = _systemSorttypeTpl:getTplById(keyTypeId)
    local sortType, sortPara = table.unpack(_systemSorttypeTpl:getSortPara(tpl_sortKey))
    local value
    if sortType == L_SortFilterConst.SortType.Satiety then
      local tpl_food = _foodTpl:getTplById(itemId)
      if tpl_food then
        value = _foodTpl:getSatietyScore(tpl_food)
      end
    elseif sortType == L_SortFilterConst.SortType.ConfigId then
      value = itemId
    elseif sortType == L_SortFilterConst.SortType.ServerId then
      value = guid or itemId
    end
    if value == nil then
      errorf("\230\142\146\229\186\143\231\177\187\229\158\139" .. sortType .. "\229\156\168commonItem\228\187\163\231\160\129\230\156\170\232\161\165\229\133\133\239\188\140\228\188\152\229\133\136\230\137\190\231\173\150\229\136\146\231\161\174\232\174\164\230\152\175\229\144\166\233\133\141\231\189\174\230\173\163\231\161\174\229\185\182\230\137\190\231\168\139\229\186\143\230\142\165\229\133\165\228\186\134")
    end
    res[L_SortFilterConst.SortTypeKeyName[sortType]] = value or 0
  end
  return res
end

return this
