-- New-Oath.lua -- New objective creation UI --
-- WanderBook: Forge your path through Azeroth with your own goals. --
-- Made by Blakmane. May 2025. --

local _, addon = ...
WanderBook = addon

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- LOCAL CALLS & HELPERS --

local LoadAddOn = _G.LoadAddOn
local selectedType = nil
local selectedZone = nil
local selectedSubzone = nil

local function SetupPlaceholder(box, placeholderText) -- Focus Helper
    box:SetText(placeholderText)
    box:SetTextColor(0.5, 0.5, 0.5)
    box:SetScript("OnEditFocusGained", function(self)
        if self:GetText() == placeholderText then
            self:SetText("")
            self:SetTextColor(1, 1, 1)
        end
    end)
    box:SetScript("OnEditFocusLost", function(self)
        if self:GetText() == "" then
            self:SetText(placeholderText)
            self:SetTextColor(0.5, 0.5, 0.5)
        end
    end)
end
local function FilterNumericInput(box, placeholderText) -- Numeric Filter Helper
    box:SetScript("OnTextChanged", function(self)
        local text = self:GetText()
        if text == placeholderText then return end
        local filtered = text:gsub("[^%d]", "")
        if filtered ~= text then
            self:SetText(filtered)
        end
    end)
end
if not _G.selectedIconTexture then
    local dummyFrame = CreateFrame("Frame")
    _G.selectedIconTexture = dummyFrame:CreateTexture()
end

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- NEW OATHS PANEL --

local createPanel = CreateFrame("Frame", nil, UIParent, "BasicFrameTemplateWithInset")
createPanel:SetFrameStrata(WanderBookUI:GetFrameStrata())
createPanel:SetFrameLevel(WanderBookUI:GetFrameLevel() + 10)
-- Strip Blizzard default textures
local regions = { createPanel:GetRegions() }
for _, region in ipairs(regions) do
    if region:GetObjectType() == "Texture" then
        region:SetTexture(nil)
    end
end

-- Apply custom background texture
local bgTex = createPanel:CreateTexture(nil, "BACKGROUND")
bgTex:SetAllPoints(true)
bgTex:SetTexture("Interface\\AddOns\\WanderBook\\Media\\new-oath-panel.tga")

createPanel:SetSize(348, 490)
createPanel:SetPoint("LEFT", WanderBookUI, "RIGHT", -30, 0)
createPanel:Hide()

createPanel:HookScript("OnHide", function()
    if WanderBook.SealFrame and WanderBook.SealFrame:IsShown() then
        WanderBook.SealFrame:Hide()
    end
end)

createPanel:HookScript("OnShow", function()
    PlaySound(SOUNDKIT.IG_CHARACTER_INFO_OPEN)
end)
createPanel:HookScript("OnHide", function()
    PlaySound(SOUNDKIT.IG_CHARACTER_INFO_CLOSE)
end)

-- TOOLTIP + PANEL MESSAGE FRAME
local unifiedTipFrame = CreateFrame("Frame", nil, createPanel, "BackdropTemplate")
unifiedTipFrame:SetSize(280, 45)
unifiedTipFrame:SetPoint("TOP", createPanel, "TOP", 0, 40)
unifiedTipFrame:SetBackdrop({
    bgFile = "Interface/Tooltips/UI-Tooltip-Background",
    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
    tile = true, tileSize = 16, edgeSize = 12,
    insets = { left = 2, right = 2, top = 2, bottom = 2 }
})
unifiedTipFrame:SetBackdropColor(0, 0, 0, 0.8)
unifiedTipFrame:SetBackdropBorderColor(1, 1, 1, 1)
unifiedTipFrame:Hide()

unifiedTipFrame.text = unifiedTipFrame:CreateFontString(nil, "OVERLAY", "GameFontNormal")
unifiedTipFrame.text:SetPoint("CENTER")
unifiedTipFrame.text:SetTextColor(1, 1, 1, 1)
unifiedTipFrame:SetScale(1.2)

local tipSource = nil

function SetTooltip(widget, text)
    widget:SetScript("OnEnter", function()
        tipSource = "tooltip"
        unifiedTipFrame.text:SetText(text)
        local width = math.min(unifiedTipFrame.text:GetStringWidth() + 20, 280)
        unifiedTipFrame:SetWidth(width)
        unifiedTipFrame:Show()
    end)
    widget:SetScript("OnLeave", function()
        if tipSource == "tooltip" then
            unifiedTipFrame:Hide()
        end
    end)
end

function SetMessage(text, duration)
    tipSource = "message"
    unifiedTipFrame.text:SetText(text)
    local width = math.min(unifiedTipFrame.text:GetStringWidth() + 20, 280)
    unifiedTipFrame:SetWidth(width)
    unifiedTipFrame:Show()
    if duration and duration > 0 then
        C_Timer.After(duration, function()
            if tipSource == "message" then
                unifiedTipFrame:Hide()
            end
        end)
    end
end

-- TITLE FIELD --
local titleBox = CreateFrame("EditBox", nil, createPanel, "InputBoxTemplate")
titleBox:SetSize(188, 26)
titleBox:SetAutoFocus(false)
titleBox:SetPoint("TOP", createPanel, "TOP", -22, -55)
titleBox:SetMaxLetters(30)
SetupPlaceholder(titleBox, "Title: Max 30 characters.")

-- DESCRIPTION FIELD --
local descScroll = CreateFrame("ScrollFrame", nil, createPanel, "UIPanelScrollFrameTemplate,BackdropTemplate")
descScroll:SetSize(244, 50)
descScroll:SetPoint("TOP", titleBox, "TOP", 22, -30)

local descBox = CreateFrame("EditBox", nil, descScroll)
descBox:SetMultiLine(true)
descBox:SetFontObject("GameFontHighlight")
descBox:SetWidth(242)
descBox:SetAutoFocus(false)
descBox:SetJustifyH("LEFT")
descBox:SetJustifyV("TOP")
descBox:SetTextInsets(7, 7, 7, 7)
descBox:SetMaxLetters(80)
SetupPlaceholder(descBox, "Description: Max 80 characters.")
descBox:SetScript("OnEscapePressed", function(self) self:ClearFocus() end)

