-- UI.lua

local addonName, addon = ...
addon.UI = {}
local UI = addon.UI
local DB = addon.DB



UI.slotPositions = {
    [1] = { x = 5, y = -10 },    -- Head
    [2] = { x = 5, y = -50 },    -- Neck
    [3] = { x = 5, y = -90 },    -- Shoulders
    [15] = { x = 5, y = -130 },  -- Back
    [5] = { x = 5, y = -170 },   -- Chest
    [9] = { x = 5, y = -210 },   -- Wrist
    [10] = { x = -5, y = -10 },  -- Hands
    [6] = { x = -5, y = -50 },   -- Waist
    [7] = { x = -5, y = -90 },   -- Legs
    [8] = { x = -5, y = -130 },  -- Feet
    [11] = { x = -5, y = -170 }, -- Finger 1
    [12] = { x = -5, y = -210 }, -- Finger 2
    [16] = { x = -135, y = -275 }, -- Main Hand
    [17] = { x = 135, y = -275 },  -- Off Hand
    [13] = { x = -135, y = -315 }, -- Trinket 1
    [14] = { x = 135, y = -315 },  -- Trinket 2
}

UI.BACKDROP_INFO = {
    bgFile = "Interface\\Buttons\\WHITE8X8",
    edgeFile = "Interface\\Buttons\\WHITE8X8",
    tile = true,
    tileEdge = true,
    tileSize = 8,
    edgeSize = 1,
    insets = { left = 1, right = 1, top = 1, bottom = 1 },
}
HexLog = addon.HexLog
local leftSlots = { [1] = true, [2] = true, [3] = true, [5] = true, [9] = true, [14] = true, [15] = true, [17] = true }

local function ApplyBackdrop(frame)
    frame.backdropInfo = UI.BACKDROP_INFO
    frame:ApplyBackdrop()
end

-- Helper function to format numbers over 999
local function formatNumber(value)
    return value > 999 and string.format("%.1fk", value / 1000) or tostring(value)
end

local function GetPlayerClass()
    local _, className = UnitClass("player")
    return className
end

local function GetClassColorByAPI()
    local className = GetPlayerClass()
    local classColor = C_ClassColor.GetClassColor(className)
    if classColor then
        return classColor:GetRGB()
    end
    -- Return default white color if class name is invalid
    return 1, 1, 1
end
function UI:GetMainFrame()
    return UI.mainFrame
end 

-- MainFrame Mixin
HexTrackerMainframeMixin = {}



function HexTrackerMainframeMixin:OnLoad()
    HexLog("MainFrame OnLoad called", 4)
    self:SetupMainFrame()
    self:SetupChildFrames()
    self:SetupDirtyFrame()
    self:SetupItemSlotFrames()
    self:SetupProgressBars()
    self:SetupCurrencyDisplayButtons()
    self:SetupValorCappedFrame()
    
end

function HexTrackerMainframeMixin:SetupMainFrame()
    self.version = C_AddOns.GetAddOnMetadata(addonName, "Version")
    tinsert(UISpecialFrames, "HexTrackerMainframe")
    UI.mainFrame = self
    self:SetMovable(true)
    self:EnableMouse(true)
    self:SetPoint("CENTER", UIParent, "CENTER", 20, 0)
    ApplyBackdrop(self)
    self:SetBackdropColor(0, 0, 0, 0)
    local r, g, b = GetClassColorByAPI()
    self:SetBackdropBorderColor(r, g, b, 0.5)
    self:Show()

    -- Title
    self.title = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    self.title:SetPoint("TOP", self, "TOP", 0, -10)
    self.title:SetText("Item Upgrade Tracker")

    self:SetScript("OnMouseDown", self.StartMoving)
    self:SetScript("OnMouseUp", self.StopMovingOrSizing)
end

