-- HousingDecorGuide/UI/Tabs/Styles/HDG_ST_ItemPanel.lua
-- Right-side item-detail panel for the Styles tab. Renders the currently
-- selected item's name/tier/source/reason text, a 3D preview, and Add-to-
-- Crafting / Add-to-Shopping-List action buttons.
--
-- Owns its panel frame; callers should not poke `detailPanel` directly.
-- API:
--   ItemPanel:Build(parent, anchorFrame, scheme)  -> creates the panel
--   ItemPanel:Render(scheme)                       -> repaints from current State
--   ItemPanel:LoadModel(decorID)                   -> swaps the 3D preview
--   ItemPanel:Show() / :Hide() / :GetFrame()       -> visibility/anchor access
--
-- Loaded after HDG_ST_State.lua so privateDB.HDG_ST.State is available.

local _, privateDB = ...

local HDG = _G.HousingDecorGuide
local L = HDG_L or {}

privateDB.HDG_ST = privateDB.HDG_ST or {}
local State = privateDB.HDG_ST.State

local M = {}
privateDB.HDG_ST.ItemPanel = M

-- Local helpers (mirror the StylesTab orchestrator's thin wrappers).
local function GetScheme()        return HDG.Theme.GetCurrentScheme() end
local function RegisterWidget(w, t) HDG.Theme.RegisterWidget(w, t) end
local function ApplyFont(fs, s, ft) HDG.Theme.ApplyFont(fs, s, ft) end

local function GetStyleEngine() return privateDB and privateDB.HDG_StyleEngine end
local function GetStyleDef(styleId)
    local SE = GetStyleEngine()
    if SE and SE.GetAllStyleDefs then
        local defs = SE:GetAllStyleDefs()
        return defs and defs[styleId]
    end
    return nil
end

-- Tier-compatibility labels used by the side panel's tier line.
local TIER_LABELS = {
    ["first-order"]    = "|cff00ff001ST ORDER|r",
    ["second-order"]   = "|cffffff002ND ORDER|r",
    ["neutral"]        = "|cffaaaaaaNEUTRAL|r",
    ["clash"]          = "|cffff4444CLASH|r",
    ["unclassified"]   = "|cff888888UNCLASSIFIED|r",
}

-- The detailPanel widget. Set by Build(); callers retrieve via :GetFrame().
local panel

-- =============================================================================
-- BUILD: panel frame + child widgets (runs once during CreateDetail)
-- =============================================================================

function M:Build(parent, anchorFrame, scheme)
    if panel then return panel end

    panel = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    panel:SetPoint("TOPLEFT", anchorFrame, "TOPRIGHT", 4, 0)
    panel:SetPoint("BOTTOMRIGHT", -4, 4)
    HDG_UIHelpers.ApplyBackdrop(panel, "panel",
        {0.08, 0.08, 0.08, 0.6}, {0.2, 0.2, 0.2, 0.4})
    RegisterWidget(panel, "Panel")

    panel.nameText = panel:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    panel.nameText:SetPoint("TOPLEFT", 10, -10)
    if scheme then ApplyFont(panel.nameText, scheme, "header") end

    panel.tierText = panel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    panel.tierText:SetPoint("TOPLEFT", panel.nameText, "BOTTOMLEFT", 0, -4)
    if scheme then ApplyFont(panel.tierText, scheme, "small") end

    panel.sourceText = panel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    panel.sourceText:SetPoint("TOPLEFT", panel.tierText, "BOTTOMLEFT", 0, -4)
    if scheme then ApplyFont(panel.sourceText, scheme, "small") end

    panel.reasonText = panel:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    panel.reasonText:SetPoint("TOPLEFT", panel.sourceText, "BOTTOMLEFT", 0, -8)
    if scheme then
        ApplyFont(panel.reasonText, scheme, "small")
        panel.reasonText:SetTextColor(scheme.text_dim.r, scheme.text_dim.g, scheme.text_dim.b, 1)
    end

    -- 3D model preview container.
    local previewContainer = CreateFrame("Frame", nil, panel, "BackdropTemplate")
    previewContainer:SetPoint("TOPLEFT", panel.reasonText, "BOTTOMLEFT", 0, -10)
    previewContainer:SetPoint("RIGHT", panel, "RIGHT", -10, 0)
    previewContainer:SetPoint("BOTTOM", panel, "BOTTOM", 0, 70)
    HDG_UIHelpers.ApplyBackdrop(previewContainer, "panel",
        {0.05, 0.05, 0.05, 0.8}, {0.2, 0.2, 0.2, 0.4})
    RegisterWidget(previewContainer, "Panel")
    previewContainer:Hide()
    panel.previewContainer = previewContainer

    local decorPreview = HDG_UIHelpers.CreateDecorPreview(previewContainer, {
        squareAspect = false,
        showOverlays = false,
        showControls = true,
        showCorbels  = true,
        sceneInsets  = { top = 4, right = 4, bottom = 4, left = 4 },
    })
    decorPreview:SetAllPoints()
    decorPreview.placeholder:Hide() -- container visibility controls this
    panel.decorPreview = decorPreview

    -- Add to Crafting Queue (craftable items only).
    panel.craftBtn = CreateFrame("Button", nil, panel, "UIPanelButtonTemplate")
    panel.craftBtn:SetSize(180, 24)
    panel.craftBtn:SetPoint("BOTTOMLEFT", 10, 40)
    panel.craftBtn:SetText(L["ACQ_ADD_TO_QUEUE"])
    panel.craftBtn:SetScript("OnClick", function()
        local SE = GetStyleEngine()
        if State.selectedItemID and SE and HDG_UI and HDG_UI.AddToCraftingQueue then
            local recipe = SE:GetRecipe(State.selectedItemID)
            if recipe then
                local queueItem = {
                    id         = recipe.itemID,
                    name       = recipe.name,
                    spell      = recipe.spellID,
                    reagents   = recipe.reagents,
                    expansion  = recipe.expansion or "Unknown",
                    profession = recipe.profession,
                }
                HDG_UI.AddToCraftingQueue(queueItem)
                print("|cff00ccff[HDG]|r Added " .. (recipe.name or "recipe") .. " to crafting queue")
            end
        end
    end)
    panel.craftBtn:Hide()

    -- Add to Vendor Shopping List (vendor items only).
    panel.vendorBtn = CreateFrame("Button", nil, panel, "UIPanelButtonTemplate")
    panel.vendorBtn:SetSize(180, 24)
    panel.vendorBtn:SetPoint("BOTTOMLEFT", 10, 10)
    panel.vendorBtn:SetText(L["STYLE_ADD_TO_SHOPPING_LIST"])
    panel.vendorBtn:SetScript("OnClick", function()
        if State.selectedItemID and HDG.Store then
            local npcIDs = HDG_VendorByItem and HDG_VendorByItem[State.selectedItemID]
            if npcIDs and #npcIDs > 0 then
                if HDG.Store:AddToVendorShoppingList(State.selectedItemID, npcIDs[1]) then
                    local iName = HDG_Data and HDG_Data.GetCachedItemName(State.selectedItemID)
                                  or ("Item " .. State.selectedItemID)
                    print("|cff00ccff[HDG]|r Added " .. iName .. " to shopping list")
                    if HDG_VendorShoppingList and HDG_VendorShoppingList.IsShown
                       and HDG_VendorShoppingList.IsShown() then
                        HDG_VendorShoppingList.Refresh()
                    end
                    if HDG_UI and HDG_UI.UpdateShopListBadge then HDG_UI.UpdateShopListBadge() end
                end
            end
        end
    end)
    panel.vendorBtn:Hide()

    return panel
end

-- =============================================================================
-- RENDER: paint from current State (called by RefreshDetail / row click)
-- =============================================================================

function M:Render(scheme)
    if not panel then return end
    if not State.selectedItemID then
        panel.nameText:SetText("")
        panel.tierText:SetText("")
        panel.sourceText:SetText("")
        panel.reasonText:SetText("")
        panel.craftBtn:Hide()
        panel.vendorBtn:Hide()
        if panel.previewContainer then panel.previewContainer:Hide() end
        panel._currentDecorID = nil
        return
    end

    local entry = HDG_AllDecorDB and HDG_AllDecorDB[State.selectedItemID]
    if not entry then return end
    local decorID = entry[1]

    local SE = GetStyleEngine()

    -- Item name
    local ic = SE and SE:GetItemInfo(State.selectedItemID)
    panel.nameText:SetText(ic and ic.name or ("Item #" .. State.selectedItemID))

    -- Tier or subcategory label
    local sDef = GetStyleDef(State.selectedStyle)
    if sDef and sDef.subcategories then
        local subcatLabel = SE and SE:GetSubcategoryLabel(State.selectedStyle, State.selectedTier) or ""
        panel.tierText:SetText("|cff88cc88" .. subcatLabel .. "|r")
    else
        local tier = SE and SE:GetCompatibility(State.selectedStyle, decorID) or "unclassified"
        panel.tierText:SetText("Compatibility: " .. (TIER_LABELS[tier] or tier))
    end

    -- Source
    local sourceType   = entry[2]
    local sourceName   = entry[3] or ""
    local sourceDetail = entry[4] or ""
    local sourceLabel  = SE and SE:GetSourceLabel(sourceType) or ""
    if sourceType ~= 5 and HDG_VendorResolver and HDG_VendorResolver.GetVendorsForItem then
        local vendors = HDG_VendorResolver.GetVendorsForItem(State.selectedItemID)
        if vendors and #vendors > 0 then
            sourceLabel = sourceLabel .. " + Vendor"
        end
    end
    local sourceStr = string.format(L["TIP_SOURCE"], sourceLabel)
    if #sourceName > 0 then sourceStr = sourceStr .. " - " .. sourceName end
    if #sourceDetail > 0 then sourceStr = sourceStr .. " (" .. sourceDetail .. ")" end
    panel.sourceText:SetText(sourceStr)
    if scheme then
        ApplyFont(panel.sourceText, scheme, "small")
        local s = GetScheme()
        if s then panel.sourceText:SetTextColor(s.text.r, s.text.g, s.text.b, 1) end
    end

    -- Why this tier
    local reason = SE and SE:GetTierReason(State.selectedStyle, decorID) or ""
    panel.reasonText:SetText(reason)

    -- Action buttons (visibility based on item source).
    local recipe = SE and SE:GetRecipe(State.selectedItemID)
    local npcIDs = HDG_VendorByItem and HDG_VendorByItem[State.selectedItemID]
    panel.craftBtn:SetShown(recipe ~= nil)
    panel.vendorBtn:SetShown(npcIDs ~= nil and #npcIDs > 0)

    -- 3D preview
    self:LoadModel(decorID)
end

function M:LoadModel(decorID)
    if not panel or not panel.decorPreview then return end
    panel._currentDecorID = decorID
    local ok = panel.decorPreview:LoadItemData({ decorID = decorID })
    panel.previewContainer:SetShown(ok)
end

-- =============================================================================
-- VISIBILITY / ACCESS
-- =============================================================================

function M:GetFrame() return panel end
function M:Show()    if panel then panel:Show() end end
function M:Hide()    if panel then panel:Hide() end end

return M
