-- Enhanced Raid Browser — Init (merged into EnhancedTransmogBrowser in v12.40.3)
-- Handles player detection, equipment scanning, spec switching, and UI toggle.
local ADDON_NAME, NS = ...
local ETB = NS.ETB
if not ETB then
    error("[ETB/ERB] NS.ETB missing — Init.lua load order wrong. " ..
          "ERB/Init.lua must load after Core/Init.lua in the TOC.")
end

-- Create ERB namespace under ETB.
ETB.ERB = ETB.ERB or {}
local ERB = ETB.ERB

ERB.version = "0.4.0"  -- First merged release (was 0.3.2 as standalone)

-- ============================================================================
-- PLAYER INFO
-- ============================================================================

function ERB:GetPlayerInfo()
    local _, englishClass, classID = UnitClass("player")

    local specIndex = GetSpecialization and GetSpecialization() or 0
    local specName = ""
    local specIcon = nil
    local specRole = ""
    if specIndex and specIndex > 0 and GetSpecializationInfo then
        local id, name, _, icon, role = GetSpecializationInfo(specIndex)
        specName = name or ""
        specIcon = icon
        specRole = role or ""
    end

    -- MoP Classic fallback: GetSpecialization() returns 0.
    -- Detect spec by checking for spec-defining spells via IsPlayerSpell().
    if (not specIndex or specIndex == 0) and IsPlayerSpell then
        local SPEC_SPELLS = {
            -- [wowClassID] = { {spellID, specName, wowSpecIndex}, ... }
            -- One unique spell per spec that only that spec learns in MoP 5.4.8
            [1] = { -- Warrior
                {12294, "Arms", 1},         -- Mortal Strike
                {23881, "Fury", 2},         -- Bloodthirst
                {23922, "Protection", 3},   -- Shield Slam
            },
            [2] = { -- Paladin
                {20473, "Holy", 1},         -- Holy Shock
                {31935, "Protection", 2},   -- Avenger's Shield
                {85256, "Retribution", 3},  -- Templar's Verdict
            },
            [3] = { -- Hunter
                {34026, "Beast Mastery", 1}, -- Kill Command
                {53209, "Marksmanship", 2},  -- Chimera Shot
                {53301, "Survival", 3},      -- Explosive Shot
            },
            [4] = { -- Rogue
                {1329, "Assassination", 1},  -- Mutilate
                {51690, "Combat", 2},        -- Killing Spree
                {51713, "Subtlety", 3},      -- Shadow Dance
            },
            [5] = { -- Priest
                {47540, "Discipline", 1},    -- Penance
                {34861, "Holy", 2},          -- Circle of Healing
                {15473, "Shadow", 3},        -- Shadowform
            },
            [6] = { -- Death Knight
                {49028, "Blood", 1},         -- Dancing Rune Weapon
                {51271, "Frost", 2},         -- Pillar of Frost
                {49206, "Unholy", 3},        -- Summon Gargoyle
            },
            [7] = { -- Shaman
                {51505, "Elemental", 1},     -- Lava Burst
                {17364, "Enhancement", 2},   -- Stormstrike
                {61295, "Restoration", 3},   -- Riptide
            },
            [8] = { -- Mage
                {30451, "Arcane", 1},        -- Arcane Blast
                {108853, "Fire", 2},         -- Inferno Blast
                {31687, "Frost", 3},         -- Summon Water Elemental
            },
            [9] = { -- Warlock
                {30108, "Affliction", 1},    -- Unstable Affliction
                {103958, "Demonology", 2},   -- Metamorphosis
                {116858, "Destruction", 3},  -- Chaos Bolt
            },
            [10] = { -- Monk
                {121253, "Brewmaster", 1},   -- Keg Smash
                {115175, "Mistweaver", 2},   -- Soothing Mist
                {113656, "Windwalker", 3},   -- Fists of Fury
            },
            [11] = { -- Druid
                {24858, "Balance", 1},       -- Moonkin Form
                {5217, "Feral", 2},          -- Tiger's Fury
                {62606, "Guardian", 3},      -- Savage Defense
                {18562, "Restoration", 4},   -- Swiftmend
            },
        }
        local classSpells = SPEC_SPELLS[classID]
        if classSpells then
            for _, entry in ipairs(classSpells) do
                if IsPlayerSpell(entry[1]) then
                    specIndex = entry[3]
                    specName = entry[2]
                    -- Try to get icon from GetSpecializationInfo if available
                    if GetSpecializationInfo then
                        local ok, _, _, _, icon = pcall(GetSpecializationInfo, specIndex)
                        if ok and icon then specIcon = icon end
                    end
                    break
                end
            end
        end
    end

    local classColor = "|cffffffff"
    if RAID_CLASS_COLORS and RAID_CLASS_COLORS[englishClass] then
        local c = RAID_CLASS_COLORS[englishClass]
        classColor = string.format("|cff%02x%02x%02x", c.r*255, c.g*255, c.b*255)
    end

    return {
        name = UnitName("player") or "Unknown",
        realm = GetRealmName and GetRealmName() or "",
        level = UnitLevel("player") or 0,
        class = englishClass,
        className = UnitClass("player"),
        classID = classID,
        classColor = classColor,
        specIndex = specIndex,
        specName = specName,
        specIcon = specIcon,
        specRole = specRole,
    }