function HexTrackerMainframeMixin:SetupChildFrames()
    local frames = {
        {self.ItemSlotGridFrame, ""},
        {self.CurrentEquippedCostFrame, "Equipped Item"},
        {self.TotalSlotCostFrame, "All Slots"},
        {self.CurrencyBarFrame, "Progress"}
    }

    for _, frameInfo in ipairs(frames) do
        local frame, titleText = frameInfo[1], frameInfo[2]
        ApplyBackdrop(frame)
        frame:SetBackdropColor(0, 0, 0, 0.2)
        local r, g, b = GetClassColorByAPI()
        frame:SetBackdropBorderColor(r, g, b, 0.5)
        
        frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        frame.title:SetFont("Fonts\\FRIZQT__.TTF", 10)
        frame.title:SetPoint("TOP", frame, "TOP", 0, -10)
        frame.title:SetText(titleText)
    end
    local barFrame = self.CurrencyBarFrame
    barFrame.footer = barFrame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    barFrame.footer:SetFont("Fonts\\FRIZQT__.TTF", 6)
    barFrame.footer:SetPoint("BOTTOM", barFrame, "BOTTOM", 0, 5)

    local footerText = "HexOhm Item Upgrade Tracker " .. self.version
    barFrame.footer:SetText(footerText)

    
end

function HexTrackerMainframeMixin:SetupItemSlotFrames()
    self.slotInfoFrames = {}
    for slot in pairs(DB.valorCostsBySlot) do
        HexLog("Creating slot: " .. slot, 4)
        local slotInfoFrame = CreateFrame("Button", "HexTrackerItemSlotInfo" .. slot, self, "HexTrackerItemSlotInfoTemplate")
        slotInfoFrame:Init(slot, self)
        self.slotInfoFrames[slot] = slotInfoFrame
    end
end

function HexTrackerMainframeMixin:SetupValorCappedFrame()
    local frame = ValorCappedFrame
    self.ValorFrame = frame

    ApplyBackdrop(frame)
    frame:SetBackdropColor(0, 0, 0, 0.8)
    frame:SetBackdropBorderColor(1, 1, 1, 0.2)

    -- Title text setup
    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    frame.title:SetFont("Fonts\\FRIZQT__.TTF", 10)
    frame.title:SetPoint("CENTER")
    frame.title:SetText("Valorstones Capped")
    frame.title:SetTextColor(1, 0, 0)

    -- OnShow script
    frame:SetScript("OnShow", function(self)
        if not self.hiddenForSession then
            print("|cffff0000You are Valorstone Capped!|r")
        end
    end)

    -- Tooltip and drag setup
    frame:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_CURSOR")
        GameTooltip:SetText("Right-click to hide", 1, 1, 1)
        GameTooltip:Show()
    end)
    
    frame:SetScript("OnLeave", function() GameTooltip:Hide() end)

    frame:SetScript("OnMouseDown", function(self, button)
        if button == "LeftButton" then
            self:StartMoving()
        elseif button == "RightButton" then
            self.hiddenForSession = true
            self:Hide()
        end
    end)
    
    frame:SetScript("OnMouseUp", function(self, button)
        if button == "LeftButton" then
            self:StopMovingOrSizing()
        elseif button == "RightButton" then
            self:Hide()
        end
    end)

    frame:Hide()
end

function HexTrackerMainframeMixin:SetupDirtyFrame()
    local frame = self.DirtyIndicator
    ApplyBackdrop(frame)
    frame:SetBackdropColor(0, 0, 0, 0.2)
    frame:SetBackdropBorderColor(1, 1, 1, 0.2)

    -- Title text setup
    frame.title = frame:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    frame.title:SetFont("Fonts\\FRIZQT__.TTF", 10)
    frame.title:SetPoint("TOP", frame, "TOP", 0, -5)
    frame.title:SetText("Needs Refreshed")
    frame.title:SetTextColor(1, 0, 0)

    -- Tooltip setup
    frame:SetScript("OnEnter", function()
        GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
        GameTooltip:SetText("Visit the upgrader to refresh", 1, 0.82, 0)
        GameTooltip:Show()
    end)
    
    frame:SetScript("OnLeave", function() GameTooltip:Hide() end)
