-- Core.lua

local addonName, addon = ...

addon.HexOhmUpgradeTracker = LibStub("AceAddon-3.0"):NewAddon(addon, "HexOhmUpgradeTracker", "AceEvent-3.0", "AceConsole-3.0")
HexOhmUpgradeTracker = addon.HexOhmUpgradeTracker
local UI = addon.UI

HexOhmUpgradeTracker.dirty = true
HexOhmUpgradeTracker.equippedItems = {}
HexOhmUpgradeTracker.upgradeCostsBySlot = {}
HexOhmUpgradeTracker.totalCurrencyCosts = addon.DB.totalCurrencyCosts
HexOhmUpgradeTracker.totalSlotCost = addon.DB.totalSlotCost

local defaults = {
    profile = {
        minimap = {}
    },
    char = {
        equippedItems = {},
        totalCurrencyCosts = nil,
        totalSlotCost = nil
    }
}

local function GetAddonVersion()
    local version = C_AddOns.GetAddOnMetadata("HexOhmUpgradeTracker", "Version")
    return version
end

function HexOhmUpgradeTracker:OnInitialize()
    self.db = LibStub("AceDB-3.0"):New("HexUpgradeTrackerDB", defaults, true)
    self.version = GetAddonVersion()
    
    -- Check version and reset data if mismatched
    if self.db.char.version ~= self.version then
        -- Clear all character-specific data
        self.db:ResetDB("char") -- This will reset the character-specific saved variables
        self.db.char.version = self.version
    end
    self.equippedItems = self.db.char.equippedItems or {}
    self:SetupMiniMapButton()
    self.lastUpdateTime = 0
    self.debounceDelay = 0.3
    self.upgradeCostsBySlot = addon.DB:BuildUpgradeTable()
    self.mainFrame = UI:GetMainFrame()
    self.version = GetAddonVersion()
end

function HexOhmUpgradeTracker:SetupMiniMapButton()
    local ldb = LibStub("LibDataBroker-1.1"):NewDataObject("HexOhmUpgradeTrackerMinimapButton", {
        type = "launcher",  -- "launcher" type is for a clickable icon
        text = "HexOhm Upgrade Tracker",
        -- icon = "Interface\\AddOns\\HexOhmUpgradeTracker\\textures\\INV_Misc_QuestionMark",
        icon = "Interface\\AddOns\\HexOhmUpgradeTracker\\textures\\Hexohm_Logo round.png",  -- Replace with your icon path
        OnClick = function(self, button)
            if button == "LeftButton" then
                if HexOhmUpgradeTracker.mainFrame:IsShown() then
                    HexOhmUpgradeTracker.mainFrame:Hide()
                else
                    HexOhmUpgradeTracker.mainFrame:UpdateAndShow()
                end
            elseif button == "RightButton" then
                -- Add other functionalities for right-click here later if needed
            end
        end,
        OnTooltipShow = function(tt)
            tt:AddLine("HexOhm Upgrade Tracker")
            tt:AddLine(" ")
            tt:AddLine("Left-click to toggle open.")
        end
    })
    
    local icon = LibStub("LibDBIcon-1.0")

    -- Register the minimap button
    icon:Register("HexOhmUpgradeTrackerMinimapButton", ldb, self.db.profile.minimap)
end

function HexOhmUpgradeTracker:OnEnable()
    self:RegisterEvents()
end

function HexOhmUpgradeTracker:RegisterEvents()
    self:RegisterEvent("PLAYER_ENTERING_WORLD", "OnPlayerEnteringWorld")
    self:RegisterEvent("PLAYER_INTERACTION_MANAGER_FRAME_SHOW", "OnUpgradeFrameShow")
    self:RegisterEvent("PLAYER_INTERACTION_MANAGER_FRAME_HIDE", "OnUpgradeFrameHide")
    self:RegisterEvent("CURRENCY_DISPLAY_UPDATE", "OnCurrencyDisplayUpdate")
    --self:RegisterEvent("ADDON_LOADED", "OnAddonLoaded")
end

function HexOhmUpgradeTracker:OnCurrencyDisplayUpdate(currencyType, quantity, quantityChange, gainSource)
    -- Check for a specific currency change, replace CURRENCY_ID_YOU_CARE_ABOUT with the actual ID
    if currencyType == addon.DB.VALORSTONE_ID then
        self.mainFrame:CheckValorForCapped(quantity)
    end
