local addonName, privateDB = ...

-- ============================================================================
-- HDG_VAMOOSE MODULE
-- Lumber farming quotes with Talking Head display
-- Features two speakers: Vamoose (shaman) and Gazlowe (goblin)
-- Quotes are stored in HDG_CraftQuotes for unified quote management
-- ============================================================================

local HDG_Vamoose = {}
privateDB.HDG_Vamoose = HDG_Vamoose

-- Reference to the centralized quote database
local HDG_CraftQuotes = privateDB.HDG_CraftQuotes

-- ============================================================================
-- TALKING HEAD FRAME
-- Custom talking head display for lumber farming quotes
-- ============================================================================

-- Create the main frame
local VamooseHead = CreateFrame("Frame", "HDG_VamooseTalkingHead", UIParent)
VamooseHead:SetSize(570, 155)
VamooseHead:SetPoint("TOP", UIParent, "TOP", 0, -200)
VamooseHead:Hide()
VamooseHead:SetFrameStrata("DIALOG")

-- Background texture
local vamooseBg = VamooseHead:CreateTexture(nil, "BACKGROUND")
vamooseBg:SetPoint("TOPLEFT", 0, 0)
vamooseBg:SetPoint("BOTTOMRIGHT", 0, 0)

-- Portrait frame overlay
local vamoosePortraitFrame = VamooseHead:CreateTexture(nil, "OVERLAY")
vamoosePortraitFrame:SetSize(143, 143)
vamoosePortraitFrame:SetPoint("TOPLEFT", 5, -6)

-- 3D Model frame
local vamooseModel = CreateFrame("PlayerModel", nil, VamooseHead)
vamooseModel:SetSize(115, 115)
vamooseModel:SetPoint("TOPLEFT", 19, -20)
vamooseModel:SetFrameStrata("DIALOG")
vamooseModel:SetFrameLevel(VamooseHead:GetFrameLevel() + 1)

-- Name text
local vamooseNameText = VamooseHead:CreateFontString(nil, "OVERLAY", "GameFontNormalLarge")
vamooseNameText:SetPoint("TOPLEFT", 160, -28)
vamooseNameText:SetTextColor(1, 0.82, 0) -- Gold

-- Body text
local vamooseBodyText = VamooseHead:CreateFontString(nil, "OVERLAY", "GameFontHighlightLarge")
vamooseBodyText:SetPoint("TOPLEFT", 160, -55)
vamooseBodyText:SetWidth(380)
vamooseBodyText:SetJustifyH("LEFT")
vamooseBodyText:SetWordWrap(true)

-- Play a quote with the talking head
-- speaker: "SHAMAN" or "GOBLIN" (defaults to SHAMAN)
-- displayID: optional override for the model display ID
local function PlayTalkingHead(quote, speaker, displayID)
    local speakerData = HDG_CraftQuotes.GetSpeaker(speaker) or HDG_CraftQuotes.GetSpeaker("SHAMAN")
    displayID = displayID or speakerData.displayID

    -- Set backdrop art (GarrFollower style - golden/bronze)
    vamooseBg:SetAtlas("TalkingHeads-GarrFollower-TextBackground")
    vamoosePortraitFrame:SetAtlas("TalkingHeads-GarrFollower-PortraitFrame")

    -- Setup 3D model
    vamooseModel:ClearModel()
    vamooseModel:SetDisplayInfo(displayID)
    vamooseModel:SetPortraitZoom(0.8)
    vamooseModel:SetCamDistanceScale(1.0)
    vamooseModel:SetPosition(0, 0, 0)

    -- Lighting for WoW 11.x
    local lightValues = {
        omnidirectional = false,
        point = CreateVector3D(-1, 0, -1),
        ambientIntensity = 0.7,
        ambientColor = CreateColor(0.7, 0.7, 0.7),
        diffuseIntensity = 1.0,
        diffuseColor = CreateColor(0.8, 0.8, 0.8),
    }
    vamooseModel:SetLight(true, lightValues)
    vamooseModel:SetAnimation(60) -- Talking animation

    -- Set text with speaker name
    vamooseNameText:SetText(speakerData.name)
    vamooseBodyText:SetText(quote)

    -- Show with fade in
    VamooseHead:Show()
    VamooseHead:SetAlpha(0)
    UIFrameFadeIn(VamooseHead, 0.3, 0, 1)

    -- Auto-hide after 5 seconds
    if VamooseHead.timer then VamooseHead.timer:Cancel() end
    if VamooseHead.hideTimer then VamooseHead.hideTimer:Cancel() end
    VamooseHead.timer = C_Timer.NewTimer(5, function()
        UIFrameFadeOut(VamooseHead, 0.5, 1, 0)
        VamooseHead.hideTimer = C_Timer.NewTimer(0.5, function() VamooseHead:Hide() end)
    end)