end

-- ============================================================================
-- EQUIPMENT SCANNER
-- ============================================================================

ERB.INV_SLOT_MAP = {
    [1]="Head",[2]="Neck",[3]="Shoulder",[5]="Chest",[6]="Waist",
    [7]="Legs",[8]="Feet",[9]="Wrist",[10]="Hands",
    [11]="Finger",[12]="Finger",[13]="Trinket",[14]="Trinket",
    [15]="Back",[16]="Weapon",[17]="Off hand",[18]="Ranged",
}

function ERB:ScanEquipment()
    local equipped = {}
    for invSlot, slotName in pairs(self.INV_SLOT_MAP) do
        local itemID = GetInventoryItemID("player", invSlot)
        if itemID then
            local itemLink = GetInventoryItemLink("player", invSlot)
            local name, _, quality, ilvl, _, _, _, _, _, icon = GetItemInfo(itemID)
            if not equipped[slotName] then equipped[slotName] = {} end
            equipped[slotName][#equipped[slotName] + 1] = {
                invSlot = invSlot, itemID = itemID, itemLink = itemLink,
                name = name or "Loading...", quality = quality or 0,
                ilvl = ilvl or 0, icon = icon,
            }
        end
    end
    return equipped
end

function ERB:GetEquippedIlvl()
    local total, count = 0, 0
    for invSlot = 1, 18 do
        local itemID = GetInventoryItemID("player", invSlot)
        if itemID then
            local _, _, _, ilvl = GetItemInfo(itemID)
            if ilvl and ilvl > 0 then total = total + ilvl; count = count + 1 end
        end
    end
    return count > 0 and math.floor(total / count) or 0
end

function ERB:GetNPCIDFromGUID(guid)
    if not guid then return nil end
    local unitType, _, _, _, _, npcID = strsplit("-", guid)
    if unitType == "Creature" or unitType == "Vehicle" then
        return tonumber(npcID)
    end
    return nil
end