end

function HexTrackerMainframeMixin:SetupProgressBars()
    local yOffset = -30
    local CurrencyIDs = {3008, 2914, 2915, 2916, 2917}

    local function CreateBars(barType)
        local bars = {}
        for _, currencyID in ipairs(CurrencyIDs) do
            local bar = CreateFrame("StatusBar", nil, self.CurrencyBarFrame, "HexTrackerCurrencyProgressBarTemplate")
            
            bar:Init(currencyID, yOffset, barType)

            yOffset = yOffset - 22

            if barType == "slot" then
                bar:Hide()
            end
            table.insert(bars, bar)
        end
        yOffset = -30
        return bars
    end


    self.slotBars = CreateBars("slot")
    self.equippedBars = CreateBars("equipped")
    
end

function HexTrackerMainframeMixin:SetupCurrencyDisplayButtons()
    local CurrencyIDs = {2914, 2915, 2916, 2917, 3008}

    local function createFrames(parentFrame, lookupTable, type)
        local buttons = {}
        local positions = {
            { "TOPLEFT", 10, -30 },
            { "TOPLEFT", 10, -50 },
            { "TOPRIGHT", -5, -30 },
            { "TOPRIGHT", -5, -50 },
            { "TOP", 0, -70 }
        }

        for i, currencyID in ipairs(CurrencyIDs) do
            local button = CreateFrame("Button", nil, parentFrame, "HexTrackerCurrencyDisplayTemplate")
            button:Init(currencyID, type)
            
            -- Position buttons
            local pos = positions[i] or positions[1]  -- Default to first position if i is out of bounds
            button:SetPoint(pos[1], parentFrame, pos[1], pos[2], pos[3])
            
            table.insert(buttons, button)
        end

        return buttons
    end

    self.currentEquippedCostButtons = createFrames(self.CurrentEquippedCostFrame, DB.totalCurrencyCosts, "Equipped")
    self.TotalSlotCostButtons = createFrames(self.TotalSlotCostFrame, DB.totalSlotCost, "Slot")
end

function HexTrackerMainframeMixin:CheckValorForCapped(quantity)
    if quantity == 2000 and not self.ValorFrame.hiddenForSession then
        self.ValorFrame:Show()
    else
        self.ValorFrame:Hide()
    end
end

function HexTrackerMainframeMixin:GetUISlotBySlotNumber(slot)
    local slotInfoFrame = self.slotInfoFrames[slot]
    return slotInfoFrame
end

function HexTrackerMainframeMixin:HandleCheckboxClick(checkbox)
    local checked = checkbox:GetChecked()
    local CurrentEquippedCostFrame = self.CurrentEquippedCostFrame.TotalEquippedCostCheckBox
    local TotalSlotCostFrame = self.TotalSlotCostFrame.TotalSlotCostCheckBox

    if checkbox == CurrentEquippedCostFrame then
        if checked then
            TotalSlotCostFrame:SetChecked(false)
        end
    elseif checkbox == TotalSlotCostFrame then
        if checked then
            CurrentEquippedCostFrame:SetChecked(false)
        end
    end

    -- Ensure at least one checkbox remains checked
    if not CurrentEquippedCostFrame:GetChecked() and not TotalSlotCostFrame:GetChecked() then
        checkbox:SetChecked(true)
    end

    -- Update the bars visibility based on checkbox states
    local CurrentEquippedCostFramehecked = self.CurrentEquippedCostFrame.TotalEquippedCostCheckBox:GetChecked()
    local TotalSlotCostFrameChecked = self.TotalSlotCostFrame.TotalSlotCostCheckBox:GetChecked()
    
    if CurrentEquippedCostFramehecked then
        self:ShowBarByType("equipped")
    elseif TotalSlotCostFrameChecked then
        self:ShowBarByType("slot")
    end
end

