--[[
============================================================================
ETB v10.0 - ItemRow.lua
============================================================================
Reusable item row component with frame pooling.
============================================================================
]]--

local ADDON_NAME, NS = ...
local ETB = NS.ETB

ETB.ItemRow = {
    pool = {},
    active = {},
    nextID = 1,
}

local ItemRow = ETB.ItemRow

-- =============================================================================
-- FRAME POOL
-- =============================================================================

function ItemRow:Acquire(parent)
    local frame = table.remove(self.pool)
    if not frame then
        frame = self:CreateFrame(parent)
    else
        frame:SetParent(parent)
    end
    frame:Show()
    self.active[frame] = true
    return frame
end

function ItemRow:Release(frame)
    if not frame then return end
    frame:Hide()
    frame:ClearAllPoints()
    frame.itemData = nil
    self.active[frame] = nil
    self.pool[#self.pool + 1] = frame
end

function ItemRow:ReleaseAll()
    for frame in pairs(self.active) do
        self:Release(frame)
    end
end

function ItemRow:GetPoolStats()
    local active = 0
    for _ in pairs(self.active) do active = active + 1 end
    return { pool = #self.pool, active = active, total = #self.pool + active }
end

-- =============================================================================
-- CREATE FRAME
-- =============================================================================

function ItemRow:CreateFrame(parent)
    local id = self.nextID
    self.nextID = self.nextID + 1
    
    local f = CreateFrame("Button", "ETBItemRow" .. id, parent)
    f:SetSize(440, 32)
    f:SetHighlightTexture("Interface\\QuestFrame\\UI-QuestTitleHighlight", "ADD")
    
    f.bg = f:CreateTexture(nil, "BACKGROUND")
    f.bg:SetAllPoints()
    f.bg:SetColorTexture(0.1, 0.1, 0.1, 0.5)
    
    f.collectedBar = f:CreateTexture(nil, "ARTWORK")
    f.collectedBar:SetSize(3, 28)
    f.collectedBar:SetPoint("LEFT", 0, 0)
    
    f.icon = f:CreateTexture(nil, "ARTWORK")
    f.icon:SetSize(24, 24)
    f.icon:SetPoint("LEFT", 5, 0)
    f.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)
    
    f.iconBorder = f:CreateTexture(nil, "OVERLAY")
    f.iconBorder:SetSize(26, 26)
    f.iconBorder:SetPoint("CENTER", f.icon, "CENTER")
    f.iconBorder:SetTexture("Interface\\Common\\WhiteIconFrame")
    
    f.name = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.name:SetPoint("LEFT", f.icon, "RIGHT", 5, 0)
    f.name:SetPoint("RIGHT", f, "RIGHT", -170, 0)
    f.name:SetJustifyH("LEFT")
    f.name:SetWordWrap(false)
    
    f.source = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.source:SetPoint("RIGHT", f.wishlistBtn, "LEFT", -6, 0)
    f.source:SetWidth(90)
    f.source:SetJustifyH("RIGHT")
    f.source:SetTextColor(0.5, 0.5, 0.5)
    f.source:SetWordWrap(false)
    
    f.status = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.status:SetPoint("RIGHT", -10, 0)
    
    f.favStar = f:CreateTexture(nil, "OVERLAY")
    f.favStar:SetSize(14, 14)
    f.favStar:SetPoint("RIGHT", f.status, "LEFT", -4, 0)
    f.favStar:SetTexture("Interface\\Common\\ReputationStar")
    f.favStar:SetTexCoord(0.5, 1, 0, 0.5)
    f.favStar:Hide()
    
    -- Wishlist button (clickable)
    f.wishlistBtn = CreateFrame("Button", nil, f)
    f.wishlistBtn:SetSize(16, 16)
    f.wishlistBtn:SetPoint("RIGHT", f.favStar, "LEFT", -3, 0)
    f.wishlistBtn.icon = f.wishlistBtn:CreateTexture(nil, "OVERLAY")
    f.wishlistBtn.icon:SetAllPoints()
    f.wishlistBtn.icon:SetTexture("Interface\\Buttons\\UI-GuildButton-PublicNote-Up")
    f.wishlistBtn.icon:SetVertexColor(0.4, 0.4, 0.4)
    f.wishlistBtn:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD")
    f.wishlistBtn:SetScript("OnClick", function(self)
        local item = self:GetParent().itemData
        if item and item.itemID and ETB.Wishlist then
            local added = ETB.Wishlist:ToggleItem(item.itemID)
            if added then
                self.icon:SetVertexColor(1, 0.82, 0)
                self:SetAlpha(1)
                ETB:Print("|cffffcc00Wishlist:|r Added " .. (item.name or "item"))
            else
                self.icon:SetVertexColor(0.5, 0.5, 0.5)
                self:SetAlpha(0.5)
                ETB:Print("|cffffcc00Wishlist:|r Removed " .. (item.name or "item"))
            end
        end
    end)
    f.wishlistBtn:SetScript("OnEnter", function(self)
        GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
        local item = self:GetParent().itemData
        local onList = item and ETB.Wishlist and ETB.Wishlist:HasItem(item.itemID)
        if onList then
            GameTooltip:AddLine("Click to remove from wishlist")
        else
            GameTooltip:AddLine("Click to add to wishlist")
        end
        GameTooltip:Show()
    end)
    f.wishlistBtn:SetScript("OnLeave", function() GameTooltip:Hide() end)
    
    -- Class usability indicator
    f.classIndicator = f:CreateTexture(nil, "OVERLAY")
    f.classIndicator:SetSize(14, 14)
    f.classIndicator:SetPoint("RIGHT", f.wishlistBtn, "LEFT", -3, 0)
    f.classIndicator:SetTexture("Interface\\Buttons\\UI-GroupLoot-Pass-Up")
    f.classIndicator:Hide()
    
    -- Alternative items indicator/button (next to name)
    f.altButton = CreateFrame("Button", nil, f)
    f.altButton:SetSize(18, 18)
    f.altButton:SetPoint("LEFT", f.name, "RIGHT", 2, 0)
    f.altButton:SetNormalTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Up")
    f.altButton:SetPushedTexture("Interface\\Buttons\\UI-SpellbookIcon-NextPage-Down")
    f.altButton:SetHighlightTexture("Interface\\Buttons\\UI-Common-MouseHilight", "ADD")
    f.altButton:SetScript("OnClick", function(self, button)
        if button == "LeftButton" then
            ItemRow:CycleAlternative(self:GetParent())
        end
    end)
    f.altButton:SetScript("OnEnter", function(self)
        local item = self:GetParent().itemData
        if item and item.hasAlternatives then
            GameTooltip:SetOwner(self, "ANCHOR_RIGHT")
            GameTooltip:SetText("Alternate Items", 1, 1, 1)
            GameTooltip:AddLine(string.format("Click to cycle through %d items with this appearance", #item.alternatives), 0.8, 0.8, 0.8)
            GameTooltip:AddLine(" ")
            for i, alt in ipairs(item.alternatives) do
                local marker = (i == item.selectedAlternativeIndex) and "|cff00ff00►|r " or "   "
                local color = ETB:GetQualityColor(alt.quality)
                GameTooltip:AddLine(marker .. color .. (alt.name or "Unknown") .. "|r", 1, 1, 1)
            end
            GameTooltip:Show()
        end
    end)
    f.altButton:SetScript("OnLeave", function() GameTooltip:Hide() end)
    f.altButton:Hide()
    
    f:SetScript("OnEnter", function(self) ItemRow:OnEnter(self) end)
    f:SetScript("OnLeave", function()
        GameTooltip:Hide()
        if ETB.ModelPreview then
            ETB.ModelPreview:Hide()
        end
    end)
    f:SetScript("OnClick", function(self, btn) ItemRow:OnClick(self, btn) end)
    
    f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    
    return f
end

-- =============================================================================
-- UPDATE
-- =============================================================================

function ItemRow:Update(frame, item, index)
    if not frame or not item then return end
    
    frame.itemData = item
    frame.index = index
    
    frame.bg:SetColorTexture(index % 2 == 0 and 0.12 or 0.08, index % 2 == 0 and 0.12 or 0.08, index % 2 == 0 and 0.14 or 0.09, 0.5)
    if item.isCollected then
        frame.collectedBar:SetColorTexture(0, 1, 0.5, 0.9)
    else
        frame.collectedBar:SetColorTexture(1, 0.25, 0.25, 0.8)
    end
    
    frame.icon:SetTexture(item.icon or "Interface\\Icons\\INV_Misc_QuestionMark")
    
    local r, g, b = ETB:GetQualityRGB(item.quality)
    frame.iconBorder:SetVertexColor(r, g, b)
    
    -- Handle name - convert to string and check if it's actually a name or just itemID
    local displayName = item.name
    
    -- If name is missing or invalid, try to get it
    if not displayName or displayName == "" or displayName == "Loading..." or displayName == "Unknown" or type(displayName) == "number" then
        -- Try GetItemInfo first (might be cached)
        if item.itemID then
            local name = GetItemInfo(item.itemID)
            if name and name ~= "" then
                displayName = name
                -- Update the item object
                item.name = name
                -- Also update cache
                if ETB.BlizzardData and ETB.BlizzardData.itemCache then
                    local cached = ETB.BlizzardData.itemCache:Get(item.itemID)
                    if cached then
                        cached.name = name
                    end
                end
            else
                displayName = "Loading..."
                -- Request item info if not already pending
                if ETB.BlizzardData and not ETB.BlizzardData.pendingItemInfo[item.itemID] then
                    ETB.BlizzardData.pendingItemInfo[item.itemID] = true
                    GetItemInfo(item.itemID)  -- Request async
                end
            end
        else
            displayName = "Loading..."
        end
    else
        displayName = tostring(displayName)
    end
    
    frame.name:SetText(ETB:GetQualityColor(item.quality) .. displayName .. "|r")
    
    -- Source info (fills gap between name and right-side icons)
    local srcText = ""
    if item.sourceType then
        local SOURCE_LABELS = {
            BOSS = item.isRaid and "Raid" or "Dungeon",
            QUEST = "Quest",
            VENDOR = "Vendor",
            CRAFTED = "Crafted",
            PVP = "PvP",
            WORLD_DROP = "World Drop",
            ACHIEVEMENT = "Achievement",
            PROFESSION = "Crafted",
        }
        srcText = SOURCE_LABELS[item.sourceType] or item.sourceType
    elseif item.sourceID and C_TransmogCollection and C_TransmogCollection.GetSourceInfo then
        local ok, info = pcall(C_TransmogCollection.GetSourceInfo, item.sourceID)
        if ok and info and info.sourceType then
            local BLIZZ_SOURCE = {
                [1] = "Boss Drop",
                [2] = "Quest",
                [3] = "Vendor",
                [4] = "World Drop",
                [5] = "Achievement",
                [6] = "Crafted",
            }
            srcText = BLIZZ_SOURCE[info.sourceType] or ""
        end
    end
    frame.source:SetText("|cffaaaaaa" .. srcText .. "|r")
    
    frame.status:SetText(item.isCollected and "|cff00ff00✓|r" or "|cffff6666✗|r")
    
    -- Favorites (always visible - dim when not starred, gold when starred)
    local isFav = ETB.FavoritesManager and ETB.FavoritesManager:IsFavorite(item.itemID)
    if isFav then
        frame.favStar:SetVertexColor(1, 0.82, 0)
        frame.favStar:SetAlpha(1)
    else
        frame.favStar:SetVertexColor(0.5, 0.5, 0.5)
        frame.favStar:SetAlpha(0.5)
    end
    frame.favStar:Show()
    
    -- Wishlist (always visible - dim when not listed, gold when listed)
    local isWL = ETB.Wishlist and ETB.Wishlist:HasItem(item.itemID)
    if isWL then
        frame.wishlistBtn.icon:SetVertexColor(1, 0.82, 0)
        frame.wishlistBtn:SetAlpha(1)
    else
        frame.wishlistBtn.icon:SetVertexColor(0.5, 0.5, 0.5)
        frame.wishlistBtn:SetAlpha(0.5)
    end
    
    -- Class usability indicator - shows if active profile cannot transmog this item
    local canTransmog = true
    if item.armorType then
        canTransmog = ETB.BlizzardData and ETB.BlizzardData:CanPlayerWearArmorType(item.armorType) or true
    elseif item.weaponType then
        canTransmog = ETB.BlizzardData and ETB.BlizzardData:CanPlayerUseWeaponType(item.weaponType) or true
    end
    
    if not canTransmog then
        frame.classIndicator:Show()
        -- Also dim the row slightly to make it visually distinct
        frame.bg:SetColorTexture(0.2, 0.1, 0.1, 0.5)  -- Reddish tint
    else
        frame.classIndicator:Hide()
    end
    
    -- Show alternative items button if there are alternatives
    if item.hasAlternatives and item.alternatives and #item.alternatives > 1 then
        frame.altButton:Show()
    else
        frame.altButton:Hide()
    end
end

-- =============================================================================
-- CYCLE ALTERNATIVE ITEMS
-- =============================================================================

function ItemRow:CycleAlternative(frame)
    local item = frame.itemData
    if not item or not item.hasAlternatives or not item.alternatives then return end
    
    -- Cycle to next alternative
    local currentIndex = item.selectedAlternativeIndex or 1
    local nextIndex = (currentIndex % #item.alternatives) + 1
    item.selectedAlternativeIndex = nextIndex
    
    -- Replace current item data with the selected alternative
    local altItem = item.alternatives[nextIndex]
    if altItem then
        -- Copy all properties from alternative to current item
        for key, value in pairs(altItem) do
            if key ~= "alternatives" and key ~= "selectedAlternativeIndex" and key ~= "hasAlternatives" then
                item[key] = value
            end
        end
    end
    
    -- Update the display
    ItemRow:Update(frame, item, frame.index)
    
    -- Update preview if shown
    if ETB.ModelPreview then
        ETB.ModelPreview:PreviewItem(item)
    end
end

-- =============================================================================
-- EVENTS
-- =============================================================================

function ItemRow:OnEnter(frame)
    local item = frame.itemData
    if not item then return end
    
    -- Check if hover preview is enabled
    local showHoverPreview = ETB.Settings:Get("preview.showOnHover")
    
    if showHoverPreview and ETB.ModelPreview then
        -- Show MINIMAL tooltip (just collection status) since preview will show the item
        GameTooltip:SetOwner(frame, "ANCHOR_NONE")  -- Hide from view
        GameTooltip:ClearLines()
        
        -- Show the hover preview instead
        C_Timer.After(0.05, function()
            if frame.itemData == item and 
               ETB.MainFrame and ETB.MainFrame.frame and ETB.MainFrame.frame:IsVisible() and
               frame:IsMouseOver() then
                ETB.ModelPreview:PreviewItem(item)
            end
        end)
    else
        -- Full tooltip when hover preview is disabled
        GameTooltip:SetOwner(frame, "ANCHOR_RIGHT")
        if item.itemID then
            local itemName, itemLink = GetItemInfo(item.itemID)
            if itemLink and itemLink ~= "" then
                if itemLink:match("^|c%x%x%x%x%x%x%x%x|Hitem:") then
                    pcall(GameTooltip.SetHyperlink, GameTooltip, itemLink)
                else
                    ETB:SafeSetTooltipItem(GameTooltip, item.itemID)
                end
            else
                ETB:SafeSetTooltipItem(GameTooltip, item.itemID)
                GetItemInfo(item.itemID)
            end
        end
        
        GameTooltip:AddLine(" ")
        GameTooltip:AddDoubleLine("ItemID:", item.itemID or "?", 1, 0.82, 0, 1, 1, 1)
        local vid = ETB:ResolveVisualID(item)
        if vid then
            GameTooltip:AddDoubleLine("VisualID:", vid, 1, 0.82, 0, 1, 1, 1)
        end
        if item.armorType then
            GameTooltip:AddDoubleLine("Armor Type:", item.armorType, 1, 0.82, 0, 1, 1, 1)
        end
        
        -- Source info is handled by TooltipEnhancer hook (FormatSourceTooltip)
        -- which fires automatically on SetHyperlink above - matching SourcesModal data
        
        GameTooltip:AddLine(" ")
        if item.isCollected then
            GameTooltip:AddLine("|cff00ff00Appearance Collected|r")
            -- Show which item was collected to learn this appearance
            if item.alternatives and #item.alternatives > 1 then
                for _, alt in ipairs(item.alternatives) do
                    if alt.isCollected and alt.name and alt.name ~= "Loading..." then
                        GameTooltip:AddLine("|cffffd100Collected via:|r " .. (alt.name or "Unknown"), 0.8, 0.8, 0.8)
                        break
                    end
                end
            elseif item.isCollected and item.name and item.name ~= "Loading..." then
                GameTooltip:AddLine("|cffffd100Collected via:|r " .. item.name, 0.8, 0.8, 0.8)
            end
        else
            GameTooltip:AddLine("|cffff6666Not Collected|r")
        end
        
        -- Show if active profile can transmog this item
        local canTransmog = true
        if item.armorType then
            canTransmog = ETB.BlizzardData and ETB.BlizzardData:CanPlayerWearArmorType(item.armorType) or true
        elseif item.weaponType then
            canTransmog = ETB.BlizzardData and ETB.BlizzardData:CanPlayerUseWeaponType(item.weaponType) or true
        end
        if not canTransmog then
            local activeClass = ETB.BlizzardData and ETB.BlizzardData:GetActiveClassName() or "Unknown"
            GameTooltip:AddLine("|cffff4444Cannot be transmogged by " .. activeClass .. "|r")
        end
        
        GameTooltip:AddLine(" ")
        GameTooltip:AddLine("Left-click: Preview | Shift: Link | Alt: Favorite", 0.5, 0.5, 0.5)
        GameTooltip:AddLine("Right-click: Sources | Note icon: Wishlist", 0.5, 0.5, 0.5)
        
        GameTooltip:Show()
    end
end

function ItemRow:OnClick(frame, button)
    local item = frame.itemData
    if not item then return end
    
    if button == "LeftButton" then
        if IsShiftKeyDown() then
            if item.itemID then
                local _, link = GetItemInfo(item.itemID)
                if link then ChatEdit_InsertLink(link) end
            end
        elseif IsControlKeyDown() then
            if item.itemID and DressUpItemLink then
                DressUpItemLink("item:" .. item.itemID)
            end
        elseif IsAltKeyDown() then
            if ETB.FavoritesManager then
                ETB.FavoritesManager:ToggleFavorite(item.itemID)
                ItemRow:Update(frame, item, frame.index)
            end
        else
            -- Open Appearance Detail Panel
            if ETB.AppearanceDetail then
                ETB.AppearanceDetail:Toggle(item)
            elseif ETB.ModelPreview then
                ETB.ModelPreview:PreviewItem(item)
            end
        end
    elseif button == "RightButton" then
        if IsControlKeyDown() then
            -- Ctrl+Right-click: toggle wishlist
            if ETB.Wishlist and item.itemID then
                local added = ETB.Wishlist:ToggleItem(item.itemID)
                if added then
                    ETB:Print("|cffffcc00Wishlist:|r Added " .. (item.name or "item"))
                else
                    ETB:Print("|cffffcc00Wishlist:|r Removed " .. (item.name or "item"))
                end
                ItemRow:Update(frame, item, frame.index)
            end
        else
            if ETB.SourcesModal then
                ETB.SourcesModal:Show(item)
            end
        end
    end
end

ETB:Debug("ItemRow", "ItemRow.lua loaded")