descScroll:SetScrollChild(descBox)
descScroll.ScrollBar:Hide()
descScroll:EnableMouse(true)
descScroll:EnableMouseWheel(false)
descScroll:SetPropagateMouseClicks(false)
descScroll:SetBackdrop({
    bgFile = "Interface/Tooltips/UI-Tooltip-Background",
    edgeFile = "Interface/Tooltips/UI-Tooltip-Border",
    tile = true, tileSize = 16, edgeSize = 12,
    insets = { left = 4, right = 4, top = 4, bottom = 4 }
})
descScroll:SetBackdropColor(0, 0, 0, 0.5)

-- ICON SELECTOR BUTTON --
local iconSelectBtn = CreateFrame("Button", nil, createPanel, "UIPanelButtonTemplate")
iconSelectBtn:SetSize(40, 40)
iconSelectBtn:SetPoint("BOTTOM", titleBox, "RIGHT", 29, -10)
iconSelectBtn:SetNormalTexture(134400) -- Default icon
createPanel.selectedIcon = 134400

-- ICONS PANEL --
local iconSelectorFrame
iconSelectBtn:SetScript("OnClick", function()
    PlaySound(SOUNDKIT.UI_IG_STORE_PAGE_NAV_BUTTON)
    if not WanderBook.iconPool or #WanderBook.iconPool == 0 then
        --print("Icon list is empty. Please check Icons.lua.")
        return
    end
    if not iconSelectorFrame then
        iconSelectorFrame = WanderBook.CreateVirtualIconSelector(createPanel, function(iconID)
            iconSelectBtn:SetNormalTexture(iconID)
            createPanel.selectedIcon = iconID
            iconSelectorFrame:Hide()
        end)
    end
    if iconSelectorFrame:IsShown() then
        iconSelectorFrame:Hide()
    else
        iconSelectorFrame:Show()
    end
end)

-- Hide popup when panel closes
createPanel:HookScript("OnHide", function()
    if iconSelectorFrame and iconSelectorFrame:IsShown() then
        iconSelectorFrame:Hide()
    end
end)

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- OBJECTIVE TYPE DROPDOWN --

local typeDrop = CreateFrame("Frame", "WBTypeDropdown", createPanel, "UIDropDownMenuTemplate")
typeDrop:SetPoint("TOPLEFT", descScroll, "BOTTOMLEFT", 5, -35)
UIDropDownMenu_SetWidth(typeDrop, 190)
UIDropDownMenu_SetText(typeDrop, "Select an Objective")
local typeOptions = {
    { text = "Do /emote", value = "emotetarget" },
    { text = "Use a Spell or Item", value = "usetarget" },
    { text = "Loot an Item", value = "loot" },
    { text = "Kill", value = "kill" },
    { text = "Kill w/ Spell or Item", value = "killwith" },
    { text = "Crit w/ Spell or Item", value = "crittarget" },
    { text = "Track Damage Amount", value = "damage" },
    { text = "Track Regeneration Amount", value = "regen" },
}

-- SPELL/ITEM ID FIELD --
local idBox = CreateFrame("EditBox", nil, createPanel, "InputBoxTemplate")
idBox:SetSize(90, 26)
idBox:SetAutoFocus(false)
idBox:SetPoint("TOP", typeDrop, "CENTER", -52, -25)
SetupPlaceholder(idBox, "Spell or Item")
--FilterNumericInput(idBox, "Spell or Item ID")
idBox:SetEnabled(false)
idBox:SetAlpha(0.3)

idBox:SetScript("OnMouseDown", function(self, button)
    if button == "RightButton" then
        self:SetText("")
    end
end)

idBox:SetScript("OnTextChanged", function(self)
    local text = self:GetText()
    if text == "Spell or Item" or text == "" then
        self:SetTextColor(0.5, 0.5, 0.5)
    else
        self:SetTextColor(1, 1, 1)
    end
end)

-- NPC ID FIELD --
local npcBox = CreateFrame("EditBox", nil, createPanel, "InputBoxTemplate")
npcBox:SetSize(90, 26)
npcBox:SetAutoFocus(false)
npcBox:SetPoint("TOP", typeDrop, "CENTER", 57, -60)
SetupPlaceholder(npcBox, "Target NPC")
--FilterNumericInput(npcBox, "Target NPC")
npcBox:SetEnabled(false)
npcBox:SetAlpha(0.3)
npcBox:EnableKeyboard(false)
npcBox:SetScript("OnMouseDown", function(self, button)
    if button == "RightButton" then self:SetText("") end
end)

-- CREATURE/NPC DROPDOWN --
local creatureTypes = { 
    "Beast", "Demon", "Dragonkin", 
    "Elemental", "Giant", "Humanoid",
    "Mechanical", "Undead", "Aberration",
    "Critter", "Totem", "Non-combat Pet", }

local selectedCreature = nil

local creatureDrop = CreateFrame("Frame", "WBCreatureDropdown", createPanel, "UIDropDownMenuTemplate")
creatureDrop:SetPoint("TOP", typeDrop, "CENTER", 55, -25)

UIDropDownMenu_SetWidth(creatureDrop, 85)
UIDropDownMenu_SetText(creatureDrop, "Creature")
creatureDrop:EnableMouse(false)
creatureDrop.Button:EnableMouse(false)
creatureDrop:SetAlpha(0.3)