end

-- Expose for external use
HDG_Vamoose.PlayTalkingHead = PlayTalkingHead

-- ============================================================================
-- QUOTE TRACKING
-- Track last quote time and count per lumber type to avoid spam
-- ============================================================================

local lastQuoteTime = {}
local collectionsSinceQuote = {}
local nextQuoteThreshold = {}

-- Initialize tracking for a lumber type with chattiness setting
-- chattiness: 1-99, determines max random threshold for next quote
local function InitTracking(lumberId, chattiness)
    chattiness = chattiness or 30
    if not lastQuoteTime[lumberId] then
        lastQuoteTime[lumberId] = 0
        collectionsSinceQuote[lumberId] = 0
        -- Random threshold between 1 and chattiness value
        nextQuoteThreshold[lumberId] = math.random(1, math.max(1, chattiness))
    end
end

-- Get a random quote for a lumber type (delegates to HDG_CraftQuotes)
-- Returns: quote, speaker ("SHAMAN" or "GOBLIN")
function HDG_Vamoose.GetRandomQuote(lumberId)
    return HDG_CraftQuotes.GetRandomLumberQuote(lumberId)
end

-- Called when lumber is collected - may trigger a quote
-- chattiness: 1-99, determines frequency (higher = less frequent)
-- Returns: quote, speaker if one should be displayed, nil otherwise
function HDG_Vamoose.OnLumberCollected(lumberId, amount, chattiness)
    if not HDG_CraftQuotes.HasLumberQuotes(lumberId) then
        return nil, nil
    end

    chattiness = chattiness or 30
    InitTracking(lumberId, chattiness)

    -- Increment collection count
    collectionsSinceQuote[lumberId] = collectionsSinceQuote[lumberId] + (amount or 1)

    -- Check if we've hit the threshold
    if collectionsSinceQuote[lumberId] >= nextQuoteThreshold[lumberId] then
        -- Reset for next quote with new random threshold
        collectionsSinceQuote[lumberId] = 0
        nextQuoteThreshold[lumberId] = math.random(1, math.max(1, chattiness))
        lastQuoteTime[lumberId] = GetTime()

        return HDG_Vamoose.GetRandomQuote(lumberId)
    end

    return nil, nil
end

-- Display a quote using the talking head frame
-- If speaker is nil, defaults to SHAMAN
function HDG_Vamoose.DisplayQuote(quote, speaker)
    if not quote then return end
    PlayTalkingHead(quote, speaker or "SHAMAN")
end

-- Reset tracking (e.g., on session end)
function HDG_Vamoose.ResetTracking(lumberId)
    if lumberId then
        lastQuoteTime[lumberId] = nil
        collectionsSinceQuote[lumberId] = nil
        nextQuoteThreshold[lumberId] = nil
    else
        -- Reset all
        lastQuoteTime = {}
        collectionsSinceQuote = {}
        nextQuoteThreshold = {}
    end
end

-- Check if quotes are available for a lumber type (delegates to HDG_CraftQuotes)
function HDG_Vamoose.HasQuotes(lumberId)
    return HDG_CraftQuotes.HasLumberQuotes(lumberId)
end

-- Get quote count for a lumber type (delegates to HDG_CraftQuotes)
function HDG_Vamoose.GetQuoteCount(lumberId)
    return HDG_CraftQuotes.GetLumberQuoteCount(lumberId)
end

-- Get total lumber quote count (delegates to HDG_CraftQuotes)
function HDG_Vamoose.GetTotalQuoteCount()
    return HDG_CraftQuotes.GetTotalLumberQuoteCount()
end

-- ============================================================================
-- DAILY BESTOWED TITLES (squirrel-given personas, rotated daily)
-- One title + Vamoose quip per real-world day. Disconnected from collection
-- stats — purely date-based rotation across the 50-entry table below.
-- HDG_DB.daily.bestowed = { date = "YYYYMMDD", index = N } persists the
-- chosen entry so date-comparison hooks elsewhere can detect the rollover.
-- ============================================================================

