local page = class("pageShop", G_UIPageBase)
local _goodsTpl = L_GameTpl:getGoodsTpl()
local _shopTpl = L_GameTpl:getShopTpl()

function page:ctor(...)
  page.super.ctor(self, ...)
  self.data = {
    canRefreshBuyTimes = false,
    npcVirtualCamera = nil,
    resetCam = nil,
    goodsList = {},
    curShopId = nil,
    shopRefreshTimer = nil,
    selectType = nil,
    shopGroupId = nil,
    shopList = nil,
    shopTabData = {},
    selectType = nil,
    checkTypeFunc = nil,
    chooseSlotId = nil
  }
end

function page.bind()
  return {
    txt_refreshTime = "",
    purchase = false,
    moduleMenuActive = true,
    refreshTimeActive = true,
    scrollList_goods = {
      moduleName = "modulePages/cellGoodsItem"
    },
    module_currency = {
      moduleName = "modulePages/moduleCurrency"
    },
    module_tabList = L_Const.ModuleInfo.CommonTabList,
    moduleBuyGoodsInfo = {
      moduleName = "modulePages/moduleBuyGoodsInfo"
    },
    shopGroupName = "",
    shopGroupIcon = "",
    show_endTime = false
  }
end

function page.methods()
  return {
    scrollList_goods = {
      onClick = function(self, slotId, cost)
        if self.data.chooseSlotId == slotId then
          self.bind.purchase = false
          self.data.chooseSlotId = nil
        else
          self.bind.purchase = true
          self.data.chooseSlotId = slotId
        end
        for i = 1, #self.bind.scrollList_goods do
          if self.bind.scrollList_goods:getValue(i, "slotId") == slotId then
            self.bind.scrollList_goods:change(i, {
              choice = self.bind.purchase
            })
            self.modules.moduleBuyGoodsInfo:playShowAnim()
          else
            self.bind.scrollList_goods:change(i, {choice = false})
          end
        end
        if self.bind.purchase then
          self:setPurchase(slotId)
        end
      end
    },
    onClick_Close = function(self)
      L_UI:close(self.pageName)
    end
  }
end

function page:preOpen(options)
  page.super.preOpen(self, options)
  self.data.shopGroupId = options.shopId
  self.shopEntity = nil
  self.data.entityId = options.entity.data.entityId
  if options.entity ~= nil then
    self.shopEntity = options.entity
    self.shopEntity.data.characterControlProperty:SetLookAtControllerEnable(false)
  end
  L_ShopStore:listenCallFunc(L_ShopStore.event.refreshStock, self.onEvent_refreshStock, self)
  L_GameStore:listenCallFunc(L_GameStore.event.refreshDayChange, self.onEvent_refreshDayChange, self)
  self:initShopTab()
  local shopGroupTpl = L_GameTpl:getShopGroupTpl()
  if self.data.curShopId == nil then
    self.data.curShopId = shopGroupTpl:getShopList(shopGroupTpl:getTplById(options.shopId))[1]
  end
  self.bind.shopGroupName = shopGroupTpl:getShopGroupName(shopGroupTpl:getTplById(self.data.shopGroupId))
  self.bind.shopGroupIcon = shopGroupTpl:getNpcShopIcon(shopGroupTpl:getTplById(self.data.shopGroupId))
  self.data.canRefreshBuyTimes = false
  local shopTpl = L_GameTpl:getShopTpl()
  local data = {
    name = shopTpl:getShopName(shopTpl:getTplById(self.data.curShopId)),
    helpBtnBool = true,
    closeCurPage = function()
      L_UI:close(self.pageName)
    end,
    helpBtn = function()
    end,
    mainBtn = function()
      L_UI:backToRoot()
    end
  }
  self:loadVirtualCamera(options.entity)
  self.firstInit = false
  self:refreshShop()
end