UIDropDownMenu_Initialize(creatureDrop, function(self, level)
    if level == 1 then
        -- Creature submenu FIRST
        local creatureInfo = UIDropDownMenu_CreateInfo()
        creatureInfo.text = "Creature"
        creatureInfo.value = "creature"
        creatureInfo.hasArrow = true
        creatureInfo.menuList = 2
        creatureInfo.checked = function()
            return selectedCreature and selectedCreature ~= "npc"
        end
        UIDropDownMenu_AddButton(creatureInfo, level)

        -- NPC option SECOND
        local npcInfo = UIDropDownMenu_CreateInfo()
        npcInfo.text = "NPC"
        npcInfo.value = "npc"
        npcInfo.func = function()
            selectedCreature = "npc"
            UIDropDownMenu_SetSelectedValue(creatureDrop, "npc")
            UIDropDownMenu_SetText(creatureDrop, "NPC")
            npcBox:SetEnabled(true)
            npcBox:SetAlpha(1)

            -- Autofill NPC ID from target
            local guid = UnitGUID("target")
            if guid and guid:match("Creature") then
                local _, _, _, _, _, npcID = strsplit("-", guid)
                local name = UnitName("target")
                if npcID then
                    npcBox:SetText(name or npcID)
                    npcBox:SetTextColor(1, 1, 1)
                    createPanel.selectedNpcID = tonumber(npcID)
                    createPanel.selectedNpcName = name
                end
            end
        end
        npcInfo.checked = function() return selectedCreature == "npc" end
        UIDropDownMenu_AddButton(npcInfo, level)
            
        -- No Target option THIRD
        local noneInfo = UIDropDownMenu_CreateInfo()
        noneInfo.text = "No specific target"
        noneInfo.value = "__none"  -- harmless value used for internal dropdown tracking
        noneInfo.func = function()
            selectedCreature = nil  -- this is key!
            UIDropDownMenu_SetSelectedValue(creatureDrop, "__none")
            UIDropDownMenu_SetText(creatureDrop, "No target")
            npcBox:SetEnabled(false)
            npcBox:SetAlpha(0.3)
            SetupPlaceholder(npcBox, "Target NPC")
            createPanel.selectedNpcID = nil
            createPanel.selectedNpcName = nil
        end
        noneInfo.checked = function()
            return selectedCreature == nil
        end
        UIDropDownMenu_AddButton(noneInfo, level)
            
        -- PvP (Soon™) --
        local playerHint = UIDropDownMenu_CreateInfo()
        playerHint.text = "Player Character (Soon™)"
        playerHint.disabled = true
        playerHint.keepShownOnClick = true
        playerHint.notCheckable = false  -- allows bullet to render
        playerHint.checked = false       -- bullet shown but not filled
        UIDropDownMenu_AddButton(playerHint, level)

    elseif level == 2 then
        for _, creatureType in ipairs(creatureTypes) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = creatureType
            info.value = creatureType
            info.func = function(selfArg)
                selectedCreature = selfArg.value
                UIDropDownMenu_SetSelectedValue(creatureDrop, selfArg.value)
                UIDropDownMenu_SetText(creatureDrop, selfArg.value)
                npcBox:SetEnabled(false)
                npcBox:SetAlpha(0.3)
                SetupPlaceholder(npcBox, "Target NPC")
                CloseDropDownMenus()
            end
            info.checked = function() return selectedCreature == creatureType end
            UIDropDownMenu_AddButton(info, level)
        end
    end
end)

-- EMOTE DROPDOWN --
local emoteList = {
  "agree", "amaze", "applaud", "awe", "bye", "cheer", "clap", "cower", "cringe",
  "cry", "dance", "drink", "facepalm", "flex", "healme", "hello", "hug", "insult",
  "kiss", "kneel", "laugh", "nod", "no", "pet", "point", "pounce", "roar", "rofl",
  "salute", "shoo", "shrug", "sit", "sleep", "thank", "train", "wave"
}

local selectedEmote = nil
local emoteDrop = CreateFrame("Frame", "WBEmoteDropdown", createPanel, "UIDropDownMenuTemplate")
emoteDrop:SetPoint("TOP", typeDrop, "CENTER", -55, -60)

UIDropDownMenu_SetWidth(emoteDrop, 85)
UIDropDownMenu_SetText(emoteDrop, "Emote")
emoteDrop:EnableMouse(false)
emoteDrop.Button:EnableMouse(false)
emoteDrop:SetAlpha(0.3)

UIDropDownMenu_Initialize(emoteDrop, function(self, level)
    for _, emote in ipairs(emoteList) do
        local info = UIDropDownMenu_CreateInfo()
        info.text = emote
        info.value = emote
        info.func = function(selfArg)
            selectedEmote = selfArg.value
            UIDropDownMenu_SetSelectedValue(emoteDrop, selfArg.value)
        end
        info.checked = function() return selectedEmote == emote end
        UIDropDownMenu_AddButton(info)
    end
end)

-- ZONE SELECTION CHECK AND DROPDOWN --
local zoneCheck = CreateFrame("CheckButton", nil, createPanel, "UICheckButtonTemplate")
zoneCheck:SetPoint("TOPRIGHT", typeDrop, "BOTTOMRIGHT", -12, -113)
zoneCheck.text:SetText("")

local zoneDrop = CreateFrame("Frame", "WBZoneDropdown", createPanel, "UIDropDownMenuTemplate")
zoneDrop:SetPoint("TOPLEFT", typeDrop, "BOTTOMLEFT", 0, -115)
UIDropDownMenu_SetWidth(zoneDrop, 165)
UIDropDownMenu_SetText(zoneDrop, "Select Zone")
zoneDrop:EnableMouse(false)
zoneDrop.Button:EnableMouse(false)
zoneDrop:SetAlpha(0.3)

local continentIDs = {
    Kalimdor = 12,
    ["Eastern Kingdoms"] = 13,
    Outland = 101,
    Northrend = 113,
    Pandaria = 424,
    Draenor = 572,
    ["Broken Isles"] = 619,
    Zandalar = 875,
    ["Kul Tiras"] = 876,
    Shadowlands = 1550,
    ["Dragon Isles"] = 1978,
    --["Khaz Algar"] = 14748,
}

