local classlib = require("core.class")
local tablex = require("core.tablex")
local animationUtil = require("ui.animationUtil")
local cardManager = require("ui.cardManager")
local consts = require("ui.consts")
local fsm = require("ui.fsm")
local lamsConsts = require("ui.lamsConsts")
local list = require("ui.list")
local menu = require("ui.menu")
local pickupConsts = require("ui.pickupConsts")
local pickupUtil = require("ui.pickupUtil")
local recipeUtil = require("ui.recipeUtil")
local resourceConsts = require("ui.resourceConsts")
local util = require("ui.util")
local AI = game.AI
local Pickup = game.Pickup
local Player = game.Player
local UI = game.UI
local RecipesMenu = classlib.Class("RecipesMenu", fsm.UIState)
local RecipesOff = RecipesMenu:StateClass("RecipesOff", fsm.UIState)
local RecipesOn = RecipesMenu:StateClass("RecipesOn", fsm.UIState)
local RecipesCraft = RecipesMenu:StateClass("RecipesCraft", fsm.UIState)
local RecipesUpgrade = RecipesMenu:StateClass("RecipesUpgrade", fsm.UIState)
local recipesMenu = RecipesMenu.New("recipesMenu", {
  RecipesOff,
  RecipesOn,
  {RecipesCraft, RecipesUpgrade}
})
function RecipesMenu:Enter()
  self:WantPadEvents(true)
  self:TurnOff()
end
function RecipesMenu:TurnOff()
  self:Goto("RecipesOff")
end
RecipesMenu.EVT_GAME_OVER = RecipesMenu.TurnOff
RecipesMenu.EVT_Restart = RecipesMenu.TurnOff
function RecipesOff:Setup()
  self.recipesOn = self:GetState("RecipesOn")
end
function RecipesOff:Enter()
end
function RecipesOff:Exit()
end
function RecipesOff:EVT_TURN_ON_RECIPES_MENU(instructionEntries, instructionArgs)
  self.recipesOn.menu:set_instructionEntries(instructionEntries)
  self.recipesOn.menu:set_instructionArgs(instructionArgs)
  self:Goto("RecipesOn")
end
function RecipesOn:Setup()
  self.menu = menu.Menu.New(self, {})
  self.showDesc = true
  local isVendor = false
  self.cardManager = cardManager.CardManager.New(self, util.GetUiObjByName("Resources_Stave_group"))
  self.cardManager:Init(isVendor, nil)
  self.menu:SetupSubmenuList(consts.inworldMenu_SubmenuList, nil, nil)
  util.Show("vendorMenuListBlur", "vendorListBackingGrow")
end
function RecipesOn:Enter()
  self.menu:Activate()
  UI.WorldUIRender("cameraJoint")
  util.Show("Resources")
  local isVendorMenu = false
  recipeUtil.AllRecipesTables_RefreshAll(nil, isVendorMenu, nil)
  recipeUtil.SubmenuList_Refresh(self, isVendorMenu)
  animationUtil.MoveWorldUIMainList("ListJoint_Pickups")
  self:SendEventToUIFsm("inWorldMenu", "EVT_SHOW_ATTRIBUTE_CARD")
  self:SendEventToUIFsm("inWorldMenu", "EVT_REFRESH_NOTIFICATIONS")
  self:SendEventToUIFsm("globalMenu", "EVT_SHOW_RECIPE_NOTICE", util.GetLAMSMsg(lamsConsts.PreviewOnly), util.GetLAMSMsg(lamsConsts.VisitTheShop))
  self:HideAllInfo()
  self.menu:ExecuteInstructions()
end
function RecipesOn:Exit()
  self.menu:Deactivate(true)
  self.showDesc = true
  util.Hide("Resources")
  self:HideAllInfo()
  self.cardManager:UpdateHoldFill(nil, false, nil)
  self:SendEventToUIFsm("inWorldMenu", "EVT_CLEAR_ATTRIBUTES_PREVIEW")
  self:SendEventToUIFsm("inWorldMenu", "EVT_HIDE_ATTRIBUTE_CARD")
  self:SendEventToUIFsm("globalMenu", "EVT_HIDE_RECIPE_NOTICE")
end
function RecipesOn:SubmenuList_Button_Update(button)
  recipeUtil.SubmenuList_Button_Update(self, button, false)