function page:show()
  if self.firstInit == true then
    self:initShopList()
  end
  if self.firstInit == false then
    self.firstInit = true
  end
end

function page:refreshShop()
  local endTime = L_ShopManager:getShopTplEndTime(self.data.curShopId)
  if endTime and endTime < L_TimeUtil.getServerTime() then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_pageshop_shoprefreshed"))
    L_UI:close(self.pageName)
    return
  end
  L_ShopStore:req_listShopItems(self.data.curShopId, function()
    self:initPage()
  end)
end

function page:initShopTab()
  if not self.data.shopGroupId then
    return
  end
  local shopGroupTpl = L_GameTpl:getShopGroupTpl()
  local shopTpl = L_GameTpl:getShopTpl()
  self.data.shopList = shopGroupTpl:getShopList(shopGroupTpl:getTplById(self.data.shopGroupId))
  self.bind.moduleMenuActive = self.data.shopList and #self.data.shopList > 1
  if #self.data.shopList > 0 then
    self.data.shopTabData = {}
    for _, shopId in ipairs(self.data.shopList) do
      local endTime = L_ShopManager:getShopTplEndTime(shopId)
      if math.isEmpty(endTime) or endTime > L_TimeUtil.getServerTime() then
        local tpl = shopTpl:getTplById(shopId)
        local icon = shopTpl:getIcon(tpl)
        local name = shopTpl:getShopName(tpl)
        table.insert(self.data.shopTabData, {
          type = shopId,
          name = name,
          icon = icon,
          order = shopTpl:getOrder(tpl),
          tab = shopTpl:getTabId(tpl)
        })
      end
    end
  end
  table.sort(self.data.shopTabData, function(a, b)
    return a.order == b.order and a.type < b.type or a.order < b.order
  end)
  if self.data.shopTabData[1] ~= nil then
    self.data.curShopId = self.data.shopTabData[1].type
  end
  self:initModule(self.data.shopTabData, self.data.curShopId, function(shopId)
    if self.data.curShopId == shopId then
      return
    end
    self.data.curShopId = shopId
    self:refreshShop()
    local name = shopTpl:getShopName(shopTpl:getTplById(self.data.curShopId))
  end)
end

function page:close(options)
  page.super.close(self, options)
  L_ShopStore:unListenCallFunc(L_ShopStore.event.refreshStock, self.onEvent_refreshStock)
  L_GameStore:unListenCallFunc(L_GameStore.event.refreshDayChange, self.onEvent_refreshDayChange)
  self:closeRefreshShop()
  self:unloadVirtualCamera()
  if self.shopEntity ~= nil then
    self:resumeShopNpcLookAtIk()
  end
end

function page:resumeShopNpcLookAtIk()
  if self.shopEntity ~= nil then
    self.shopEntity.data.characterControlProperty:SetLookAtControllerEnable(true)
  end
end

function page:initPage()
  self.bind.purchase = false
  self.data.selectType = 0
  self:initCurrencyList()
  self:initShopList()
end