local continentZoneCache = {}
local zoneSubzoneCache = {}
local function FetchSubzonesFor(zoneID)
    local mapTypes = {
        Enum.UIMapType.Micro,
        Enum.UIMapType.Zone,
        Enum.UIMapType.Dungeon,
        Enum.UIMapType.Orphan,
    }
    local seen, results = {}, {}
    for _, mapType in ipairs(mapTypes) do
        local children = C_Map.GetMapChildrenInfo(zoneID, mapType)
        if children then
            for _, sub in ipairs(children) do
                if sub.name ~= "" and not seen[sub.name] then
                    seen[sub.name] = true
                    table.insert(results, sub)
                end
            end
        end
    end
    table.sort(results, function(a, b) return a.name < b.name end)
    return results
end

-- DROPDOWN POPULATE ZONES + FILTERS --
local function PopulateZones()
    for contName, contID in pairs(continentIDs) do
        if not continentZoneCache[contName] then
            local zonesRaw = C_Map.GetMapChildrenInfo(contID, Enum.UIMapType.Zone)
            continentZoneCache[contName] = {}

            if zonesRaw then
                local seenNames = {}

                local blacklistZones = {
                    --["Gilneas City"] = true,
                    ["Vision of Stormwind"] = true,
                    ["Vision of Orgrimmar"] = true,
                }

                for _, zoneInfo in ipairs(zonesRaw) do
                    local zoneName = zoneInfo.name
                    local mapInfo = C_Map.GetMapInfo(zoneInfo.mapID)

                    if zoneName
                       and not seenNames[zoneName]
                       and not blacklistZones[zoneName]
                       and mapInfo
                       and mapInfo.parentMapID == contID  -- ensures parent is exact continent ID
                       and not (mapInfo.mapType == Enum.UIMapType.Dungeon or
                                mapInfo.mapType == Enum.UIMapType.Scenario or
                                mapInfo.mapType == Enum.UIMapType.Orphan)
                    then
                        seenNames[zoneName] = true
                        table.insert(continentZoneCache[contName], zoneInfo)

                        if not zoneSubzoneCache[zoneInfo.mapID] then
                            zoneSubzoneCache[zoneInfo.mapID] = FetchSubzonesFor(zoneInfo.mapID)
                        end
                    end
                end

                -- Sort clean zones by name
                table.sort(continentZoneCache[contName], function(a, b) return a.name < b.name end)
            end
        end
    end
end

-- ZONE CHECKBOX ACTIVATOR --
zoneCheck:SetScript("OnClick", function(self)
    local enabled = self:GetChecked()

    zoneDrop:EnableMouse(enabled)
    zoneDrop.Button:EnableMouse(enabled)
    zoneDrop:SetAlpha(enabled and 1 or 0.3)

    if enabled then
        PopulateZones()
        local mapID = C_Map.GetBestMapForUnit("player")
        if mapID then
            local mapInfo = C_Map.GetMapInfo(mapID)
            if mapInfo and mapInfo.name then
                selectedZone = mapInfo.name
                UIDropDownMenu_SetSelectedValue(zoneDrop, mapInfo.name)
                UIDropDownMenu_SetText(zoneDrop, mapInfo.name)
            end
        end

        -- Show hint in main dropdown if no goal type selected
        if not selectedType then
            selectedType = "zone"
            UIDropDownMenu_SetText(typeDrop, "Just visiting a Zone?")
        end
    else
        UIDropDownMenu_SetSelectedValue(zoneDrop, nil)
        UIDropDownMenu_SetText(zoneDrop, "Select Zone")
        selectedZone = nil

        if selectedType == "zone" then
            selectedType = nil
            UIDropDownMenu_SetText(typeDrop, "Select an Objective")
        end
    end
end)

UIDropDownMenu_Initialize(zoneDrop, function(self, level, menuList)
    if level == 1 then
        for name in pairs(continentZoneCache) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = name
            info.hasArrow = true
            info.notCheckable = true
            info.menuList = name
            UIDropDownMenu_AddButton(info, level)
        end
    elseif level == 2 then
        local zones = continentZoneCache[menuList]
        for _, zone in ipairs(zones or {}) do
            local info = UIDropDownMenu_CreateInfo()
            info.text = zone.name
            info.value = zone.name
            info.notCheckable = true
            info.func = function(btn)
                selectedZone = btn.value
                selectedSubzone = nil
                UIDropDownMenu_SetSelectedValue(zoneDrop, btn.value)
                UIDropDownMenu_SetText(zoneDrop, btn.value)
                CloseDropDownMenus()
            end
            UIDropDownMenu_AddButton(info, level)
        end
    end
end)

-- COUNTER CHECKBOX --
local isCounter = false
local counterCheck = CreateFrame("CheckButton", nil, createPanel, "UICheckButtonTemplate")
counterCheck:SetPoint("TOPRIGHT", zoneDrop, "BOTTOMRIGHT", 12, 0)
counterCheck.text:SetText("Counter")
counterCheck.text:SetPoint("LEFT", counterCheck, "LEFT", -40, 0)
counterCheck:SetChecked(false)
local counterTooltipFrame = CreateFrame("Frame", nil, createPanel)
counterTooltipFrame:SetSize(40, 20)
counterTooltipFrame:SetPoint("CENTER", counterCheck, "CENTER", -80, 0)
counterTooltipFrame:SetFrameLevel(counterCheck:GetFrameLevel() + 1)
counterTooltipFrame:EnableMouse(true)
counterCheck:SetEnabled(false)
counterCheck:SetAlpha(0.3)

-- AMOUNT FIELD --
local goalAmount = 1
local amountBox = CreateFrame("EditBox", nil, createPanel, "InputBoxTemplate")
amountBox:SetSize(40, 26)
amountBox:SetPoint("TOPLEFT", zoneDrop, "BOTTOMLEFT", 23, -1)
amountBox:SetAutoFocus(false)
amountBox:SetJustifyH("CENTER")
amountBox:SetNumeric(true)
amountBox:SetText(goalAmount)

-- Increment/Decrement Buttons
local downButton = CreateFrame("Button", nil, amountBox, "UIPanelButtonTemplate")
downButton:SetSize(25, 25)
downButton:SetPoint("LEFT", amountBox, "RIGHT", 5, 0)
downButton:SetText("-")
downButton:SetScript("OnClick", function()
    goalAmount = math.max(1, goalAmount - 1)
    amountBox:SetText(goalAmount)
end)