-- ============================================================================
-- INITIALIZATION (called from ETB's PLAYER_LOGIN)
-- ============================================================================

function ERB:OnPlayerLogin()
    if ERB.DataBridge then
        ERB.DataBridge:Initialize()
    end
    -- v15.7.0: CustomBiS depends on DataBridge.playerClassIdx/playerSpecIdx,
    -- so it must run AFTER DataBridge:Initialize. SavedVariables are already
    -- loaded by PLAYER_LOGIN.
    if ERB.CustomBiS then
        ERB.CustomBiS:Initialize()
    end
    if ERB.BossTooltip then
        ERB.BossTooltip:Initialize()
    end
    ERB.equipped = ERB:ScanEquipment()
    ERB.initialized = true
end

-- ============================================================================
-- SPEC/EQUIPMENT CHANGE EVENTS
-- ============================================================================

local erbEventFrame = CreateFrame("Frame")
erbEventFrame:RegisterEvent("PLAYER_LOGIN")

erbEventFrame:SetScript("OnEvent", function(_, event)
    if event == "PLAYER_LOGIN" then
        -- Initialize immediately — BiSData is already loaded from TOC.
        -- GetSpecialization() often returns nil at login.
        -- DataBridge will fall back to first spec; we re-detect on PLAYER_ENTERING_WORLD.
        ERB:OnPlayerLogin()
        erbEventFrame:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
        erbEventFrame:RegisterEvent("PLAYER_TALENT_UPDATE")
        erbEventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
        erbEventFrame:RegisterEvent("PLAYER_EQUIPMENT_CHANGED")
    elseif event == "PLAYER_ENTERING_WORLD" then
        -- Spec API may not be ready immediately. Retry with delay.
        if ERB.initialized and ERB.DataBridge then
            -- Try immediately
            local function retrySpecDetect()
                if not ERB.DataBridge then return end
                if ERB.DataBridge.specAutoDetected then return end -- already got it
                local currentSpec = ERB.DataBridge.playerSpecName
                ERB.DataBridge:Initialize()
                ERB.equipped = ERB:ScanEquipment()
                if ERB.DataBridge.playerSpecName ~= currentSpec then
                    if ERB.MainFrame and ERB.MainFrame:IsShown() then
                        ERB.MainFrame:Refresh()
                        ERB.MainFrame:SelectSlot(ERB.DataBridge.currentSlot or "Head")
                    end
                end
            end
            retrySpecDetect()
            -- If still not auto-detected, retry after delays
            if not ERB.DataBridge.specAutoDetected then
                C_Timer.After(1, retrySpecDetect)
            end
            if not ERB.DataBridge.specAutoDetected then
                C_Timer.After(3, retrySpecDetect)
            end
        end
    elseif event == "ACTIVE_TALENT_GROUP_CHANGED" or event == "PLAYER_TALENT_UPDATE" then
        if ERB.initialized and ERB.DataBridge then
            local prevSpec = ERB.DataBridge.playerSpecName
            ERB.DataBridge:Initialize()
            ERB.equipped = ERB:ScanEquipment()
            if ERB.MainFrame and ERB.MainFrame:IsShown() then
                ERB.MainFrame:Refresh()
                ERB.MainFrame:SelectSlot(ERB.DataBridge.currentSlot or "Head")
            end
        end
    elseif event == "PLAYER_EQUIPMENT_CHANGED" then
        if ERB.initialized then
            ERB.equipped = ERB:ScanEquipment()
            if ERB.MainFrame and ERB.MainFrame:IsShown() then
                ERB.MainFrame:UpdateDisplay()
            end
        end
    end
end)

-- ============================================================================
-- UI MODE TOGGLE — switch between ETB transmog browser and ERB raid browser
-- ============================================================================

ETB.uiMode = "transmog"  -- "transmog" or "raid"

function ETB:ToggleUIMode()
    if self.uiMode == "transmog" then
        -- Switch to ERB raid browser
        if self.MainFrame and self.MainFrame.frame then
            self.MainFrame.frame:Hide()
        end
        self.uiMode = "raid"
        if ERB.MainFrame then
            ERB.MainFrame:Toggle()
        end
    else
        -- Switch to ETB transmog browser
        if ERB.MainFrame and ERB.MainFrame.frame then
            ERB.MainFrame.frame:Hide()
        end
        self.uiMode = "transmog"
        if self.MainFrame and self.MainFrame.frame then
            self.MainFrame.frame:Show()
            self.MainFrame:UpdateDisplay()
        end
    end
end

-- ============================================================================
-- SLASH COMMANDS
-- ============================================================================

SLASH_ERB1 = "/erb"
SlashCmdList["ERB"] = function(msg)
    msg = strtrim(msg):lower()

    if msg == "" or msg == "show" or msg == "browser" then
        if ERB.MainFrame then
            ERB.MainFrame:Toggle()
        end
    elseif msg == "source" or msg == "switch" then
        if ERB.DataBridge then
            ERB.DataBridge:CycleSource()
            ERB.equipped = ERB:ScanEquipment()
            if ERB.MainFrame and ERB.MainFrame:IsShown() then
                ERB.MainFrame:Refresh()
                ERB.MainFrame:SelectSlot(ERB.DataBridge.currentSlot or "Head")
            end
        end
    elseif msg == "status" then
        local info = ERB:GetPlayerInfo()
        local avgIlvl = ERB:GetEquippedIlvl()
        print("|cff00ccff[ERB]|r Status:")
        print("  Character: " .. (info.classColor or "") .. (info.name or "?") .. "|r")
        print("  Class: " .. (info.classColor or "") .. (info.className or "?") .. "|r")
        if ERB.DataBridge then
            print("  Spec: " .. (ERB.DataBridge.playerSpecName or info.specName or "?"))
            print("  Avg ilvl: " .. avgIlvl)
            local srcLabel = ERB.DataBridge:GetSourceLabel(ERB.DataBridge.activeSource)
            print("  Source: " .. (srcLabel or "?") .. " (" .. ERB.DataBridge:GetBiSCount() .. " items)")
            print("  Boss mappings: " .. ERB.DataBridge:CountNPCMappings())
            for _, key in ipairs(ERB.DataBridge:GetAvailableSources()) do
                local label = ERB.DataBridge:GetSourceLabel(key)
                local tag = (key == ERB.DataBridge.activeSource) and " |cff00ff00(active)|r" or ""
                print("    " .. label .. tag)
            end
        end
    elseif msg:find("^spec") then
        if not ERB.DataBridge then return end
        local specArg = msg:match("^spec%s+(%d+)")
        local specs = ERB.DataBridge:GetAvailableSpecs()
        if specArg then
            local idx = tonumber(specArg)
            if idx and specs[idx] then
                ERB.DataBridge:SwitchSpec(specs[idx].idx)
                ERB.equipped = ERB:ScanEquipment()
                if ERB.MainFrame and ERB.MainFrame:IsShown() then
                    ERB.MainFrame:Refresh()
                    ERB.MainFrame:SelectSlot(ERB.DataBridge.currentSlot or "Head")
                end
            end
        else
            local info = ERB:GetPlayerInfo()
            print("|cff00ccff[ERB]|r Specs for " .. (info.classColor or "") .. (info.className or "?") .. "|r:")
            for i, spec in ipairs(specs) do
                local tag = spec.isActive and " |cff00ff00(active)|r" or ""
                print("  " .. i .. ". " .. spec.name .. tag)
            end
        end
    elseif msg == "help" then
        print("|cff00ccff[ERB]|r Commands:")
        print("  /erb — Toggle raid browser")
        print("  /erb source — Switch WoWHead / WoWTBC lists")
        print("  /erb spec — List specs / /erb spec [n] to switch")
        print("  /erb status — Show stats")
        print("  /erb diag — Diagnostic info")
    elseif msg == "diag" then
        print("|cff00ccff[ERB]|r Diagnostic:")
        print("  ERB.BiSData: " .. (ERB.BiSData and "loaded" or "|cffff4444MISSING|r"))
        print("  ERB.Sources: " .. (ERB.Sources and table.concat(ERB.Sources, ", ") or "|cffff4444MISSING|r"))
        print("  ERB.ItemBossMap: " .. (ERB.ItemBossMap and "loaded" or "|cffff4444MISSING|r"))
        print("  ERB.BossNames: " .. (ERB.BossNames and "loaded" or "|cffff4444MISSING|r"))
        if ERB.DataBridge then
            print("  DataBridge.activeSource: " .. tostring(ERB.DataBridge.activeSource))
            print("  DataBridge.playerClassIdx: " .. tostring(ERB.DataBridge.playerClassIdx))
            print("  DataBridge.playerSpecIdx: " .. tostring(ERB.DataBridge.playerSpecIdx))
            print("  DataBridge.playerSpecName: " .. tostring(ERB.DataBridge.playerSpecName))
            print("  DataBridge.specAutoDetected: " .. tostring(ERB.DataBridge.specAutoDetected))
            -- Show what WoW API currently returns
            local wowSpecIdx = GetSpecialization and GetSpecialization() or 0
            local wowSpecName = ""
            if wowSpecIdx and wowSpecIdx > 0 and GetSpecializationInfo then
                local _, name = GetSpecializationInfo(wowSpecIdx)
                wowSpecName = name or ""
            end
            print("  WoW GetSpecialization(): " .. tostring(wowSpecIdx) .. " (" .. wowSpecName .. ")")
            -- Show spell-based detection
            local info = ERB:GetPlayerInfo()
            print("  Spell-based spec: " .. tostring(info.specIndex) .. " (" .. (info.specName or "?") .. ")")
            -- Init status — shows which early-return (if any) Initialize hit, or "ok".
            -- Blank means Initialize() has never been called this session.
            local status = ERB.DataBridge.initStatus
            if status == "ok" then
                print("  Initialize status: |cff00ff00ok|r")
            elseif status then
                print("  Initialize status: |cffff6666" .. status .. "|r")
            else
                print("  Initialize status: |cffff4444never ran|r")
            end
            print("  DataBridge.currentPhase: " .. tostring(ERB.DataBridge:GetCurrentPhase()))
            print("  DataBridge.itemCount: " .. tostring(ERB.DataBridge.itemCount))
            -- Count npcIndex
            local npcCount = 0
            local npcItemCount = 0
            for npcID, items in pairs(ERB.DataBridge.npcIndex) do
                npcCount = npcCount + 1
                for _ in pairs(items) do npcItemCount = npcItemCount + 1 end
            end
            print("  npcIndex: " .. npcCount .. " NPCs, " .. npcItemCount .. " items")
            -- Count slotData
            local slotCount = 0
            local totalItems = 0
            for slot, phases in pairs(ERB.DataBridge.slotData) do
                for phase, items in pairs(phases) do
                    slotCount = slotCount + 1
                    totalItems = totalItems + #items
                end
            end
            print("  slotData: " .. slotCount .. " slot/phase combos, " .. totalItems .. " total entries")
        else
            print("  DataBridge: |cffff4444NOT INITIALIZED|r")
        end
        if ERB.BossTooltip then
            print("  BossTooltip._initialized: " .. tostring(ERB.BossTooltip._initialized))
        end
        print("  ERB.initialized: " .. tostring(ERB.initialized))
    end
end