function page:initShopList()
  local sortList = L_ShopStore:getGoodsList(self.data.curShopId)
  self.data.goodsList = {}
  for _, v in pairs(sortList) do
    local goodsId = v.goodsId
    local tpl = _goodsTpl:getTplById(goodsId)
    local condition = true
    condition = L_ConditionManager:isComplete(_goodsTpl:getCommonCondition(tpl))
    local itemType = _goodsTpl:getItem(tpl)[1][1]
    local itemId = _goodsTpl:getItem(tpl)[1][2]
    local item = L_ItemManager:parseItem(itemType, itemId)
    local order = _goodsTpl:getOrder(tpl)
    local stockNum = L_ShopStore:getStock(self.data.curShopId, v.slotId)
    local stockText = L_Lang:get(_goodsTpl:getLimitTxt(tpl), {
      [0] = stockNum
    })
    table.insert(self.data.goodsList, {
      itemType = L_Const.resType.goods,
      itemId = goodsId,
      parseData = item,
      slotId = v.slotId,
      choice = not math.isEmpty(self.data.chooseSlotId) and self.data.chooseSlotId == v.slotId,
      curShopId = self.data.curShopId,
      txt_name = _goodsTpl:getGoodsName(tpl),
      go_new = false,
      stockText = stockText,
      stock_box = L_ShopStore:getIsLimitGoods(self.data.curShopId, v.slotId),
      soldOutMask = stockNum <= 0 and L_ShopStore:getIsLimitGoods(self.data.curShopId, v.slotId),
      goodsData = v,
      lockActive = not condition,
      stockNum = stockNum,
      deadTime = v.deadTime,
      order = order
    })
  end
  self:sortList()
  self.bind.scrollList_goods:clear()
  self.bind.scrollList_goods:insert_array(self.data.goodsList)
  C_AudioManager.Play("Play_SFX_System_UI_NPCShop_Item_Appear")
  self.data.canRefreshBuyTimes = true
  self:closeRefreshShop()
  self:openRefreshShop()
end

function page:sortList()
  for _, good in ipairs(self.data.goodsList) do
    good.weight = good.order
    if good.lockActive then
      good.weight = 10000000 + good.weight
    end
    if good.stockNum == 0 then
      good.weight = 100000000 + good.weight
    end
  end
  local compareFunc = function(a, b)
    if a.weight == b.weight then
      return a.itemId < b.itemId
    end
    return a.weight < b.weight
  end
  table.sort(self.data.goodsList, compareFunc)
end

function page:initCurrencyList()
  local tpl_sys = L_GameTpl:getSystemUnlockTpl():getTplByTab(L_SystemConst.enum.shop, self.data.curShopId)
  self.modules.module_currency:refreshRes(tpl_sys)
end

function page:onEvent_refreshStock(entity)
  if not entity then
    return
  end
  local needSort = false
  for _, v in pairs(self.data.goodsList) do
    if v.slotId == entity.slotId then
      local stock_num = L_ShopStore:getStock(self.data.curShopId, entity.slotId)
      if stock_num <= 0 then
        v.go_soldOut = true
        v.deadTime = entity.deadTime
        needSort = true
      else
        v.go_soldOut = false
      end
      local tpl = _goodsTpl:getTplById(v.itemId)
      local stockNum = L_ShopStore:getStock(self.data.curShopId, v.slotId)
      local stockText = L_Lang:get(_goodsTpl:getLimitTxt(tpl), {
        [0] = stockNum
      })
      v.stockNum = stockNum
      v.stockText = stockText
      local condition = true
      condition = L_ConditionManager:isComplete(_goodsTpl:getCommonCondition(tpl))
      if v.lockActive and condition then
        needSort = true
      end
      v.lockActive = not condition
      v.soldOutMask = stock_num <= 0 and L_ShopStore:getIsLimitGoods(self.data.curShopId, v.slotId)
    end
  end
  if needSort then
    self.bind.purchase = false
    self.data.chooseSlotId = nil
    self:sortList()
    self.bind.scrollList_goods:clear()
    self.bind.scrollList_goods:insert_array(self.data.goodsList)
  end
end

function page:onEvent_refreshDayChange()
  Timer.once(1.5, function()
    self.data.canRefreshBuyTimes = false
    L_ShopStore:req_listShopItems(self.data.curShopId, function(errorCode)
      self:initShopList()
      if errorCode == L_Const.errorCode.ErrCodeSucc then
        L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_pageshop_shoprefreshed"))
        self.bind.purchase = false
        self.data.chooseSlotId = nil
      end
    end)
  end, self, self.gameObject)
end