local upButton = CreateFrame("Button", nil, amountBox, "UIPanelButtonTemplate")
upButton:SetSize(25, 25)
upButton:SetPoint("LEFT", downButton, "RIGHT", 2, 0)
upButton:SetText("+")
upButton:SetScript("OnClick", function()
    goalAmount = math.min(9999, goalAmount + 1)
    amountBox:SetText(goalAmount)
end)

amountBox:SetEnabled(false)
amountBox:SetAlpha(0.3)
upButton:Disable()
downButton:Disable()
amountBox:SetScript("OnTextChanged", function(self)
    local val = tonumber(self:GetText())
    if val then goalAmount = val end
end)

-- Activation toggle between both
counterCheck:SetScript("OnClick", function(self)
    isCounter = self:GetChecked()

    if isCounter then
        amountBox:SetText("")
        amountBox:SetEnabled(false)
        amountBox:SetAlpha(0.3)
        upButton:Disable()
        downButton:Disable()
    else
        amountBox:SetText(goalAmount)
        amountBox:SetEnabled(true)
        amountBox:SetAlpha(1)
        upButton:Enable()
        downButton:Enable()
    end
end)

-- COMPONENT TOOLTIPS --
SetTooltip(typeDrop, "|cfffe35eeTell me, what kind of vow\ndo you wish to make?")
SetTooltip(idBox, "|cfffe35eeYou can type or shift+click\nthe Spell or Item you seek.")
SetTooltip(npcBox, "|cfffe35eeTarget the creature you seek,\nI shall keep watch.")
SetTooltip(emoteDrop, "|cfffe35eeWhat gesture shall\nmark your oath?")
SetTooltip(creatureDrop, "|cfffe35eeChoose the kind of creature\nyou intend to face.")
SetTooltip(zoneDrop, "|cfffe35eeShall this oath be bound\nto a specific place?")
SetTooltip(counterCheck.text, "|cfffe35eeTrack it forever.\nIdeal for ongoing records.")
SetTooltip(amountBox, "|cfffe35eeHow many times or what\namount you want to track?")

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- UPDATE VISIBILITY --

local function UpdateFieldVisibility()
    -- Disable all main input fields first
    idBox:SetEnabled(false)
    idBox:SetAlpha(0.3)
    npcBox:SetEnabled(false)
    npcBox:SetAlpha(0.3)
    emoteDrop:EnableMouse(false)
    emoteDrop.Button:EnableMouse(false)
    emoteDrop:SetAlpha(0.3)
    creatureDrop:EnableMouse(false)
    creatureDrop.Button:EnableMouse(false)
    creatureDrop:SetAlpha(0.3)
    
    -- Clear all field values each time a new type is selected
    idBox:SetText("Spell or Item")
    if not createPanel.selectedNpcID then
        npcBox:SetText("Target NPC")
    end
    UIDropDownMenu_SetSelectedValue(emoteDrop, nil)
    UIDropDownMenu_SetText(emoteDrop, "Emote")
    selectedEmote = nil
    UIDropDownMenu_SetSelectedValue(creatureDrop, nil)
    UIDropDownMenu_SetText(creatureDrop, "Creature")
    selectedCreature = nil

    -- Activation rules
    local rules = {
        emote = { "emote" },
        emotetarget = { "emote", "creature", "npc" },
        use = { "id" },
        usetarget = { "id", "creature", "npc" },
        loot = { "id" },
        kill = { "creature", "npc" },
        killwith = { "id", "creature", "npc" },
        crit = { "id" },
        crittarget = { "id", "creature", "npc" },
        damage = { "id" },
        regen = { "id" },
    }

    for _, key in ipairs(rules[selectedType] or {}) do
        if key == "id" then
            idBox:SetEnabled(true)
            idBox:SetAlpha(1)
        elseif key == "npc" then
            npcBox:SetEnabled(true)
            npcBox:SetAlpha(1)
        elseif key == "emote" then
            emoteDrop:EnableMouse(true)
            emoteDrop.Button:EnableMouse(true)
            emoteDrop:SetAlpha(1)
            if not selectedEmote then
                local first = emoteList[1]
                selectedEmote = first
                UIDropDownMenu_SetSelectedValue(emoteDrop, first)
                UIDropDownMenu_SetText(emoteDrop, first)
            end
        elseif key == "creature" then
            creatureDrop:EnableMouse(true)
            creatureDrop.Button:EnableMouse(true)
            creatureDrop:SetAlpha(1)
            if not selectedCreature then
                local first = creatureTypes[1]
                selectedCreature = first
                UIDropDownMenu_SetSelectedValue(creatureDrop, first)
                UIDropDownMenu_SetText(creatureDrop, first)
            end
        end
    end
    
    if selectedType == "emotetarget" or selectedType == "kill" or selectedType == "usetarget" or selectedType == "crittarget" or selectedType == "killwith" and selectedCreature ~= "npc" then
        selectedCreature = "Beast"
        UIDropDownMenu_SetSelectedValue(creatureDrop, "Beast")
        UIDropDownMenu_SetText(creatureDrop, "Beast")
        npcBox:SetEnabled(false)
        npcBox:SetAlpha(0.3)
    end

    -- Counter/Goal control logic
    if selectedType then
        counterCheck:SetEnabled(true)
        counterCheck:SetAlpha(1)

        if counterCheck:GetChecked() then
            amountBox:SetText("")
            amountBox:SetEnabled(false)
            amountBox:SetAlpha(0.3)
            upButton:Disable()
            downButton:Disable()
        else
            amountBox:SetText(goalAmount)
            amountBox:SetEnabled(true)
            amountBox:SetAlpha(1)
            upButton:Enable()
            downButton:Enable()
        end
    else
        counterCheck:SetEnabled(false)
        counterCheck:SetAlpha(0.3)
        amountBox:SetText("")
        amountBox:SetEnabled(false)
        amountBox:SetAlpha(0.3)
        upButton:Disable()
        downButton:Disable()
    end
