-- ============================================================================
-- Vamoose's Companion - Init
-- Addon initialization, lifecycle, and slash commands
-- ============================================================================

VC = VC or {}
_G.VamoosesCompanion = VC

VC.frame = CreateFrame("Frame")
VC.frame:RegisterEvent("ADDON_LOADED")
VC.frame:RegisterEvent("PLAYER_LOGIN")
VC.frame:RegisterEvent("PLAYER_LOGOUT")

-- ============================================================================
-- LIFECYCLE
-- ============================================================================

function VC:OnInitialize()
    VC_DB = VC_DB or {}
    VC.Store:LoadFromSavedVariables()
    VC.Constants:ApplyTheme()

    if VC.Theme and VC.Theme.Initialize then
        VC.Theme:Initialize()
    end

    -- Apply locale quote overrides
    VC:ApplyLocaleQuotes()

    local version = C_AddOns.GetAddOnMetadata("VamoosesCompanion", "Version") or "Dev"
    if VC.Store:GetState().config.debug then
        print("|cFFA0522D[VC]|r Vamoose's Companion v" .. version .. " loaded. Type /vc for help.")
    end
end

function VC:OnEnable()
    VC._sessionStart = GetTime()
    VC.EventBus:Trigger("VC_ADDON_ENABLED")

    -- Populate Murgle's missing categories from Scurry quotes
    if VC.NerglishGen and VC.NerglishGen.PopulateMurgleFromScurry then
        VC.NerglishGen:PopulateMurgleFromScurry()
    end

    -- Initialize modules
    if VC.Collectors and VC.Collectors.Initialize then
        VC.Collectors:Initialize()
    end
    if VC.ActivitySense and VC.ActivitySense.Initialize then
        VC.ActivitySense:Initialize()
    end
    if VC.Memory and VC.Memory.Initialize then
        VC.Memory:Initialize()
    end
    if VC.Engine and VC.Engine.Initialize then
        VC.Engine:Initialize()
    end
    if VC.Mood and VC.Mood.Initialize then
        VC.Mood:Initialize()
    end
    if VC.Bonding and VC.Bonding.Initialize then
        VC.Bonding:Initialize()
    end

    -- Pet Summoner (before Portrait — validates linked pet state)
    if VC.PetSummoner and VC.PetSummoner.Initialize then
        VC.PetSummoner:Initialize()
    end

    -- Initialize UI
    if VC.Display and VC.Display.Initialize then
        VC.Display:Initialize()
    end
    if VC.Portrait and VC.Portrait.Initialize then
        VC.Portrait:Initialize()
    end
    if VC.AuraLighting and VC.AuraLighting.Initialize then
        VC.AuraLighting:Initialize()
    end
    if VC.Settings and VC.Settings.Initialize then
        VC.Settings:Initialize()
    end
    if VC.Mascot and VC.Mascot.Initialize then
        VC.Mascot:Initialize()
    end
end

-- ============================================================================
-- LOCALE QUOTE SWITCHING
-- ============================================================================

-- Backup English quotes on first call (exposed on VC for review tool access)
VC._enQuoteBackup = {}

function VC:ApplyLocaleQuotes()
    local state = VC.Store:GetState()
    local setting = state.config.localeQuotes or "auto"
    local clientLocale = GetLocale()
    local effective = setting
    if setting == "auto" then effective = clientLocale end

    -- Backup English on first run
    if not VC._enQuoteBackup.scurry and VC_QuoteDB and VC_QuoteDB.scurry then
        VC._enQuoteBackup.scurry = VC_QuoteDB.scurry
    end

    -- Apply locale override
    local localeDBs = {
        deDE = VC_QuoteDB_deDE,
        ptBR = VC_QuoteDB_ptBR,
    }
    local localeDB = localeDBs[effective]
    if localeDB and localeDB.scurry then
        VC_QuoteDB.scurry = localeDB.scurry
    elseif VC._enQuoteBackup.scurry then
        VC_QuoteDB.scurry = VC._enQuoteBackup.scurry
    end
