--[[
============================================================================
ETB - LauncherPanel.lua  (Central Plaza)
============================================================================
A paginated "central plaza" hub shown on minimap-button click. Each ETB
feature is a stall staffed by a themed NPC model:

  Transmog Browser .. Lich King          Wishlist ........... Chromie
  Transmog Planner .. your character      Collection Planner . Tirion Fordring
  Raid BiS Browser .. Ra-den              Tutorial ........... Hogger
  Mounts ............ Al'ar (phoenix)     Pets ............... Chromaggus
  Zone Scan ......... Gen. Nazgrim        Rare Tracker ....... Time-Lost Proto-Drake

Three model cards are created once and re-skinned as the player pages through
the plaza, so we never build (or animate) more than three live models at a
time — important for login/FPS smoothness.
============================================================================
]]--

local ADDON_NAME, NS = ...
local ETB = NS.ETB
if not ETB then return end

ETB.LauncherPanel = ETB.LauncherPanel or {}
local LP = ETB.LauncherPanel
LP.frame = nil
LP.page = 1

-- ============================================================================
-- CONSTANTS
-- ============================================================================
local PANEL_WIDTH  = 740
local PANEL_HEIGHT = 488
local CARD_WIDTH   = 215
local CARD_HEIGHT  = 290
local CARD_GAP     = 14
local CARDS_PER_PAGE = 3

-- ============================================================================
-- FEATURE / NPC DEFINITIONS
-- model.kind: "player" | "display" | "creature"
--   display -> SetDisplayInfo(display)  (most reliable; used where the exact
--              creature display id is known)
--   creature-> SetCreature(npc), framed full-body via SetPortraitZoom(0)
-- ============================================================================
local function openTransmogBrowser()
    LP:Hide(); if ETB.MainFrame then ETB.MainFrame:Toggle() end
end
local function openTransmogPlanner()
    LP:Hide()
    if ETB.TransmogUI then
        local TUI = ETB.TransmogUI
        if TUI.Show then TUI:Show() elseif TUI.frame then TUI.frame:Show() end
    end
end
local function openRaidBiS()
    LP:Hide()
    local ERB = ETB.GetERB and ETB:GetERB()
    if ERB and ERB.MainFrame then ERB.MainFrame:Toggle() end
end
local function openWishlist()
    LP:Hide(); if ETB.WishlistPanel then ETB.WishlistPanel:Toggle() end
end
local function openPlanner()
    LP:Hide(); if ETB.PlannerUI then ETB.PlannerUI:Toggle() end
end
local function openTutorial()
    LP:Hide(); if ETB.Tutorial then ETB.Tutorial:Toggle() end
end
local function openMounts()
    LP:Hide()
    if NS.EMT and NS.EMT.Browser and NS.EMT.Browser.Toggle then NS.EMT.Browser:Toggle() end
end
local function openPets()
    LP:Hide()
    if NS.EPT and NS.EPT.Browser and NS.EPT.Browser.Toggle then NS.EPT.Browser:Toggle() end
end
local function openToys()
    LP:Hide()
    if NS.ETT and NS.ETT.Browser and NS.ETT.Browser.Toggle then NS.ETT.Browser:Toggle() end
end
local function openZoneScan()
    LP:Hide()
    if ETB.ZoneScan and ETB.ZoneScan.Toggle then ETB.ZoneScan:Toggle() end
end
local function openRareTracker()
    LP:Hide()
    local ERT = ETB.ERT
    if ERT then
        if ERT.ToggleTracker then ERT:ToggleTracker()
        elseif ERT.ShowTracker then ERT:ShowTracker() end
    end
end

-- Central Plaza cards are built from the canonical feature registry
-- (Core/FeatureRegistry.lua) so the launcher, slash commands and tutorial all
-- share one list. Open actions are registered here (where the modules resolve)
-- so /etb <command> can open the same windows.
local FEATURE_ACTIONS = {
    transmog = openTransmogBrowser,
    outfits  = openTransmogPlanner,
    bis      = openRaidBiS,
    wishlist = openWishlist,
    planner  = openPlanner,
    tutorial = openTutorial,
    mounts   = openMounts,
    pets     = openPets,
    toys     = openToys,
    zonescan = openZoneScan,
    rares    = openRareTracker,
}

local FEATURES = {}
for _, f in ipairs(ETB.Features or {}) do
    local act = FEATURE_ACTIONS[f.id]
    if act then
        if ETB.FeatureRegistry then ETB.FeatureRegistry:SetAction(f.id, act) end
        FEATURES[#FEATURES + 1] = {
            title = f.title, color = f.color, desc = f.desc,
            model = f.model, action = act,
        }
    end