end

-- MAIN DROPDOWN INITIALIZATION --
UIDropDownMenu_Initialize(typeDrop, function(self, level)
    for _, opt in ipairs(typeOptions) do
        local info = UIDropDownMenu_CreateInfo()
        info.text = opt.text
        info.value = opt.value
        info.func = function(selfArg)
            selectedType = selfArg.value
            UIDropDownMenu_SetSelectedValue(typeDrop, selfArg.value)
            UpdateFieldVisibility()

            if selectedType == "damage" or selectedType == "regen" then
                goalAmount = 1000
                amountBox:SetText(goalAmount)
            else
                goalAmount = 1
                amountBox:SetText(goalAmount)
            end
        end
        info.checked = function() return selectedType == opt.value end
        UIDropDownMenu_AddButton(info)
    end
        
    local future1 = UIDropDownMenu_CreateInfo()
    future1.text = "Track Deaths (Soon™)"
    future1.disabled = true
    future1.notCheckable = false
    future1.checked = false
    UIDropDownMenu_AddButton(future1)
       
    local future2 = UIDropDownMenu_CreateInfo()
    future2.text = "Track Currency (Soon™)"
    future2.disabled = true
    future2.notCheckable = false
    future2.checked = false
    UIDropDownMenu_AddButton(future2)
        
    local future3 = UIDropDownMenu_CreateInfo()
    future3.text = "Instance Runs (Soon™)"
    future3.disabled = true
    future3.notCheckable = false
    future3.checked = false
    UIDropDownMenu_AddButton(future3)
        
end)

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- CREATE - RESET - WAXSEAL --

-- RESET PANEL BUTTON --
local function ResetNewOathPanel()
    titleBox:SetText("Title: Max 30 characters.")
    titleBox:SetTextColor(0.5, 0.5, 0.5)
    titleBox:ClearFocus()

    descBox:ClearFocus()
    descBox:SetEnabled(true)
    descBox:SetAlpha(1)
    descBox:SetText("")
    SetupPlaceholder(descBox, "Description: Max 80 characters.")
    
    UIDropDownMenu_SetSelectedValue(typeDrop, nil)
    UIDropDownMenu_SetText(typeDrop, "Select an Objective")
    selectedType = nil
    UpdateFieldVisibility()

    iconSelectBtn:SetNormalTexture(134400)
    createPanel.selectedIcon = 134400
    
    zoneCheck:SetChecked(false)
    zoneDrop:EnableMouse(false)
    zoneDrop.Button:EnableMouse(false)
    zoneDrop:SetAlpha(0.3)
    UIDropDownMenu_SetSelectedValue(zoneDrop, nil)
    UIDropDownMenu_SetText(zoneDrop, "Select Zone")
    selectedZone = nil
    selectedSubzone = nil
    
    SetupPlaceholder(idBox, "Spell or Item")
    idBox:SetTextColor(0.5, 0.5, 0.5)
    createPanel.selectedItemID = nil
    createPanel.selectedSpellID = nil

    UIDropDownMenu_SetSelectedValue(emoteDrop, nil)
    UIDropDownMenu_SetText(emoteDrop, "Emote")
    selectedEmote = nil
    emoteDrop:EnableMouse(false)
    emoteDrop.Button:EnableMouse(false)
    emoteDrop:SetAlpha(0.3)

    SetupPlaceholder(npcBox, "Target NPC")
    npcBox:SetEnabled(false)
    npcBox:SetAlpha(0.3)
    
    counterCheck:SetChecked(false)
    isCounter = false
    goalAmount = 1
    amountBox:SetText("1")

    UIDropDownMenu_SetSelectedValue(creatureDrop, nil)
    UIDropDownMenu_SetText(creatureDrop, "Creature")
    selectedCreature = nil
    creatureDrop:EnableMouse(false)
    creatureDrop.Button:EnableMouse(false)
    creatureDrop:SetAlpha(0.3)
    
    SetTooltip(emoteDrop, "|cfffe35eeWhat gesture shall\nmark your oath?")
    SetTooltip(creatureDrop, "|cfffe35eeChoose the kind of creature\nyou intend to face.")
    SetTooltip(zoneDrop, "|cfffe35eeShall this oath be bound\nto a specific place?")

    if iconSelectorFrame and iconSelectorFrame:IsShown() then
        iconSelectorFrame:Hide()
    end
    if WanderBook.SealFrame and WanderBook.SealFrame:IsShown() then
        WanderBook.SealFrame:Hide()
    end
end

-- RESET --
local resetBtn = CreateFrame("Button", nil, createPanel)
resetBtn:SetSize(42, 40)
resetBtn:SetPoint("BOTTOM", createPanel, "BOTTOM", -63, 39)
--resetBtn:SetNormalTexture("Interface/Buttons/UI-RefreshButton")
resetBtn:SetNormalTexture("Interface\\AddOns\\WanderBook\\Media\\btn-yellow-reset-n.tga")
resetBtn:SetHighlightTexture("Interface\\AddOns\\WanderBook\\Media\\btn-yellow-reset-h.tga")
resetBtn:SetPushedTexture("Interface\\AddOns\\WanderBook\\Media\\btn-yellow-reset-d.tga")
resetBtn:SetScript("OnClick", function()
    PlaySound(SOUNDKIT.UI_IG_STORE_PAGE_NAV_BUTTON)
    ResetNewOathPanel()
end)

-- CREATE --
local createBtn = CreateFrame("Button", nil, createPanel)
createBtn:SetSize(126, 40)
createBtn:SetPoint("BOTTOM", createPanel, "BOTTOM", 24, 39)
--createBtn:SetNormalTexture("Interface/Buttons/UI-StopButton")
createBtn:SetNormalTexture("Interface\\AddOns\\WanderBook\\Media\\btn-green-big-n.tga")
createBtn:SetHighlightTexture("Interface\\AddOns\\WanderBook\\Media\\btn-green-big-h.tga")
createBtn:SetPushedTexture("Interface\\AddOns\\WanderBook\\Media\\btn-green-big-d.tga")
local cbLabel = createBtn:CreateFontString(nil, "OVERLAY", nil)
cbLabel:SetFont("Fonts\\FRIZQT__.TTF", 14, "")
cbLabel:SetTextColor(0.5, 1, 0.5)
cbLabel:SetPoint("CENTER", createBtn, "CENTER")
cbLabel:SetText("Create")