function HexTrackerMainframeMixin:ShowBarByType(type)
    if type == "slot" then

        for _, bar in ipairs(self.slotBars) do
            bar:Show()
        end
        for _, bar in ipairs(self.equippedBars) do
            bar:Hide()
        end
    else
        for _, bar in ipairs(self.slotBars) do
            bar:Hide()
        end
        for _, bar in ipairs(self.equippedBars) do
            bar:Show()
        end
    end
end

function HexTrackerMainframeMixin:UpdateProgressbars()
    for _, bar in ipairs(self.equippedBars) do
        bar:Update()
    end

    for _, bar in ipairs(self.slotBars) do
        bar:Update()
    end
end

function HexTrackerMainframeMixin:UpdateCurrencyDisplayButtons()
    for _, CurrencyDisplay in ipairs(self.TotalSlotCostButtons) do
        CurrencyDisplay:UpdateText()
    end

    for _, CurrencyDisplay in ipairs(self.currentEquippedCostButtons) do
        CurrencyDisplay:UpdateText()
    end

end

function HexTrackerMainframeMixin:UpdateSlotInfo()
    for _, frame in pairs(self.slotInfoFrames)do
        frame:UpdateInfo()
    end
end

function HexTrackerMainframeMixin:UpdateAll()
    -- update ItemSlotInfo
    self:UpdateSlotInfo()

    -- update Progress Bars
    self:UpdateProgressbars()

    -- update Currency Display 
    self:UpdateCurrencyDisplayButtons()

    self:CheckDirty()

end

function HexTrackerMainframeMixin:CheckDirty()
    local dirty = false
    for _, slotInfo in pairs(self.slotInfoFrames) do
       
        if slotInfo:IsDirty() then
            dirty = true
            break
        end
    end

    if dirty then
        self.DirtyIndicator:Show()
    else
        self.DirtyIndicator:Hide()
    end
end

function HexTrackerMainframeMixin:UpdateAndShow()
    self:UpdateAll()
    HexLog("Upgrad and Show Called", 4)
    if not self:IsShown() then
        HexLog("ItemUpgradeFrame shown is true", 4)
        self:Show()
    end
    
end






local function SetTextToObj(obj, text, quality)
    obj:SetText(text)

    if quality then
        local color = ITEM_QUALITY_COLORS[quality].color
        if color then
            obj:SetTextColor(color.r, color.g, color.b)
        end
    end
end

-- ItemSlotFrameMixin
HexTrackerItemSlotInfoTemplateMixin = {}
local itemSlotInfo = HexTrackerItemSlotInfoTemplateMixin

function itemSlotInfo:Init(slot, mainFrame)
    self.slot = slot
    self.ItemIcon.slot = slot
    self.equippedItemSlot = {}
    self.qualityString = nil
    self.itemLevel = nil
    self.quality = 1
    local position = UI.slotPositions[slot]

    if position then
        local anchorPoint = leftSlots[slot] and "TOPLEFT" or "TOPRIGHT"
        local buttonAnchorPoint = leftSlots[slot] and "LEFT" or "RIGHT"
        
        self:SetPoint(anchorPoint, mainFrame.ItemSlotGridFrame, anchorPoint, position.x, position.y)
        self.ItemIcon:SetPoint(buttonAnchorPoint, self, buttonAnchorPoint)
    end

    self.backdropInfo = UI.BACKDROP_INFO
    self:ApplyBackdrop()
    self:SetBackdropColor(0, 0, 0, 0.7)
    self:SetBackdropBorderColor(1, 1, 1, 0.2)

    self.DiscountText:SetFont("Fonts\\FRIZQT__.TTF", 10, "OUTLINE")
    self.DiscountText:Hide()

    if not leftSlots[slot] then
        self.DiscountText:SetPoint("CENTER", self, "CENTER", -35, -2)
    end

    self:SetupTooltip()
    self:SetupText()
    self:SetupItemIconClick()
    self:CreateCurrencyIcons()
    self.CurrencyIcon3008:Show()
end