end

-- Event Handler
VC.frame:SetScript("OnEvent", function(self, event, arg1)
    if event == "ADDON_LOADED" and arg1 == "VamoosesCompanion" then
        VC:OnInitialize()
        self:UnregisterEvent("ADDON_LOADED")
    elseif event == "PLAYER_LOGIN" then
        self:UnregisterEvent("PLAYER_LOGIN")
        C_Timer.After(5, function() VC:OnEnable() end)
    elseif event == "PLAYER_LOGOUT" then
        VC.Store:Flush()
    end
end)

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

SLASH_VC1 = "/vc"
SLASH_VC2 = "/companion"
SlashCmdList["VC"] = function(msg)
    local command = msg:lower():match("^(%S*)")
    local arg = msg:lower():match("^%S+%s+(.*)")

    if command == "" or command == "help" then
        print("|cFFA0522D[VC]|r Commands:")
        print("  /vc mute - Toggle mute")
        print("  /vc chattiness [1-4] - Set chattiness (1=minimal, 4=maximum)")
        print("  /vc mode [bubble|chat] - Display mode")
        print("  /vc toggle <type> - Toggle event type (farming/gold/achieve/death/ambient/quest/boss/levelup/rep/zone/login)")
        print("  /vc test [type] - Force a test quote")
        print("  /vc status - Show current settings")
        print("  /vc companion <name> - Switch companion (vamoose/scurry/gazlowe/patches)")
        print("  /vc portrait - Toggle portrait")
        print("  /vc reset - Reset portrait position")
        print("  /vc mood - Show current mood")
        print("  /vc bond - Show bonding level")
        print("  /vc settings - Open settings panel")
        print("  /vc theme - Cycle themes")
        print("  /vc debug - Toggle debug mode")

    elseif command == "settings" then
        if VC.Settings and VC.Settings.Toggle then
            VC.Settings:Toggle()
        end

    elseif command == "mute" then
        local state = VC.Store:GetState()
        local newMuted = not state.config.muted
        VC.Store:Dispatch("SET_MUTED", { muted = newMuted })
        print("|cFFA0522D[VC]|r " .. (newMuted and "Muted" or "Unmuted"))

    elseif command == "chattiness" then
        local level = tonumber(arg)
        if level and level >= 1 and level <= 4 then
            VC.Store:Dispatch("SET_CHATTINESS", { level = level })
            local tier = VC.Constants.CHATTINESS[level]
            print("|cFFA0522D[VC]|r Chattiness: " .. tier.label)
        else
            local current = VC.Store:GetState().config.chattiness
            print("|cFFA0522D[VC]|r Chattiness: " .. VC.Constants.CHATTINESS[current].label .. " (" .. current .. "/4)")
            print("  Usage: /vc chattiness <1-4>")
        end

    elseif command == "mode" then
        if arg == "bubble" or arg == "chat" then
            VC.Store:Dispatch("TOGGLE_DISPLAY_MODE", { mode = arg })
            local modes = VC.Store:GetState().config.displayModes
            print("|cFFA0522D[VC]|r Mode " .. arg .. ": " .. (modes[arg] and "ON" or "OFF"))
        else
            local modes = VC.Store:GetState().config.displayModes or {}
            local active = {}
            if modes.bubble then active[#active + 1] = "bubble" end
            if modes.chat then active[#active + 1] = "chat" end
            print("|cFFA0522D[VC]|r Display modes: " .. (#active > 0 and table.concat(active, " + ") or "none"))
            print("  Usage: /vc mode [bubble|chat]")
        end

    elseif command == "toggle" then
        if arg and VC.Constants.CATEGORY_COOLDOWNS[arg] then
            local state = VC.Store:GetState()
            local current = state.config.eventToggles[arg]
            VC.Store:Dispatch("SET_EVENT_TOGGLE", { eventType = arg, enabled = not current })
            print("|cFFA0522D[VC]|r " .. arg .. " quotes: " .. (not current and "ON" or "OFF"))
        else
            print("|cFFA0522D[VC]|r Usage: /vc toggle <farming|gold|achieve|death|ambient>")
        end

    elseif command == "test" then
        -- arg may be "home <tag>" to exercise a specific presence bucket,
        -- e.g. "/vc test home idle_house" or "/vc test home enter_plot".
        local eventType, sub = (arg or "ambient"):match("^(%S+)%s*(%S*)")
        eventType = eventType or "ambient"
        local context = {}
        if eventType == "home" then
            local tag = (sub ~= "" and sub) or "enter_house"
            context.homeTag = tag
            if tag == "enter_house" then context.homeEntry = "first" end
        end
        if VC.Engine and VC.Engine.ProcessEvent then
            VC.Engine:ProcessEvent({
                eventType = eventType,
                intensity = VC.Constants.INTENSITY.HIGH,
                context = context,
                timestamp = GetTime(),
                source = "SLASH_TEST",
            })
        else
            print("|cFFA0522D[VC]|r Engine not loaded")
        end

    elseif command == "status" then
        local s = VC.Store:GetState()
        local tier = VC.Constants.CHATTINESS[s.config.chattiness]
        local comp = VC_CompanionProfiles and VC_CompanionProfiles[s.config.activeCompanion]
        local dm = s.config.displayModes or {}
        local dmParts = {}
        if dm.bubble then dmParts[#dmParts + 1] = "bubble" end
        if dm.chat then dmParts[#dmParts + 1] = "chat" end
        local bondInfo = VC.Bonding and VC.Bonding:GetLevelInfo() or {}
        local moodStr = VC.Mood and VC.Mood:GetMood() or "N/A"

        print("|cFFA0522D[VC]|r Status:")
        print(format("  Companion: %s | %s | %s | History: %d/%d",
            comp and comp.name or s.config.activeCompanion,
            s.config.muted and "MUTED" or tier.label,
            #dmParts > 0 and table.concat(dmParts, "+") or "none",
            #s.quoteHistory, VC.Constants.HISTORY_MAX))
        print(format("  Mood: %s | Bond: %s (%d) | Streak: %dd",
            moodStr, bondInfo.name or "?", bondInfo.rapport or 0, bondInfo.streakDays or 0))

        -- Lifetime counts
        local c = s.memory and s.memory.lifetimeCounts or {}
        print(format("  Counts: %d boss, %d death, %d quest, %d achieve, %d M+",
            c.bossKills or 0, c.deaths or 0, c.questsCompleted or 0,
            c.achievementsEarned or 0, c.mythicPlusCompleted or 0))
        print(format("          %d fish, %d crits, %d zones, %d sessions, %sg earned",
            c.fishCaught or 0, c.craftingCrits or 0, c.zonesVisited or 0,
            c.sessionCount or 0,
            c.goldEarned and format("%.1fk", c.goldEarned / 10000) or "0"))

        -- Milestones fired
        local fired = s.memory and s.memory.milestonesFired or {}
        local streakFired = s.memory and s.memory.streakMilestonesFired or {}
        local msList = {}
        for k in pairs(fired) do msList[#msList + 1] = k end
        for k in pairs(streakFired) do msList[#msList + 1] = k end
        if #msList > 0 then
            table.sort(msList)
            print("  Milestones: " .. table.concat(msList, ", "))
        end

        -- Event toggles (compact: only show OFF ones)
        local off = {}
        for k, v in pairs(s.config.eventToggles) do
            if not v then off[#off + 1] = k end
        end
        if #off > 0 then
            table.sort(off)
            print("  Disabled: " .. table.concat(off, ", "))
        end

    elseif command == "companion" then
        if arg and VC_CompanionProfiles and VC_CompanionProfiles[arg] and VC_QuoteDB and VC_QuoteDB[arg] then
            VC.Store:Dispatch("SET_CONFIG", { key = "activeCompanion", value = arg })
            if VC.Portrait and VC.Portrait.UpdateModel then
                VC.Portrait:UpdateModel()
            end
            local profile = VC_CompanionProfiles[arg]
            print("|cFFA0522D[VC]|r Companion: " .. profile.name .. " - " .. profile.title)
        else
            local current = VC.Store:GetState().config.activeCompanion
            local names = {}
            for k in pairs(VC_CompanionProfiles or {}) do
                if VC_QuoteDB and VC_QuoteDB[k] then table.insert(names, k) end
            end
            print("|cFFA0522D[VC]|r Companion: " .. current)
            print("  Available: " .. table.concat(names, ", "))
        end

    elseif command == "portrait" then
        local s = VC.Store:GetState()
        local newShown = not s.ui.portraitShown
        VC.Store:Dispatch("SET_PORTRAIT_SHOWN", { shown = newShown })
        if VC.Portrait and VC.Portrait.frame then
            VC.Portrait.frame:SetShown(newShown)
        end
        print("|cFFA0522D[VC]|r Portrait " .. (newShown and "shown" or "hidden"))

    elseif command == "reset" then
        VC_DB = {}
        VC.Store:ResetToDefaults()
        if VC.Portrait and VC.Portrait.frame then
            VC.Portrait.frame:ClearAllPoints()
            VC.Portrait.frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 20, -200)
            VC.Portrait:UpdateModel(true)
        end
        print("|cFFA0522D[VC]|r All saved variables reset. /reload recommended.")

    elseif command == "theme" then
        local newTheme = VC.Constants:ToggleTheme()
        local displayName = VC.Constants.ThemeDisplayNames[newTheme] or newTheme
        VC.EventBus:Trigger("VC_THEME_UPDATE", {
            themeName = VC.Constants.ThemeNames[newTheme]
        })
        print("|cFFA0522D[VC]|r Theme: " .. displayName)

    elseif command == "mood" then
        local mood = VC.Mood and VC.Mood:GetMood() or "N/A"
        local intensity = VC.Mood and VC.Mood:GetIntensity() or 0
        local mc = VC.Constants.MOOD_COLORS[mood] or VC.Constants.MOOD_COLORS.NEUTRAL
        local hex = format("%02x%02x%02x", -- floats truncate in %x: 0.6*255=152.99 -> 152, one shade off
            math.floor(mc.r * 255 + 0.5), math.floor(mc.g * 255 + 0.5), math.floor(mc.b * 255 + 0.5))
        print(format("|cFFA0522D[VC]|r Mood: |cFF%s%s|r (%.2f)", hex, mood, intensity))

    elseif command == "bond" then
        local info = VC.Bonding and VC.Bonding:GetLevelInfo()
        if info then
            local next = info.nextThreshold and tostring(info.nextThreshold) or "Max"
            print(format("|cFFA0522D[VC]|r Bond: %s (%d/%s)", info.name, info.rapport, next))
            if info.streakDays > 1 then
                print(format("  Login streak: %d days", info.streakDays))
            end
        else
            print("|cFFA0522D[VC]|r Bonding not initialized")
        end

    elseif command == "models" then
        if VC.ModelViewer then VC.ModelViewer:Toggle() end

    elseif command == "anim" then
        local animID = tonumber(arg)
        if animID then
            -- Try on model viewer selected model first, then portrait
            local target = VC.ModelViewer and VC.ModelViewer._selectedModel
            if target then
                target:SetAnimation(animID)
                print("|cFFA0522D[VC]|r Playing anim " .. animID .. " on model viewer selection")
            elseif VC.Portrait and VC.Portrait.frame and VC.Portrait.frame.model then
                VC.Portrait.frame.model:SetAnimation(animID)
                print("|cFFA0522D[VC]|r Playing anim " .. animID .. " on portrait")
            end
        else
            print("|cFFA0522D[VC]|r Usage: /vc anim <id> (e.g. /vc anim 135)")
        end

    elseif command == "scene" then
        -- Test ModelScene rendering with shared helpers
        local displayID = tonumber(arg)
        if not displayID then
            local comp = VC_CompanionProfiles[VC.Store:GetState().config.activeCompanion]
            displayID = comp and comp.displayID or 36894
        end
        if not VC._testScene then
            local f = CreateFrame("Frame", "VC_SceneTest", UIParent, "BackdropTemplate")
            f:SetSize(300, 300)
            f:SetPoint("CENTER")
            f:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8x8", edgeFile = "Interface\\Buttons\\WHITE8x8", edgeSize = 1 })
            f:SetBackdropColor(0.1, 0.1, 0.1, 1)
            f:SetBackdropBorderColor(1, 1, 1, 0.5)
            f:SetFrameStrata("DIALOG")
            f:EnableMouse(true)
            f:SetMovable(true)
            f:RegisterForDrag("LeftButton")
            f:SetScript("OnDragStart", f.StartMoving)
            f:SetScript("OnDragStop", f.StopMovingOrSizing)
            f.scene = VC.UI:CreateModelScene(f, 0)
            f.scene:SetAllPoints(f)
            f.scene:SetFrameLevel(f:GetFrameLevel() + 1)
            local dbg = f:CreateFontString(nil, "OVERLAY", "GameFontNormalSmall")
            dbg:SetPoint("TOPLEFT", 5, -5)
            f.dbg = dbg
            local close = CreateFrame("Button", nil, f, "UIPanelCloseButton")
            close:SetPoint("TOPRIGHT", 2, 2)
            VC._testScene = f
        end
        local f = VC._testScene
        f:Show()
        local did = displayID
        VC.UI:SetCreatureOnScene(f.scene, displayID, {
            scale = 1.0,
            onLoaded = function(a)
                local ba, bb, bc, bd, be, bf = a:GetActiveBoundingBox()
                if ba then
                    local sw, sh = f.scene:GetSize() -- floats; %.0f instead of %d
                    f.dbg:SetText(format("ID:%d h:%.2f w:%.2f d:%.2f\nscale:%.2f frame:%.0fx%.0f",
                        did, bf - bc, be - bb, bd - ba, a:GetScale(), sw, sh))
                else
                    f.dbg:SetText(format("ID:%d NO BBOX", did))
                end
            end,
        })
        print(format("|cFFA0522D[VC]|r Scene test: displayID %d", displayID))

    elseif command == "debug" then
        local state = VC.Store:GetState()
        VC.Store:Dispatch("SET_CONFIG", { key = "debug", value = not state.config.debug })
        local newDebug = VC.Store:GetState().config.debug
        print("|cFFA0522D[VC]|r Debug: " .. (newDebug and "ON" or "OFF"))
        if VC.Portrait and VC.Portrait.frame and VC.Portrait.frame.model then
            VC.Portrait:UpdateDebugText(VC.Portrait.frame.model, nil, "Debug")
        end

    elseif command == "murgle" then
        if VC.NerglishGen then VC.NerglishGen:HandleSlash() end

    else
        print("|cFFA0522D[VC]|r Unknown command. Type /vc for help.")
    end
end

-- ============================================================================
-- ADDON COMPARTMENT (referenced by TOC AddonCompartmentFunc directives).
-- Blizzard registers the entry from the TOC at PLAYER_ENTERING_WORLD using
-- ## Title as the text and ## IconTexture as the icon (HDG pattern).
-- ============================================================================

function VC_OnAddonCompartmentClick(_, buttonName)
    if buttonName == "LeftButton" then
        VC.Settings:Toggle()
    end
end

function VC_OnAddonCompartmentEnter(_, menuItem)
    GameTooltip:SetOwner(menuItem, "ANCHOR_RIGHT")
    GameTooltip:AddLine("|cFFA0522DVamoose's Companion|r", 1, 1, 1)
    GameTooltip:AddLine("A companion that reacts to your adventures", 0.7, 0.7, 0.7)
    GameTooltip:AddLine(" ")
    GameTooltip:AddLine("|cFFFFFFFFClick:|r Open settings", 0.7, 0.7, 0.7)
    GameTooltip:Show()
end

function VC_OnAddonCompartmentLeave()
    GameTooltip:Hide()
end