-- WAX SEAL CONFIRMATION --
local sealFrame = CreateFrame("Frame", nil, UIParent, "BackdropTemplate")
WanderBook.SealFrame = sealFrame
sealFrame:SetSize(160, 140)
sealFrame:SetPoint("TOP", createPanel, "BOTTOM", 0, 15)
sealFrame:SetBackdrop({
    bgFile = "Interface\\AddOns\\WanderBook\\Media\\seal-panel.tga",
    edgeFile = nil, -- Remove border or set a custom one
    tile = false,
    tileSize = 0,
    edgeSize = 0,
    insets = { left = 0, right = 0, top = 0, bottom = 0 }
})
--sealFrame:SetBackdropColor(0, 0, 0, 1)
sealFrame:Hide()

local sealBtn = CreateFrame("Button", nil, sealFrame)
sealBtn:SetSize(90, 90)
sealBtn:SetPoint("CENTER", -3, -3)
sealBtn:SetNormalTexture("Interface\\AddOns\\WanderBook\\Media\\btn-seal-n.tga")
sealBtn:SetHighlightTexture("Interface\\AddOns\\WanderBook\\Media\\btn-seal-h.tga")
sealBtn:SetPushedTexture("Interface\\AddOns\\WanderBook\\Media\\btn-seal-d.tga")

local pushed = sealBtn:GetPushedTexture()
pushed:ClearAllPoints()
pushed:SetPoint("TOPLEFT", 0, -2)
pushed:SetPoint("BOTTOMRIGHT", 0, -2)

sealBtn:SetScript("OnClick", function()
    local title = titleBox:GetText()
    if title == "Title: Max 30 characters." then title = "" end
    local desc = descBox:GetText()
    if desc == "Description: Max 80 characters." then desc = "" end

    if not selectedType or title == "" then return end

    local cmd = string.format('type=%s title="%s"', selectedType, title)

    if desc ~= "" then
        cmd = cmd .. string.format(' desc="%s"', desc)
    end
    if createPanel.selectedIcon then
        cmd = cmd .. string.format(' icon=%d', createPanel.selectedIcon)
    end
        
    if idBox:IsEnabled() and idBox:GetText() ~= "" and idBox:GetText() ~= "Spell or Item" then 
        local rawInput = idBox:GetText():gsub("^%s*(.-)%s*$", "%1")
        local idNum = tonumber(rawInput)

        if createPanel.selectedType == "item" and createPanel.selectedItemID then
            cmd = cmd .. string.format(' item=%d', createPanel.selectedItemID)
        elseif createPanel.selectedType == "spell" and createPanel.selectedSpellID then
            cmd = cmd .. string.format(' spell=%d', createPanel.selectedSpellID)
        else
            -- Fallback for manual typing
            if idNum then
                cmd = cmd .. string.format(' token=%d', idNum)
            else
                cmd = cmd .. string.format(' token="%s"', rawInput)
            end
        end
    end
        
    if selectedCreature == "npc" then
        if createPanel.selectedNpcID then
            cmd = cmd .. string.format(' npc=%d', createPanel.selectedNpcID)
        elseif npcBox:GetText() ~= "" and npcBox:GetText() ~= "Target NPC" then
            cmd = cmd .. string.format(' npc="%s"', npcBox:GetText())
        end
    elseif selectedCreature then
        cmd = cmd .. string.format(' creature=%s', selectedCreature)
    end
        
    if selectedEmote then
        cmd = cmd .. string.format(' emote=%s', selectedEmote)
    end
    if zoneCheck:GetChecked() and selectedZone then
        cmd = cmd .. string.format(' zone="%s"', selectedZone)
    end
    if counterCheck:GetChecked() then
        cmd = cmd .. " goal=counter"
    else
        cmd = cmd .. string.format(" goal=%d", goalAmount)
    end

    -- Submit to Core
    SlashCmdList["MAKEOATH"](cmd)
    -- Reindex all current objectives
    if WanderBook.objectives then
        for index, obj in ipairs(WanderBook.objectives) do
            obj.id = index
        end
    end
        
    -- Reindex all current objectives
    if WanderBook.objectives then
        for index, obj in ipairs(WanderBook.objectives) do
            obj.id = index
        end
    end
        
    if WanderBookUI and WanderBookUI:IsShown() then
        WanderBookUI:ShowObjectives()
    end
    ResetNewOathPanel()
    sealFrame:Hide()
    createPanel:Hide()
end)

-- CREATE BUTTON --
createBtn:SetScript("OnClick", function()
    -- Validation checks -- Red color code: |cffff4444 --
    local title = titleBox:GetText()
    if title == "Title: Max 30 characters." then title = "" end

    local desc = descBox:GetText()
    if desc == "Description: Max 80 characters." then desc = "" end

    if title == "" or desc == "" or createPanel.selectedIcon == 134400 then 
        SetMessage("|cffff4444Your oath is incomplete. It needs a name,\ndescription, icon and a goal.|r", 3)
        return
    end
        
    if idBox:IsEnabled() and (idBox:GetText() == "" or idBox:GetText() == "Spell or Item") then
        SetMessage("|cffff4444You must offer the Spell or Item name or ID.\nThe Book cannot sense what is not named|r", 3)
        return
    end

if idBox:IsEnabled() and idBox:GetText() ~= "" and idBox:GetText() ~= "Spell or Item" then
    local rawInput = idBox:GetText():trim()
    local idNum = tonumber(rawInput)
    local hasValidID = false

    if idNum then
        hasValidID = C_Spell.GetSpellInfo(idNum) ~= nil or C_Item.GetItemNameByID(idNum) ~= nil
    else
        if IDCatcher_ResolveSpellIDByName and IDCatcher_ResolveSpellIDByName(rawInput) then
            hasValidID = true
        elseif IDCatcher_ResolveItemIDByName and IDCatcher_ResolveItemIDByName(rawInput) then
            hasValidID = true
        else
            -- Final fallback to C_Item
            local fallbackItemID = C_Item.GetItemInfoInstant(rawInput)
            hasValidID = fallbackItemID ~= nil
        end
    end

    if not hasValidID then
        SetMessage("|cffff4444I don't recognize that name,\ncan you provide an ID? Try WoWhead...|r", 5)
        return
    end
end

          
    if not selectedType and not zoneCheck:GetChecked() then
        SetMessage("|cffff4444Every oath needs a purpose.\nChoose a goal... or a place.|r", 3)
        return
    end

    -- NPC ID required
    if npcBox:IsEnabled() and (npcBox:GetText() == "" or npcBox:GetText() == "Target NPC") then
        SetMessage("|cffff4444Target the NPC. The Book does\nnot guess who you seek.|r", 3)
        return
    end
    PlaySound(SOUNDKIT.IG_ABILITY_PAGE_TURN)
    sealFrame:Show()
end)