function itemSlotInfo:OnMouseDown(button)
    
    if not ItemUpgradeFrame then return end

    if button == "LeftButton" then
        PickupInventoryItem(self.slot)
    elseif button == "RightButton" then
      
        local location = self.equippedItemSlot.location
        if location and location:IsValid() then
           
            C_ItemUpgrade.ClearItemUpgrade()
            C_ItemUpgrade.SetItemUpgradeFromLocation(location)
        else
            print("not a valid location")
        end
    end
    
end

function itemSlotInfo:SetupItemIconClick()


    -- Named function for handling the click event
    local function OnItemIconClick(self, button)
        local location = self:GetParent().equippedItemSlot.location
        -- Ensure the item upgrade frame is available
        if not ItemUpgradeFrame then return end
        
        -- Check if the ItemUpgradeFrame is shown
        if ItemUpgradeFrame:IsShown() then
            if button == "LeftButton" then
                PickupInventoryItem(self.slot)
            elseif button == "RightButton" then
                print(button)
                print(tostring(location))
                if location and location:IsValid() then
                    print("location valid")
                    C_ItemUpgrade.ClearItemUpgrade()
                    C_ItemUpgrade.SetItemUpgradeFromLocation(location)
                else
                    print("not a valid location")
                end
            else
                print(button)
            end
        end
    end

    -- Set up the click script for the item icon
    self.ItemIcon:SetScript("OnMouseDown", OnItemIconClick)
end

function itemSlotInfo:CreateCurrencyIcons()
    -- Create frame for currency icon 3008 (displayed first)
    self.CurrencyIcon3008 = self:CreateTexture(nil, "OVERLAY")
    self.CurrencyIcon3008:SetSize(10, 10) -- Set the size of the icon
    self.CurrencyIcon3008:SetTexture(C_CurrencyInfo.GetCurrencyInfo(3008).iconFileID) -- Get the texture for currency 3008
    self.CurrencyIcon3008:SetPoint("LEFT", self.DiscountText, "RIGHT", 3, 1) -- Position it to the right of DiscountText

    -- Tooltip for currency icon 3008
    self.CurrencyIcon3008:SetScript("OnEnter", function()
        GameTooltip:SetOwner(self.CurrencyIcon3008, "ANCHOR_RIGHT")
        GameTooltip:SetText("Half price Valorstones")
        GameTooltip:Show()
    end)
    self.CurrencyIcon3008:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    -- Create frame for currency icon 2914 (displayed second)
    self.CurrencyIcon2914 = self:CreateTexture(nil, "OVERLAY")
    self.CurrencyIcon2914:SetSize(10, 10) -- Set the size of the icon
    self.CurrencyIcon2914:SetTexture(C_CurrencyInfo.GetCurrencyInfo(2914).iconFileID) -- Get the texture for currency 2914
    self.CurrencyIcon2914:SetPoint("LEFT", self.CurrencyIcon3008, "RIGHT", 5, 0) -- Position it to the right of the first icon

    -- Tooltip for currency icon 2914
    self.CurrencyIcon2914:SetScript("OnEnter", function()
        GameTooltip:SetOwner(self.CurrencyIcon2914, "ANCHOR_RIGHT")
        GameTooltip:SetText("No Crest Cost")
        GameTooltip:Show()
    end)
    self.CurrencyIcon2914:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)
end