end
function RecipesOn:SubmenuList_Button_OnGainFocus(button)
  animationUtil.UpdateCamera(self, pickupConsts.TAG_PICKUP_KRATOS, "Resources")
  recipeUtil.SubmenuList_Button_OnGainFocus(self, button, consts.vendorMenu_SubmenuList, false)
end
function RecipesOn:SubmenuList_Button_OnLoseFocus(button)
  self:HideAllInfo()
  recipeUtil.SubmenuList_Button_OnLoseFocus(self, button, consts.vendorMenu_SubmenuList, false)
end
function RecipesOn:HideAllInfo()
  self.cardManager:HideAll()
  self:SendEventToUIFsm("inWorldMenu", "EVT_CLEAR_ATTRIBUTES_PREVIEW")
end
function RecipesOn:CanRecipeBeMade(recipeListItem)
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
  local canPurchase = recipeUtil.CanPurchase(recipeName)
  local atLimit = recipeUtil.RecipeListItem_AtLimit(recipeListItem)
  local canRecipeBeMade = canPurchase and not atLimit
  return canRecipeBeMade
end
function RecipesOn:CanCompare(currState)
  local subList = currState.menu:GetList("SubList")
  local currRecipeListItem = subList:GetSelectedItem()
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(currRecipeListItem)
  local pickupNameInSlot
  local canCompare = false
  if recipeUtil.IsValidRecipeName(recipeName) then
    local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(currRecipeListItem)
    local primaryRecipeItemType = recipeUtil.GetRecipeItemType(primaryRecipeItem)
    local isPrimaryItemPickup = primaryRecipeItemType == resourceConsts.RESOURCE_FLAG_PICKUP
    local isReinforcementRecipe = recipeUtil.IsReinforcementRecipe(recipeName)
    local isQuiverRecipe = recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_QUIVER)
    if (isReinforcementRecipe or isPrimaryItemPickup) and not isQuiverRecipe then
      local itemName = isReinforcementRecipe and recipeUtil.RecipeListItem_GetReinforcementPickupName(currRecipeListItem) or recipeUtil.GetRecipeItemName(primaryRecipeItem)
      local pickupSlot = pickupUtil.GetSlotName(itemName)
      if pickupUtil.IsValidSlotName(pickupSlot) then
        local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
        local creature = pickupUtil.GetCreatureFromCharacter(character)
        pickupNameInSlot = pickupUtil.GetPickupNameInSlot(creature, pickupSlot)
        canCompare = pickupUtil.IsValidName(pickupNameInSlot)
      end
    end
  end
  return canCompare, pickupNameInSlot
end
function RecipesOn:UpdateUICreatureByRecipe(currState, recipeListItem, resetToPickupInSlot)
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
  if recipeUtil.IsValidRecipeName(recipeName) and not recipeUtil.RecipeIsForSellRune(recipeName) then
    local primaryRecipeItem = recipeUtil.RecipeListItem_GetPrimaryItem(recipeListItem)
    local primaryRecipeItemType = recipeUtil.GetRecipeItemType(primaryRecipeItem)
    local isPrimaryItemPickup = primaryRecipeItemType == resourceConsts.RESOURCE_FLAG_PICKUP
    local isReinforcementRecipe = recipeUtil.IsReinforcementRecipe(recipeName)
    local isQuiverRecipe = recipeUtil.HasFlag(recipeName, resourceConsts.RESOURCE_FLAG_QUIVER)
    if (isReinforcementRecipe or isPrimaryItemPickup) and not isQuiverRecipe then
      local itemName = isReinforcementRecipe and recipeUtil.RecipeListItem_GetReinforcementPickupName(recipeListItem) or recipeUtil.GetRecipeItemName(primaryRecipeItem)
      local pickupSlot = pickupUtil.GetSlotName(itemName)
      if pickupUtil.IsValidSlotName(pickupSlot) then
        local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
        local creature = pickupUtil.GetCreatureFromCharacter(character)
        local pickupNameInSlot = pickupUtil.GetPickupNameInSlot(creature, pickupSlot)
        local stage = 0
        if pickupNameInSlot ~= nil then
          stage = Pickup.GetProfileStage(pickupNameInSlot)
          if isReinforcementRecipe then
            stage = stage + 1
          end
          assert(stage ~= -1, "Attempting to equip the player with a pickup they do not possess")
        end
        if resetToPickupInSlot then
          itemName = pickupNameInSlot
          stage = pickupUtil.GetStage(itemName, creature)
        end
        pickupUtil.UpdateSlotOnUICreature(pickupSlot, itemName, stage, creature, character)
      end
    end
  end