end

local TOTAL_PAGES = math.ceil(#FEATURES / CARDS_PER_PAGE)

-- ============================================================================
-- MODEL HELPER
-- ============================================================================
local function applyModel(model, spec)
    if not model or not spec then return end
    pcall(function() if model.ClearModel then model:ClearModel() end end)
    if spec.kind == "player" then
        pcall(function() model:SetUnit("player") end)
    elseif spec.kind == "display" and spec.display then
        pcall(function() model:SetDisplayInfo(spec.display) end)
    else
        local ok = false
        if spec.display then ok = pcall(function() model:SetDisplayInfo(spec.display) end) end
        if not ok and spec.npc then pcall(function() model:SetCreature(spec.npc) end) end
        -- Full-body framing so big models (dragons/phoenix) aren't cropped.
        pcall(function() if model.SetPortraitZoom then model:SetPortraitZoom(0) end end)
    end
    pcall(function() model:SetPosition(0, 0, 0) end)
    pcall(function() model:SetRotation(spec.rot or 0) end)
end

-- Which of the three slots to fill for a page holding `count` features
-- (centres a lone card on the final page).
local function slotsFor(count)
    if count == 1 then return { 2 }
    elseif count == 2 then return { 1, 3 }
    else return { 1, 2, 3 } end
end

-- ============================================================================
-- CARD CREATION  (generic, reused across pages)
-- ============================================================================
function LP:CreateCard(parent, xOffset)
    local card = CreateFrame("Frame", nil, parent, "BackdropTemplate")
    card:SetSize(CARD_WIDTH, CARD_HEIGHT)
    card:SetPoint("TOP", parent, "TOP", xOffset, -66)
    if card.SetBackdrop then
        card:SetBackdrop({
            bgFile = "Interface\\Collections\\CollectionsBackgroundTile",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 256, edgeSize = 12,
            insets = { left = 2, right = 2, top = 2, bottom = 2 },
        })
    end

    card.model = CreateFrame("DressUpModel", nil, card)
    card.model:SetSize(CARD_WIDTH - 8, CARD_HEIGHT - 84)
    card.model:SetPoint("TOP", 0, -4)
    card.model:EnableMouse(false)

    card.title = card:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    card.title:SetPoint("TOP", card.model, "BOTTOM", 0, -2)

    card.button = CreateFrame("Button", nil, card, "UIPanelButtonTemplate")
    card.button:SetSize(CARD_WIDTH - 16, 26)
    card.button:SetPoint("BOTTOM", 0, 8)

    card.desc = card:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    card.desc:SetPoint("BOTTOM", card.button, "TOP", 0, 4)
    card.desc:SetWidth(CARD_WIDTH - 20)
    card.desc:SetJustifyH("CENTER")
    card.desc:SetTextColor(0.6, 0.6, 0.6)

    card:EnableMouse(true)
    card:SetScript("OnMouseUp", function(self, btn)
        if btn == "LeftButton" and self._action then self._action() end
    end)
    card.button:SetScript("OnClick", function() if card._action then card._action() end end)

    card:Hide()
    return card
end

-- ============================================================================
-- POPULATE A CARD FROM A FEATURE
-- ============================================================================
local function fillCard(card, feature)
    if not card then return end
    if not feature then card:Hide(); return end
    card._action = feature.action
    card.title:SetText("|c" .. (feature.color or "ffffffff") .. feature.title .. "|r")
    card.button:SetText(feature.title)
    card.desc:SetText(feature.desc or "")
    applyModel(card.model, feature.model)
    card:Show()
end

-- ============================================================================
-- RENDER A PAGE
-- ============================================================================
function LP:RenderPage(page)
    if not self.frame then return end
    page = math.max(1, math.min(TOTAL_PAGES, page or 1))
    self.page = page

    local startIdx = (page - 1) * CARDS_PER_PAGE
    local pageFeatures = {}
    for i = 1, CARDS_PER_PAGE do
        local f = FEATURES[startIdx + i]
        if f then pageFeatures[#pageFeatures + 1] = f end
    end

    -- hide all slots first, then fill the chosen ones
    for i = 1, CARDS_PER_PAGE do self.frame.cards[i]:Hide() end
    local slots = slotsFor(#pageFeatures)
    for i, f in ipairs(pageFeatures) do
        fillCard(self.frame.cards[slots[i]], f)
    end

    self.frame.pageLabel:SetText(string.format("Page %d / %d", page, TOTAL_PAGES))
    self.frame.prevBtn:SetEnabled(page > 1)
    self.frame.nextBtn:SetEnabled(page < TOTAL_PAGES)
end

-- ============================================================================
-- CREATE
-- ============================================================================
function LP:Create()
    if self.frame then return self.frame end

    local f = CreateFrame("Frame", "ETBLauncherPanel", UIParent, "BackdropTemplate")
    f:SetSize(PANEL_WIDTH, PANEL_HEIGHT)
    f:SetPoint("CENTER", 0, 50)
    f:SetFrameStrata("DIALOG")
    f:SetFrameLevel(200)
    if f.SetBackdrop then
        f:SetBackdrop({
            bgFile = "Interface\\DialogFrame\\UI-DialogBox-Background-Dark",
            edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
            tile = true, tileSize = 32, edgeSize = 32,
            insets = { left = 8, right = 8, top = 8, bottom = 8 },
        })
    end
    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", f.StopMovingOrSizing)

    local title = f:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
    title:SetPoint("TOP", 0, -14)
    title:SetText("|cffffd100Enhanced Transmog Browser|r")

    local closeBtn = CreateFrame("Button", nil, f, "UIPanelCloseButton")
    closeBtn:SetPoint("TOPRIGHT", -2, -2)

    if UISpecialFrames then
        local already = false
        for _, name in ipairs(UISpecialFrames) do
            if name == "ETBLauncherPanel" then already = true; break end
        end
        if not already then tinsert(UISpecialFrames, "ETBLauncherPanel") end
    end

    f.statsText = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
    f.statsText:SetPoint("TOP", title, "BOTTOM", 0, -4)
    f.statsText:SetTextColor(0.6, 0.6, 0.6)

    -- three reusable model cards
    f.cards = {}
    local spacing = CARD_WIDTH + CARD_GAP
    f.cards[1] = self:CreateCard(f, -spacing)
    f.cards[2] = self:CreateCard(f, 0)
    f.cards[3] = self:CreateCard(f, spacing)

    -- page navigation
    f.prevBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    f.prevBtn:SetSize(96, 24)
    f.prevBtn:SetPoint("BOTTOMLEFT", 20, 14)
    f.prevBtn:SetText("< Prev")
    f.prevBtn:SetScript("OnClick", function() LP:RenderPage(LP.page - 1) end)

    f.nextBtn = CreateFrame("Button", nil, f, "UIPanelButtonTemplate")
    f.nextBtn:SetSize(96, 24)
    f.nextBtn:SetPoint("BOTTOMRIGHT", -20, 14)
    f.nextBtn:SetText("Next >")
    f.nextBtn:SetScript("OnClick", function() LP:RenderPage(LP.page + 1) end)

    f.pageLabel = f:CreateFontString(nil, "OVERLAY", "GameFontNormal")
    f.pageLabel:SetPoint("BOTTOM", 0, 18)

    self.frame = f
    return f
end

-- ============================================================================
-- SHOW / HIDE / TOGGLE
-- ============================================================================
function LP:Show()
    if not self.frame then self:Create() end

    if ETB.BlizzardData then
        local stats = ETB.BlizzardData:GetAllStats()
        local erbInfo = ""
        local ERB = ETB.ERB
        if ERB and ERB.DataBridge and ERB.DataBridge.playerSpecName then
            erbInfo = string.format(" | |cff00ccffBiS:|r %s %s (%d items)",
                ERB.DataBridge.playerSpecName,
                ERB.DataBridge:GetSourceLabel(ERB.DataBridge.activeSource) or "",
                ERB.DataBridge.itemCount or 0)
        end
        if stats and stats.total > 0 then
            self.frame.statsText:SetText(string.format(
                "Collection: |cff00ff00%s|r / %s appearances (|cffffff00%.1f%%|r)%s",
                ETB:FormatNumber(stats.collected),
                ETB:FormatNumber(stats.total),
                stats.percent,
                erbInfo))
        end
    end

    self:RenderPage(self.page or 1)
    self.frame:Show()
end

function LP:Hide()
    if self.frame then self.frame:Hide() end
end

function LP:Toggle()
    if self.frame and self.frame:IsShown() then
        self:Hide()
    else
        self:Show()
    end
end

ETB:Debug("LauncherPanel", "LauncherPanel.lua (central plaza) loaded")