function itemSlotInfo:SetupTooltip()

    local function AddCostLines(costs, title)
        if costs then
            GameTooltip:AddLine(title)
            local sortedCurrencyIDs = {}
            for currencyID in pairs(costs) do
                table.insert(sortedCurrencyIDs, currencyID)
            end
            table.sort(sortedCurrencyIDs)
            for _, currencyID in ipairs(sortedCurrencyIDs) do
                local cost = costs[currencyID]
                local currencyName = C_CurrencyInfo.GetCurrencyInfo(currencyID).name
                GameTooltip:AddLine(currencyName .. ": " .. cost)
            end
        else
            GameTooltip:AddLine("Not an Upgradable Item")
        end
    end

    self:SetScript("OnEnter", function()
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        local equippedItemSlot = self.equippedItemSlot
        --local itemInfo = itemSlot.info

        if equippedItemSlot then
            AddCostLines(equippedItemSlot.sumEquippedItemsCost, "\nCosts to Max Out Current Item:")
            AddCostLines(equippedItemSlot.maxSlotCosts, "\nEstimated Costs to Max Out Slot:")
        else
            GameTooltip:SetText("No item found.")
        end

        GameTooltip:Show()
    end)

    self:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    self.ItemIcon:SetScript("OnEnter", function()
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        local equippedItemSlot = self.equippedItemSlot

        if equippedItemSlot then
            local itemLink = equippedItemSlot.link
            if itemLink then
                GameTooltip:SetHyperlink(itemLink)
            else
                GameTooltip:SetText("No item found.")
            end
        else
            GameTooltip:SetText("No item found.")
        end

        GameTooltip:Show()
    end)

    self:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

end

function itemSlotInfo:SetupText()
    local slot = self.slot or 1
    local upgradeString = "Undetermined"
    local itemLevel = "Item Level"
    local quality = 0
    
    local color = ITEM_QUALITY_COLORS[quality].color

    local function createText(anchor1, anchor2, xOffset, yOffset, text, fontSize, color)
        local fontString = self:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
        fontString:SetPoint(anchor1, self.ItemIcon, anchor2, xOffset, yOffset)
        fontString:SetFont("Fonts\\FRIZQT__.TTF", fontSize, "OUTLINE")
        fontString:SetText(text)
        if color then
            fontString:SetTextColor(color.r, color.g, color.b)
        end
        return fontString
    end
    -- Update or create the quality string
    local anchor1 = leftSlots[slot] and "TOPLEFT" or "TOPRIGHT"
    local anchor2 = leftSlots[slot] and "TOPRIGHT" or "TOPLEFT"
    local xOffset = leftSlots[slot] and 0 or 0
    local yOffset = leftSlots[slot] and -3 or -3


    self.qualityString = createText(anchor1, anchor2, xOffset, yOffset, upgradeString, 8)
    self.itemLevel = createText(anchor1, anchor2, xOffset, yOffset - 10, itemLevel, 8, color)
end

function itemSlotInfo:UpdateInfo()
    self:UpdateText()
    self:UpdateIcon()
end

function itemSlotInfo:UpdateText()

    HexLog("Updating Slot Text: " .. self.slot, 4)
    local equippedItemSlot = self.equippedItemSlot

    if not equippedItemSlot.location:IsValid() then
        print("not valid location")
        self:Hide()
        return
    else
        self:Show()
    end

    local itemLevel
    if equippedItemSlot then
        itemLevel = equippedItemSlot.itemLevel or "error"
        local quality = equippedItemSlot.quality or 0
        SetTextToObj(self.itemLevel, itemLevel, quality)
        local color = ITEM_QUALITY_COLORS[quality].color
        self:SetBackdropBorderColor(color.r, color.g, color.b, 0.7)
    else
        HexLog("No equippedItemSlot found for slot " .. self.slot, 1)
    end
    

    local itemInfo = equippedItemSlot.info
    if itemInfo then
        local currUpgrade = itemInfo.currUpgrade or ""
        local maxUpgrade = itemInfo.maxUpgrade or ""
        local upgradeString = itemInfo.customUpgradeString

        
        upgradeString = upgradeString .. ": " .. tostring(currUpgrade) .. " / " .. tostring(maxUpgrade)

        SetTextToObj(self.qualityString, upgradeString)

        if self:IsDiscounted() then
            self.DiscountText:Show()
        else
            self.DiscountText:Hide()
        end



    else
        local upgradeString = "Not Upgradeable"
        SetTextToObj(self.qualityString, upgradeString)
    end

    if self:IsDiscountedValor() and self.DiscountText:IsShown() then
        self.CurrencyIcon3008:Show()
    else
        self.CurrencyIcon3008:Hide()
    end

    if self:IsDiscountedCrest() and self.DiscountText:IsShown() then
        self.CurrencyIcon2914:Show()
    else
        self.CurrencyIcon2914:Hide()
    end