end
function RecipesOn:SelectRecipe(currState, recipeListItem)
  local recipeName = recipeUtil.RecipeListItem_GetRecipeName(recipeListItem)
  if not recipeUtil.IsValidRecipeName(recipeName) then
    self:HideAllInfo()
  else
    local currCharacter = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    local canRecipeBeMade = self:CanRecipeBeMade(recipeListItem)
    local shouldUpdateAttributes = recipeUtil.RecipeListItem_ShouldUpdateAttributes(recipeListItem)
    recipeUtil.RecipeListItem_RevealRecipeInputs(recipeListItem)
    if shouldUpdateAttributes then
      local resetToPickupInSlot = false
      self:UpdateUICreatureByRecipe(currState, recipeListItem, resetToPickupInSlot)
      self:SendEventToUIFsm("inWorldMenu", "EVT_UPDATE_ATTRIBUTES_PREVIEW", currCharacter)
    end
    local submenuList = self.menu:GetList(consts.vendorMenu_SubmenuList)
    local subStateIndex = submenuList:GetSelectedItem()
    local canCompare = self:CanCompare(currState)
    self.cardManager:DisplayCard_ForRecipe(recipeListItem, canRecipeBeMade, subStateIndex, currCharacter, canCompare)
  end
  self:UpdateFooterButtonPrompt(currState.menu, false, false)
end
function RecipesOn:UpdateAttributeDesc(currValue)
  self.showDesc = currValue
  if self.showDesc == true then
    self:SendEventToUIFsm("inWorldMenu", "EVT_SHOW_ATTRIBUTE_DESCRIPTIONS")
  else
    self:SendEventToUIFsm("inWorldMenu", "EVT_HIDE_ATTRIBUTE_DESCRIPTIONS")
  end
end
function RecipesOn:UpdateFooterButtonPrompt(currMenu, showSelect, showExit)
  local showTouchPadMap = game.IsMapAvailable() and game.build.GOLD_VERSION ~= 0
  currMenu:UpdateFooterButton("Select", showSelect)
  currMenu:UpdateFooterButton("Map", showTouchPadMap)
  currMenu:UpdateFooterButton("Weapon", true)
  currMenu:UpdateFooterButton("Skill", true)
  currMenu:UpdateFooterButton("Quest", true)
  currMenu:UpdateFooterButton("Settings", true)
  currMenu:UpdateFooterButton("Back", not showExit)
  currMenu:UpdateFooterButton("Exit", showExit)
  currMenu:UpdateFooterButton("Close", true)
  currMenu:UpdateFooterButtonText()
end
function RecipesOn:SubmenuSetup(currState, subStateIndex)
  currState.menu = menu.Menu.New(currState, {
    FooterButtonInfo = {
      {
        Item = "Select",
        Text = "[AdvanceButton] " .. util.GetLAMSMsg(lamsConsts.Select)
      },
      {
        Item = "Map",
        Text = "[TouchPad] " .. util.GetLAMSMsg(lamsConsts.Map),
        EventHandlers = {
          {
            Events = {
              "EVT_TouchPad_Release"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_MAP")
            end
          }
        }
      },
      {
        Item = "Weapon",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_WEAPON_MENU"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_WEAPON")
            end
          }
        }
      },
      {
        Item = "Skill",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_SKILL_TREE_MENU"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_SKILL_TREE")
            end
          }
        }
      },
      {
        Item = "Quest",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_GO_TO_QUEST_MENU"
            },
            Handler = function()
              self:SendEventToUIFsm("globalMenu", "EVT_GO_TO_QUEST")
            end
          }
        }
      },
      {
        Item = "Settings",
        Text = "[TriangleButton] " .. util.GetLAMSMsg(lamsConsts.Options),
        EventHandlers = {
          {
            Events = {
              "EVT_Triangle_Release"
            },
            Handler = function()
              self:Menu_Triangle_ReleaseHandler()
            end
          }
        }
      },
      {
        Item = "Back",
        Text = "[BackButton] " .. util.GetLAMSMsg(lamsConsts.Back)
      },
      {
        Item = "Exit",
        Text = "[BackButton] " .. util.GetLAMSMsg(lamsConsts.Exit)
      },
      {
        Item = "Close",
        Text = "",
        EventHandlers = {
          {
            Events = {
              "EVT_Options_Release"
            },
            Handler = function()
              self:Menu_Options_ReleaseHandler()
            end
          }
        }
      }
    }
  })
  currState.subStateIndex = subStateIndex
  currState.isVendorMenu = false
  local listObjectName = "PickupList"
  recipeUtil.Submenu_SetupLists(currState, listObjectName)