local DAILY_TITLES = {
    { name = "Twilight Court Architect",  quote = "Sleeps with one eye open. The other is admiring the moonlight." },
    { name = "Velvet Dawn Curator",       quote = "Wakes before the sun. Decorates before the coffee." },
    { name = "Lumber Baron",              quote = "Has opinions about wood. Strong ones. Probably wrong." },
    { name = "Wallpaper Whisperer",       quote = "Knows the secrets of every pattern. Most aren't worth the asking price." },
    { name = "Mantle Magnate",            quote = "More candlesticks than a chandler's guild. Counts them nightly." },
    { name = "Cobblestone Connoisseur",   quote = "Tested every path stone for foot comfort. Personally. In bare feet." },
    { name = "Topiary Tyrant",            quote = "Hedge clippers sharper than wit. Both deployed daily." },
    { name = "Lantern Luminary",          quote = "Lit up rooms before it was fashionable. Hasn't stopped." },
    { name = "Banner Bannermarshal",      quote = "Hangs flags at precise angles. Approves of pageantry. Loudly." },
    { name = "Hearth Herald",             quote = "Believes every room needs a fire. And someone to admire it." },
    { name = "Drapery Despot",            quote = "Curtains closed, deals open. Negotiates by candlelight." },
    { name = "Sconce Savant",             quote = "Pronounces it correctly. Will correct you. Politely. Once." },
    { name = "Cushion Cultist",           quote = "Worships the throw pillow. Performs daily devotions of fluffing." },
    { name = "Tapestry Tactician",        quote = "Reads battle scenes for fun. Knows who lost. Has theories." },
    { name = "Floorboard Footnoter",      quote = "Spreadsheet of every plank. Squeaks cross-referenced. Rankings exist." },
    { name = "Shelf Sheriff",             quote = "Books in strict order. Don't try anything. Don't even try." },
    { name = "Vase Voyager",              quote = "Travels for ceramics. Returns with three more than necessary." },
    { name = "Curtain Call Captain",      quote = "Drama in every room. Insists on the proper exit." },
    { name = "Tankard Trustee",           quote = "Each mug named. Refuses to lend any. Especially the favourites." },
    { name = "Pillow Plenipotentiary",    quote = "International peace via cushion arrangement. Treaties pending." },
    { name = "Hourglass Hierophant",      quote = "Counts time differently. Sand falls slower for the deserving." },
    { name = "Garden Gargoyle Inspector", quote = "Each statue judged. Most found wanting. None told." },
    { name = "Rune Rug Reader",           quote = "Sees stories in carpet patterns. The carpet has heard things." },
    { name = "Goblet Gourmand",           quote = "Prefers vintage. Of glassware. The contents are negotiable." },
    { name = "Mirror Magus",              quote = "All mirrors angled with intent. The reasons remain undisclosed." },
    { name = "Tile Trafficker",           quote = "Knows exactly where each tile came from. Will tell you. Twice." },
    { name = "Iron Lattice Lord",         quote = "Wrought metal in every doorway. None of it ironic. All of it heavy." },
    { name = "Crystal Cartographer",      quote = "Maps the manor by chandelier-light alone. Ink optional." },
    { name = "Marble Maven",              quote = "Veins matter. The stone variety AND the conversational." },
    { name = "Bronze Bench Beneficiary",  quote = "Sat on every garden bench in the kingdom. Reviews pending." },
    { name = "Stained Glass Statesman",   quote = "Each pane a treaty. The light through it the seal." },
    { name = "Birdbath Bureaucrat",       quote = "Incident reports filed for each visiting sparrow. In triplicate." },
    { name = "Hayloft Hierarch",          quote = "Bales arranged with theological precision. Cattle approve." },
    { name = "Forge Founder",             quote = "Soot stains as design choice. The craft is never done. Never." },
    { name = "Treasurer of Trinkets",     quote = "Each bauble catalogued. The insurance assessor wept." },
    { name = "Astrolabe Auteur",          quote = "Schedules dinner by celestial alignment. Insists the carrots agree." },
    { name = "Brewmaster of Ambiance",    quote = "Air pressure calibrated room by room. The mood obeys." },
    { name = "Chandelier Czar",           quote = "Counts crystals mid-conversation. Tracks the distractions afterward." },
    { name = "Bookcase Bishop",           quote = "Ordains the order. Dewey Decimal is merely a starting point." },
    { name = "Doorknob Decretist",        quote = "Opinions on each handle. Will share. Especially the brass." },
    { name = "Foyer Philosopher",         quote = "Greets every visitor with an existential question. None expected answers." },
    { name = "Wreath Wright",             quote = "Each one bound by hand. The callouses confirm it." },
    { name = "Plinth Patron",             quote = "Statues need pedestals. Pedestals need names. All named. Personally." },
    { name = "Carpet Curator-General",    quote = "Threads counted. Twice. Then once more for confidence." },
    { name = "Aquarium Almoner",          quote = "The fish are fed first. Always. Nothing else gets started." },
    { name = "Privy Provost",             quote = "Even the outhouse is themed. Especially the outhouse." },
    { name = "Knickknack Sovereign",      quote = "Crown of clutter. Throne of pillows. Robe woven from receipts." },
    { name = "Quilt Quartermaster",       quote = "Stitched the inventory by candlelight. The cat helped, mostly." },
    { name = "Coat-Stand Connoisseur",    quote = "One hat per hook. No exceptions. The cloak gets a pole." },
    { name = "Mosaic Margrave",           quote = "Tiles tell tales. Knows them all. Recites unprompted." },
}