end

function itemSlotInfo:IsDiscounted()
    local itemSlot = self.equippedItemSlot
    local itemInfo = itemSlot.info
    --print(itemSlot.slot)

    if itemInfo.upgradeLevelInfos and itemSlot.upgradeable then
        local upgradeLevelInfos = itemInfo.upgradeLevelInfos[2]
        if upgradeLevelInfos and upgradeLevelInfos.currencyCostsToUpgrade then
            local currencyCostsToUpgrade = upgradeLevelInfos.currencyCostsToUpgrade[1]
            if currencyCostsToUpgrade and currencyCostsToUpgrade.discountInfo then
                local discountInfo = currencyCostsToUpgrade.discountInfo
                return discountInfo.isDiscounted
                --print(discountInfo.isDiscounted)
                --print(discountInfo.isPartialTwoHandDiscount)
                --print(discountInfo.isAccountWideDiscount)
                --print(discountInfo.doesCurrentCharacterMeetHighWatermark)

            end
        end
    end
    return false
end

function itemSlotInfo:IsDiscountedValor()
    

    local halfCostValorThreshold = self.equippedItemSlot.accountHighWatermark
    local itemLevel = self.equippedItemSlot.itemLevel
    
    if halfCostValorThreshold then 
        if itemLevel < halfCostValorThreshold then
            return true
        else
            return false
        end
    end
end

function itemSlotInfo:IsDiscountedCrest()
    local freeCrestThreshold = self.equippedItemSlot.characterHighWatermark
    local itemLevel = self.equippedItemSlot.itemLevel
    
    if freeCrestThreshold then 
        if itemLevel < freeCrestThreshold then
            return true
        else
            return false
        end
    end
end

function itemSlotInfo:UpdateIcon()
    local itemIcon = self.equippedItemSlot.itemIcon
    if itemIcon then
        self.ItemIcon:SetNormalTexture(itemIcon)
    end
end

function itemSlotInfo:IsDirty()
    if self.equippedItemSlot.location:IsValid() then
        return self.equippedItemSlot.dirty
    end
end




HexTrackerCurrencyDisplayTemplateMixin = {}
local currencyDisplay = HexTrackerCurrencyDisplayTemplateMixin
function currencyDisplay:Init(currencyID, type)

    self.currencyID = currencyID
    self.type = type

    self:SetSize(60, 20)

    self.Cost:SetText(0)
    self.Cost:SetFont("Fonts\\FRIZQT__.TTF", 10)

    local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyID)
    local iconFileID = currencyInfo.iconFileID
    local itemLink = C_CurrencyInfo.GetCurrencyLink(currencyID)

    self.CurrencyIcon:SetTexture(iconFileID)
    self.CurrencyIcon:SetShown(true)

    self:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        if itemLink then
            GameTooltip:SetHyperlink(itemLink)
        else
            GameTooltip:SetText("No item found.")
        end
        GameTooltip:Show()
    end)

    self:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    return self
end

function currencyDisplay:UpdateText()
    HexLog("updating Display Text",4)
    local currencyID = self.currencyID
    
    if self.type == "Slot" then
        
        local cost = HexOhmUpgradeTracker.totalSlotCost[currencyID].cost
        self.Cost:SetText(cost)
        HexLog("updating Slot currency display text to " .. cost, 4)
    else
        local cost = HexOhmUpgradeTracker.totalCurrencyCosts[currencyID].cost
        self.Cost:SetText(cost)
        HexLog("updating equippted currency display text to " .. cost, 4)
    end

end