end
function RecipesOn:SubmenuEnter(currState, includeTypes, excludeTypes)
  currState.menu:Activate()
  recipeUtil.MainList_Refresh(currState, true)
  currState.menu:ExecuteInstructions()
end
function RecipesOn:SubmenuExit(currState)
  local subList = currState.menu:GetList("SubList")
  if subList:get_active() == true then
    local recipeListItem = subList:GetSelectedItem()
    local resetToPickupInSlot = true
    self:UpdateUICreatureByRecipe(currState, recipeListItem, resetToPickupInSlot)
  end
  currState.menu:Deactivate(true)
end
function RecipesOn:Menu_Options_ReleaseHandler()
  self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
end
function RecipesOn:Menu_Triangle_ReleaseHandler()
  self:SendEventToUIFsm("globalMenu", "EVT_OPEN_SETTINGS_MENU")
end
function RecipesOn:SubList_BackReleaseHandler(currState)
  self:HideAllInfo()
  local subList = currState.menu:GetList("SubList")
  local recipeListItem = subList:GetSelectedItem()
  local resetToPickupInSlot = true
  self:UpdateUICreatureByRecipe(currState, recipeListItem, resetToPickupInSlot)
  local mainList = currState.menu:GetList("MainList")
  local currMainSelection = mainList:GetSelectedItem()
  local categoryList = currState.menu:GetList("CategoryList")
  local currCategorySelection = categoryList:GetSelectedItem()
  local categoryItems = recipeUtil.CategoryList_GetItems(currState.subStateIndex, currMainSelection)
  if #categoryItems == 1 then
    local isVendorMenu = false
    recipeUtil.SubmenuList_Activate(self, isVendorMenu)
    currCategorySelection = categoryItems[1]
  end
  if recipeUtil.IsSonSelection(currCategorySelection) then
    self:SendEventToUIFsm("inWorldMenu", "EVT_SHOW_ATTRIBUTE_CARD")
  end
  recipeUtil.SubList_BackReleaseHandler(currState)
  self.cardManager:HideComparisonCard()
end
function RecipesOn:SubList_R2PressHandler(currState)
  local canCompare, pickupNameInSlot = self:CanCompare(currState)
  if self:CanCompare(currState) then
    local itemName = pickupNameInSlot
    local itemType = resourceConsts.RESOURCE_FLAG_PICKUP
    local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    local isEquipped = true
    local args
    self.cardManager:ShowComparisonCard(itemName, itemType, character, isEquipped, args)
  end
end
function RecipesOn:SubList_R2ReleaseHandler(currState)
  self.cardManager:HideComparisonCard()
end
function RecipesOn:SubList_R3ReleaseHandler(currState)
  local canCompare, pickupNameInSlot = self:CanCompare(currState)
  if canCompare then
    local itemName = pickupNameInSlot
    local itemType = resourceConsts.RESOURCE_FLAG_PICKUP
    local character = recipeUtil.GetCurrentCharacterByCategorySelection(currState)
    local isEquipped = true
    local args
    self.cardManager:ToggleComparisonCard(itemName, itemType, character, isEquipped, args)
  end
end
function RecipesOn:EVT_TURN_OFF_RECIPES_MENU()
  self:Goto("RecipesOff")
end
function RecipesCraft:Setup()
  self.recipesOn = self:GetState("RecipesOn")
  self.recipesOn:SubmenuSetup(self, "Craft")
  self.currCharacter = pickupConsts.TAG_PICKUP_KRATOS
end
function RecipesCraft:Enter()
  self.recipesOn:SubmenuEnter(self, {}, {})
end
function RecipesCraft:Exit()
  self.recipesOn:SubmenuExit(self)
end
function RecipesCraft:CanRecipeBeMade(recipeListItem)
  return self.recipesOn:CanRecipeBeMade(recipeListItem)