end

-- Example method to update the currency display
function HexOhmUpgradeTracker:UpdateCurrencyDisplay()
    -- Your code to update the display or perform any actions when currency changes
    print("Updating currency display...")
end

function HexOhmUpgradeTracker:OnPlayerEnteringWorld()
    -- Create a timer with a 5-second delay before registering the event

    C_Timer.After(1, function()
        self:RegisterEvent("BAG_UPDATE_DELAYED", "OnGearUpdateEvent")
        self:InitalizeData()
    end)
end

function HexOhmUpgradeTracker:InitalizeData()

    self:InitalizeEquippedItemSlot()
    self:InitalizeCostData()
    self:SaveData()
    self.mainFrame:UpdateProgressbars()
end

function HexOhmUpgradeTracker:InitalizeEquippedItemSlot()
    local newEquippedItems = {}

    if next(self.db.char.equippedItems) == nil then
        -- Initialize new items if the table is empty
        for slot in pairs(self.upgradeCostsBySlot) do
            local equippedItemSlot = CreateFromMixins(addon.EquippedItemsMixin)
            -- Pass the correct slot number to get the corresponding UI element
            local slotInfoFrame = self.mainFrame:GetUISlotBySlotNumber(slot)
            equippedItemSlot:init(slot, slotInfoFrame)
            table.insert(newEquippedItems, equippedItemSlot)
            if slotInfoFrame then
                slotInfoFrame.equippedItemSlot = equippedItemSlot
                slotInfoFrame:UpdateInfo()
            end
        end
    else
        -- Load existing items from saved data
        for _, itemData in ipairs(self.db.char.equippedItems) do
            local equippedItemSlot = CreateFromMixins(addon.EquippedItemsMixin)
            local slot = itemData.slot
            -- Pass the correct slot number to get the corresponding UI element
            local slotInfoFrame = self.mainFrame:GetUISlotBySlotNumber(slot)
            equippedItemSlot:init(slot, slotInfoFrame)
            equippedItemSlot:LoadData(itemData)  -- Apply saved data
            table.insert(newEquippedItems, equippedItemSlot)
            if slotInfoFrame then
                slotInfoFrame.equippedItemSlot = equippedItemSlot
                slotInfoFrame:UpdateInfo()
            end
        end
    end

    self.equippedItems = newEquippedItems
end

function HexOhmUpgradeTracker:InitalizeCostData()
    if not self.db.char.totalCurrencyCosts then
        for currencyID in pairs(self.totalCurrencyCosts) do
            self.totalCurrencyCosts[currencyID].cost = 0
        end

        for currencyID in pairs(self.totalSlotCost) do
            self.totalSlotCost[currencyID].cost = 0
        end

        for _, EquippedItem in ipairs(self.equippedItems) do
            EquippedItem:CalculateMaxSlotCost()
        end
    else
        for currencyID, data in pairs(self.db.char.totalCurrencyCosts) do
            addon.DB.totalCurrencyCosts[currencyID] = data
        end
    end

    if self.db.char.currentEquippedCostButtons then
        for currencyID, data in pairs(self.db.char.currentEquippedCostButtons) do
            addon.DB.currentEquippedCostButtons[currencyID] = data
        end
    end

    self:UpdateTotalSlotCost()
    self:UpdateEquippedSlotCost()
    self.mainFrame:UpdateCurrencyDisplayButtons()
end

function HexOhmUpgradeTracker:SaveData()
    local savedItems = {}
    for i, item in ipairs(self.equippedItems) do
        savedItems[i] = item:SaveData()
    end
    self.db.char.equippedItems = savedItems

    -- Ensure that totalCurrencyCosts and totalSlotCost are saved as tables with a `cost` field
    self.db.char.totalCurrencyCosts = {}
    for currencyID, v in pairs(self.totalCurrencyCosts) do
        self.db.char.totalCurrencyCosts[currencyID] = {cost = v.cost}
    end

    self.db.char.totalSlotCost = {}
    for currencyID, v in pairs(self.totalSlotCost) do
        self.db.char.totalSlotCost[currencyID] = {cost = v.cost}
    end
end