-- HIDE SEAL BUTTON IF COMPONENT CHANGES --
local function HideSealOnChange()
    if WanderBook.SealFrame and WanderBook.SealFrame:IsShown() then
        WanderBook.SealFrame:Hide()
    end
end

local sealWatchers = {
    titleBox, descBox, idBox, npcBox, amountBox,
    typeDrop, zoneDrop, emoteDrop, creatureDrop,
    zoneCheck, counterCheck,
    iconSelectBtn
}

for _, widget in ipairs(sealWatchers) do
    if widget.HookScript then
        if widget.GetObjectType and widget:GetObjectType() == "EditBox" then
            widget:HookScript("OnEditFocusGained", HideSealOnChange)
        elseif widget.GetObjectType and widget:GetObjectType() == "Button" then
            widget:HookScript("OnClick", HideSealOnChange)
        elseif widget.Button and widget.Button.HookScript then
            -- Watch dropdown button click
            widget.Button:HookScript("OnClick", HideSealOnChange)
        end
    end
end

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------
-- TOGGLE NEW OATH PANEL FUNCTION --

function WanderBook.ToggleNewOathPanel()
    if createPanel:IsShown() then
        createPanel:Hide()
    else
        createPanel:Show()
    end
end

WanderBook.NewOathPanel = createPanel

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------

-- SPELL/ITEM SHIFT+CLICK INSERT HOOK --
hooksecurefunc("ChatEdit_InsertLink", function(link)
    if type(link) ~= "string" then return end

    --print("|cff00ffff[SHIFT+CLICK] Raw link:|r", link)

    -- ID field
    if idBox and idBox:HasFocus() then
        local spellID = link:match("Hspell:(%d+):")
        if spellID then
            spellID = tonumber(spellID)
            --print("|cff00ff00[SHIFT+CLICK] Detected spellID:|r", spellID)
            local spellInfo = C_Spell.GetSpellInfo(spellID)
            local name = spellInfo and spellInfo.name
            if name then
                idBox:SetText(name)
                idBox:SetTextColor(1, 1, 1)
                local icon = C_Spell.GetSpellTexture(spellID)
                if icon then
                    iconSelectBtn:SetNormalTexture(icon)
                    createPanel.selectedIcon = icon
                end
                createPanel.selectedType = "spell"
                createPanel.selectedSpellID = spellID
            end
            return
        end

        local itemID = link:match("Hitem:(%d+):")
        if itemID then
            itemID = tonumber(itemID)
            local name = C_Item.GetItemNameByID(itemID)
            if name then
                -- Usability check for non-loot objectives
                if selectedType ~= "loot" then
                    local _, useSpellID = GetItemSpell(itemID)
                    if not useSpellID then
                        SetMessage("|cffff4444That item has no Use:\n...give me another.|r", 3)
                        idBox:SetText("")
                        createPanel.selectedItemID = nil
                        return
                    end
                end
                idBox:SetText(name)
                idBox:SetTextColor(1, 1, 1)
                local icon = select(10, C_Item.GetItemInfo(itemID))
                if icon then
                    iconSelectBtn:SetNormalTexture(icon)
                    createPanel.selectedIcon = icon
                end
                createPanel.selectedItemID = itemID
                createPanel.selectedType = "item"
            end
            return
        end
        -- If no ID match, show that
        --print("|cffff0000[SHIFT+CLICK] No itemID or spellID detected from link.|r")
    end

    -- Title or Description field
    local insertText = link:match("%[(.-)%]")
    if insertText then
        if titleBox and titleBox:HasFocus() then
            titleBox:Insert(insertText)
        elseif descBox and descBox:HasFocus() then
            descBox:Insert(insertText)
        end
    end
end)

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------

-- NPC ID FIELD LIVE TARGET UPDATER --
local npcUpdaterFrame = CreateFrame("Frame")
npcUpdaterFrame:RegisterEvent("PLAYER_TARGET_CHANGED")
npcUpdaterFrame:SetScript("OnEvent", function()
    if not createPanel:IsShown() then return end
    if selectedCreature ~= "npc" then return end
    if not npcBox:IsEnabled() then return end

    local guid = UnitGUID("target")
    if guid and guid:match("Creature") then
        local _, _, _, _, _, npcID = strsplit("-", guid)
        if npcID and tonumber(npcID) then
            local name = UnitName("target")
            npcBox:SetText(name or npcID)
            npcBox:SetTextColor(1, 1, 1)
            createPanel.selectedNpcID = tonumber(npcID)
            createPanel.selectedNpcName = name
            return
        end
    end

    -- If no valid creature or ID, clear the NPC field completely
    npcBox:SetText("Target NPC")
    npcBox:SetTextColor(0.5, 0.5, 0.5)
    createPanel.selectedNpcID = nil
    createPanel.selectedNpcName = nil

end)

--------------------------------------------------------------------------------------
--------------------------------------------------------------------------------------