end
function RecipesCraft:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.recipesOn, self)
end
function RecipesCraft:MainList_BackReleaseHandler()
  self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
end
function RecipesCraft:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function RecipesCraft:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.recipesOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function RecipesCraft:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = false
  recipeUtil.SubmenuList_Activate(self.recipesOn, isVendorMenu)
end
function RecipesCraft:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.recipesOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function RecipesCraft:Category_OnSelect(currMainSelection, currCategorySelection)
  if recipeUtil.IsSonSelection(currCategorySelection) then
    self:SendEventToUIFsm("inWorldMenu", "EVT_HIDE_ATTRIBUTE_CARD")
  end
end
function RecipesCraft:SubList_Button_OnGainFocus(button)
  local currItem = button:get_item()
  self.recipesOn:SelectRecipe(self, currItem)
end
function RecipesCraft:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
  self:SendEventToUIFsm("inWorldMenu", "EVT_REFRESH_NOTIFICATIONS")
end
function RecipesCraft:SubList_BackReleaseHandler()
  self.recipesOn:SubList_BackReleaseHandler(self)
end
function RecipesCraft:SubList_R2PressHandler()
end
function RecipesCraft:SubList_R2ReleaseHandler()
end
function RecipesCraft:SubList_R3ReleaseHandler()
  self.recipesOn:SubList_R3ReleaseHandler(self)
end
function RecipesUpgrade:Setup()
  self.recipesOn = self:GetState("RecipesOn")
  self.recipesOn:SubmenuSetup(self, "Upgrade")
  self.currCharacter = pickupConsts.TAG_PICKUP_KRATOS
end
function RecipesUpgrade:Enter()
  self.recipesOn:SubmenuEnter(self, {}, {})
end
function RecipesUpgrade:Exit()
  self.recipesOn:SubmenuExit(self)
end
function RecipesUpgrade:CanRecipeBeMade(recipeListItem)
  return self.recipesOn:CanRecipeBeMade(recipeListItem)
end
function RecipesUpgrade:MainList_AdvanceReleaseHandler()
  recipeUtil.MainList_AdvanceReleaseHandler(self.recipesOn, self)
end
function RecipesUpgrade:MainList_BackReleaseHandler()
  self:SendEventToUIFsm("globalMenu", "EVT_TURN_OFF_GLOBAL_MENU")
end
function RecipesUpgrade:MainList_Button_Update(button)
  recipeUtil.MainList_Button_Update(self, button)
end
function RecipesUpgrade:MainList_Button_OnGainFocus(button)
  local showExit = true
  self.recipesOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function RecipesUpgrade:CategoryList_BackReleaseHandler()
  recipeUtil.CategoryList_BackReleaseHandler(self)
  local isVendorMenu = false
  recipeUtil.SubmenuList_Activate(self.recipesOn, isVendorMenu)
end
function RecipesUpgrade:CategoryList_Button_OnGainFocus(button)
  local showExit = false
  self.recipesOn:UpdateFooterButtonPrompt(self.menu, true, showExit)
end
function RecipesUpgrade:Category_OnSelect(currMainSelection, currCategorySelection)
  if recipeUtil.IsSonSelection(currCategorySelection) then
    self:SendEventToUIFsm("inWorldMenu", "EVT_HIDE_ATTRIBUTE_CARD")
  end
end
function RecipesUpgrade:SubList_Button_OnGainFocus(button)
  local currItem = button:get_item()
  self.recipesOn:SelectRecipe(self, currItem)
end
function RecipesUpgrade:SubList_Button_OnLoseFocus(button)
  recipeUtil.SubList_Button_OnLoseFocus(self, button)
  self:SendEventToUIFsm("inWorldMenu", "EVT_REFRESH_NOTIFICATIONS")
end
function RecipesUpgrade:SubList_BackReleaseHandler()
  self.recipesOn:SubList_BackReleaseHandler(self)
end
function RecipesUpgrade:SubList_R2PressHandler()
end
function RecipesUpgrade:SubList_R2ReleaseHandler()
end
function RecipesUpgrade:SubList_R3ReleaseHandler()
  self.recipesOn:SubList_R3ReleaseHandler(self)
end
function RecipesMenu:OnSaveCheckpoint(tab)
end
function RecipesMenu:OnRestoreCheckpoint(tab)
end