HexTrackerCurrencyProgressBarTemplateMixin = {}
local ProgressBarMixin = HexTrackerCurrencyProgressBarTemplateMixin
function ProgressBarMixin:Init(currencyID, yOffset, barType)
    self.currencyID = currencyID

    self:SetSize(120, 15)
    self:SetPoint("TOP", self:GetParent(), "TOP", 0, yOffset)
    self:SetMinMaxValues(0, 100)
    if barType == "slot" then 
        self.DB = DB.totalSlotCost
    else
        self.DB = DB.totalCurrencyCosts
    end

    local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(currencyID)
    self.name = string.match(currencyInfo.name, "%S+")
    self.currentQuantity = currencyInfo.quantity
    self.goalQuantity = self.DB[currencyID].cost
    self.link = C_CurrencyInfo.GetCurrencyLink(currencyID)

    local progress = (self.currentQuantity / self.goalQuantity) * 100
    if self.goalQuantity == 0 then
        progress = 1
    end
    self:SetValue(progress)

    self.TextContainer.ProgressText:SetText(self.name)
    self.TextContainer.ProgressText:SetFont("Fonts\\FRIZQT__.TTF", 10)
    self.TextContainer.CurrentProgress:SetFont("Fonts\\FRIZQT__.TTF", 10)

    -- Use formatted numbers for display
    local formattedCurrent = formatNumber(self.currentQuantity)
    local formattedGoal = formatNumber(self.goalQuantity)
    local bartext = formattedCurrent .. "/" .. formattedGoal
    self.TextContainer.CurrentProgress:SetText(bartext)

    
    -- Tooltip setup
    self:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT", 0, -120)
        GameTooltip:SetHyperlink(self.link)
        GameTooltip:Show()
    end)

    self:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)
end

function ProgressBarMixin:Update()
    if self.currencyID then 
        local currencyInfo = C_CurrencyInfo.GetCurrencyInfo(self.currencyID)
        self.currentQuantity = currencyInfo.quantity
        self.goalQuantity = self.DB[self.currencyID].cost
        if self.currencyID == DB.VALORSTONE_ID then
            self:GetParent():GetParent():CheckValorForCapped(self.currentQuantity)
        end

        local progress = (self.currentQuantity / self.goalQuantity) * 100
        if self.goalQuantity == 0 then
            progress = 1
        end
        self:SetValue(progress)

        -- Use formatted numbers for display
        local formattedCurrent = formatNumber(self.currentQuantity)
        local formattedGoal = formatNumber(self.goalQuantity)
        local bartext = formattedCurrent .. "/" .. formattedGoal
        self.TextContainer.CurrentProgress:SetText(bartext)
    end
    
end

function ProgressBarMixin:OnShow()
    -- When the frame is shown, start both the value animation and the glow animation.
    self:AnimateToCurrentValue()
    self:StartGlowAnimation()
end

function ProgressBarMixin:AnimateToCurrentValue()
    local currentValue = self:GetValue() or 0  -- Get the current value of the bar.
    local targetValue = currentValue  -- Use the current set value as the target value.
    local animationDuration = 1.0  -- Duration in seconds for the animation.
    local startTime = GetTime()

    -- Set the initial value to 0 before animating.
    self:SetValue(0)

    -- Use an OnUpdate script to smoothly animate the value.
    self:SetScript("OnUpdate", function(frame, elapsed)
        local elapsedTime = GetTime() - startTime
        local progress = math.min(elapsedTime / animationDuration, 1)  -- Ensure progress is between 0 and 1.

        -- Interpolate between 0 and target value.
        local newValue = progress * targetValue
        frame:SetValue(newValue)

        if progress >= 1 then
            frame:SetScript("OnUpdate", nil)  -- Stop updating once the animation is complete.
        end
    end)
end

function ProgressBarMixin:StartGlowAnimation()
    -- Play the glow animation group.
    if self.GlowAnim then
        self.GlowAnim:Play()
    end
end

function ProgressBarMixin:StopGlowAnimation()
    -- Stop the glow animation group.
    if self.GlowAnim then
        self.GlowAnim:Stop()
    end
end