function HexOhmUpgradeTracker:UpdateTotalSlotCost()
    for currencyID in pairs(self.totalSlotCost) do
        self.totalSlotCost[currencyID].cost = 0
    end

    for _, EquippedItem in ipairs(self.equippedItems) do
        for currencyID in pairs(self.totalSlotCost) do
            self.totalSlotCost[currencyID].cost = (self.totalSlotCost[currencyID].cost or 0) + EquippedItem.maxSlotCosts[currencyID]
        end
    end
end

function HexOhmUpgradeTracker:UpdateEquippedSlotCost()
    for currencyID in pairs(self.totalCurrencyCosts) do
        self.totalCurrencyCosts[currencyID].cost = 0
    end

    for _, EquippedItem in ipairs(self.equippedItems) do
        for currencyID in pairs(self.totalCurrencyCosts) do
            self.totalCurrencyCosts[currencyID].cost = (self.totalCurrencyCosts[currencyID].cost or 0) + (EquippedItem.sumEquippedItemsCost[currencyID] or 0)
        end
    end
end

function HexOhmUpgradeTracker:OnUpgradeFrameShow(event, interactionType)
    if interactionType == Enum.PlayerInteractionType.ItemUpgrade then
        self:UpdateAllAndShow()
		C_ItemUpgrade.ClearItemUpgrade()
        
    end
end

function HexOhmUpgradeTracker:OnUpgradeFrameHide(event, interactionType)
    if interactionType == Enum.PlayerInteractionType.ItemUpgrade then
        self.mainFrame:Hide()
        self:SaveData()
    end
end

function HexOhmUpgradeTracker:UpdateAllAndShow()
    for _, equippedItem in ipairs(self.equippedItems) do
        -- Get and store the item info in the equippedItems mixin
        equippedItem:UpdateUpgradeInfo()
        -- Update the maxslotcost
        equippedItem:CalculateMaxSlotCost()
        -- Update the sumEquippedItemsCost
        equippedItem:CalculateEquippedActualCost()
    end

    -- Update all db tables
    self:UpdateEquippedSlotCost()
    self:UpdateTotalSlotCost()

    -- Refresh all displays
    local mainFrame = self.mainFrame
    mainFrame:UpdateAndShow()

    self:SaveData()
end

-- Define the debounce delay and animation delay time
local ANIMATION_DELAY = 1.6  -- Animation duration time in seconds

-- Modify the OnGearUpdateEvent function to handle animation timing
function HexOhmUpgradeTracker:OnGearUpdateEvent()
    -- Check if the ItemUpgradeFrame exists and animations are in progress
    if ItemUpgradeFrame and ItemUpgradeFrame.upgradeAnimationsInProgress then
        print("Animation in progress")
        
        -- Set a timer to check again after the animation delay
        C_Timer.After(ANIMATION_DELAY, function()
            -- Recheck if animations are still in progress after the delay
            if ItemUpgradeFrame and not ItemUpgradeFrame.upgradeAnimationsInProgress then
                -- Animation finished, call DebounceGearUpdate
                local upgrade = true
                self:OnGearUpdate(upgrade)
            else
                -- If animation still in progress, call OnGearUpdateEvent again
                self:OnGearUpdateEvent()
            end
        end)
    else
        -- If no animations in progress, call DebounceGearUpdate immediately
        self:DebounceGearUpdate()
    end
end

-- DebounceGearUpdate function remains the same
function HexOhmUpgradeTracker:DebounceGearUpdate()
    local currentTime = GetTime()
    if currentTime - self.lastUpdateTime < self.debounceDelay then
        -- If the function was called too recently, do nothing
        return
    end

    -- Update the last update time
    self.lastUpdateTime = currentTime

    -- Call the actual OnGearUpdate function
    self:OnGearUpdate()
end

-- OnGearUpdate function remains the same
function HexOhmUpgradeTracker:OnGearUpdate(IsUpgrade)
    HexLog("Bag slot changed ", 4)

    for _, equippedItem in pairs(self.equippedItems) do
        equippedItem:CheckAndMarkDirtyItems()
    end

    self:UpdateTotalSlotCost()
    self.mainFrame:UpdateAll()
    
    if ItemUpgradeFrame and ItemUpgradeFrame:IsShown() then
        HexLog("Frame is opened", 2)
        if IsUpgrade then
            C_Timer.After(0.1, function()
                self:UpdateAllAndShow()
            end)
        else
            C_Timer.After(0.1, function()
                self:UpdateAllAndShow()
                C_ItemUpgrade.ClearItemUpgrade()
            end)
        end
    end

    self:SaveData()
end