function page:openRefreshShop()
  if self.data.shopRefreshTimer then
    self:closeRefreshShop()
  end
  local endTime = L_ShopManager:getShopTplEndTime(self.data.curShopId)
  self.bind.refreshTimeActive = not math.isEmpty(endTime)
  self.bind.show_endTime = true
  if string.isEmpty(endTime) then
    self.bind.show_endTime = false
    return
  end
  if endTime and endTime < L_TimeUtil.getServerTime() then
    L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_pageshop_shoprefreshed"))
    L_UI:close(self.pageName)
    return
  end
  local frequency = 1
  local shopId = self.data.curShopId
  local _run = function()
    local tempEndTime = L_ShopManager:getShopTplEndTime(shopId)
    self.bind.txt_refreshTime = L_WordsTpl:getValue("ui_pageshop_shoprefresh_time") .. L_TimeUtil.getLeftTimeString(tempEndTime)
    if tempEndTime and tempEndTime < L_TimeUtil.getServerTime() and self.data.canRefreshBuyTimes then
      self.data.canRefreshBuyTimes = false
      L_FlyMsgManager:showNormalMsg(L_WordsTpl:getValue("ui_pageshop_shoprefreshed"))
      L_UI:close(self.pageName)
    end
  end
  self.bind.txt_refreshTime = L_WordsTpl:getValue("ui_pageshop_shoprefresh_time") .. L_TimeUtil.getLeftTimeString(endTime)
  if endTime and endTime >= L_TimeUtil.getServerTime() then
    self.data.shopRefreshTimer = Timer.repeated(frequency, _run)
  end
end

function page:closeRefreshShop()
  if self.data.shopRefreshTimer == nil then
    return
  end
  self.data.shopRefreshTimer:destroy()
  self.data.shopRefreshTimer = nil
end

function page:setPurchase(slotId)
  local options = {
    slotId = slotId,
    shopId = self.data.curShopId
  }
  self.modules.moduleBuyGoodsInfo:refresh(options)
end

function page:loadVirtualCamera(entity)
  L_ShopStore:setCurOpenShopGroupId(self.data.shopGroupId)
  local cameraController = L_CameraManager:switchToNpcShop()
  L_CameraManager:bindEntity(entity)
  L_PlayerManager:showOrHideAllPlayer(false)
  AzurWorld.HUDMgr:SetAllVisible(false, "PageShop")
  L_EntityManager:showOrHideRoot(L_Const.WorldNode.PLAYERPETNODE, false)
  self:SendPageShopShowEvent(true)
end

function page:unloadVirtualCamera()
  L_ShopStore:setCurOpenShopGroupId(-1)
  L_PlayerManager:showOrHideAllPlayer(true)
  local blend = L_CameraManager:getBlendStyle(L_Const.blendStyleMode.custom)
  blend.time = 1000
  L_CameraManager:revertCamController(blend)
  AzurWorld.HUDMgr:SetAllVisible(true, "PageShop")
  L_EntityManager:showOrHideRoot(L_Const.WorldNode.PLAYERPETNODE, true)
  self:SendPageShopShowEvent(false)
end

function page:SendPageShopShowEvent(bShow)
  local entity = C_EntityManager.GetEntity(self.data.entityId)
  if not entity then
    return
  end
end

function page:initModule(typeList, defaultSelectType, func)
  self.data.checkTypeFunc = func
  self.data.selectType = defaultSelectType
  self:initTypeList(typeList)
end

function page:initTypeList(typeList)
  if #typeList <= 1 then
    return
  end
  local tabList = {}
  local selectId = 1
  for i, v in ipairs(typeList) do
    if self.data.selectType == v.type then
      selectId = i
    end
    if v.tab == 0 then
      errorf("\229\149\134\229\186\151\230\178\161\233\133\141tab! " .. v.type)
    end
    table.insert(tabList, v.tab)
  end
  self.modules.module_tabList:setData(tabList, function(tab)
    local type = _shopTpl:getShopIdByTab(tab)
    self.data.checkTypeFunc(type)
    self.data.selectType = type
  end, selectId)
end

return page