-- Returns today's bestowed title. Deterministic from the system date so all
-- characters on the account see the same title on the same day. Caches the
-- (date, index) tuple in HDG_DB.daily.bestowed for downstream date-rollover
-- detection (any consumer can compare cache.date to date("%Y%m%d") to know
-- whether the title has rotated since their last read).
function HDG_Vamoose.GetDailyTitle()
    HDG_DB = HDG_DB or {}
    HDG_DB.daily = HDG_DB.daily or {}

    local today = date("%Y%m%d")
    local cache = HDG_DB.daily.bestowed
    if cache and cache.date == today and cache.index and DAILY_TITLES[cache.index] then
        return DAILY_TITLES[cache.index]
    end

    local seed = tonumber(today) or 0
    local idx  = (seed % #DAILY_TITLES) + 1
    HDG_DB.daily.bestowed = { date = today, index = idx }
    return DAILY_TITLES[idx]
end

-- Backwards-compat: prior callers passed a styleTagName and got a personalised
-- title. The argument is now ignored — daily rotation drives the choice.
function HDG_Vamoose.GetBestowedTitle(_)
    return HDG_Vamoose.GetDailyTitle()
end

-- ============================================================================
-- BLIZZARD EVENT WIRING -- talking-head craft quote
-- Subscribes to TRADE_SKILL_ITEM_CRAFTED_RESULT to roll a chattiness-gated
-- craft quote when a decor item completes. Acquisition log + queue
-- auto-decrement live in HDG_Data + HDG_PowerCrafting; this is the
-- personality module's slice.
-- ============================================================================
local _craftQuoteTracking = {
    craftsSinceQuote   = 0,  -- counter since last quote
    nextQuoteThreshold = 1,  -- random threshold for next quote (1..chattiness)
}

-- Returns true when a quote should fire on this craft, based on the
-- vamooseChattiness slider (lower = chattier; 0 = silent).
local function shouldShowCraftQuote(chattiness)
    if (chattiness or 0) <= 0 then return false end
    _craftQuoteTracking.craftsSinceQuote = _craftQuoteTracking.craftsSinceQuote + 1
    if _craftQuoteTracking.craftsSinceQuote >= _craftQuoteTracking.nextQuoteThreshold then
        _craftQuoteTracking.craftsSinceQuote   = 0
        _craftQuoteTracking.nextQuoteThreshold = math.random(1, math.max(1, chattiness))
        return true
    end
    return false
end

function HDG_Vamoose.RegisterCraftQuoteHandler()
    local f = CreateFrame("Frame")
    f:RegisterEvent("TRADE_SKILL_ITEM_CRAFTED_RESULT")
    f:SetScript("OnEvent", function(_, _, result)
        if not result or not result.hyperlink then return end
        local HDG = _G.HousingDecorGuide
        local store = HDG and HDG.Store
        local state = store and store:GetState()
        local config = (state and state.config) or {}

        local quotesEnabled = config.quotesEnabled
        if quotesEnabled == nil then quotesEnabled = true end
        if not quotesEnabled then return end
        local craftQuotesEnabled = config.craftQuotesEnabled
        if craftQuotesEnabled == nil then craftQuotesEnabled = true end
        if not craftQuotesEnabled then return end

        local itemID = tonumber(result.hyperlink:match("item:(%d+)"))
        local decorInfo = itemID and privateDB.decorItem and privateDB.decorItem[itemID]
        if not decorInfo or not decorInfo.profession or not decorInfo.expansion then return end

        local chattiness = config.vamooseChattiness or 30
        if not shouldShowCraftQuote(chattiness) then return end

        local CraftQuotes = privateDB.HDG_CraftQuotes
        if not CraftQuotes then return end
        local expansionAbbr = HDG_ExpansionData
            and HDG_ExpansionData.GetAbbreviation
            and HDG_ExpansionData.GetAbbreviation(decorInfo.expansion)
        local quote = CraftQuotes.GetRandomQuote(decorInfo.profession, expansionAbbr)
        if not quote then return end
        local speaker = CraftQuotes.GetSpeaker(decorInfo.profession)
        if not speaker then return end

        local onlyChat = config.quotesOnlyChat or false
        if onlyChat then
            print(string.format("|cFF14b8a6[%s]|r %s crafted! %s",
                speaker.name, result.hyperlink, quote))
        else
            HDG_Vamoose.PlayTalkingHead(quote, decorInfo.profession, speaker.displayID)
        end
    end)
end
