--[[
	Deconstruct Module for ElvUI (WoW 3.3.5a / Ascension)
	Adapted from ElvUI_SLE retail version
	
	This module provides functionality to disenchant, mill, prospect, and unlock items
	directly from bags by creating an overlay button when mousing over compatible items.
]] --
local E, L, V, P, G = unpack(select(2, ...))
local B = E:GetModule("Bags")

local D = B:NewModule("Deconstruct", "AceHook-3.0", "AceEvent-3.0")
local Search = E.Libs.ItemSearch

-- Lua functions
local _G = _G
local format, strfind, type, tostring = format, strfind, type, tostring
local pairs, select, unpack = pairs, select, unpack

-- WoW API
local GetTradeTargetItemLink = GetTradeTargetItemLink
local InCombatLockdown = InCombatLockdown
local GetContainerItemLink = GetContainerItemLink
local GetSpellInfo = GetSpellInfo
local GetItemInfo = GetItemInfo
local GetItemCount = GetItemCount
local CreateFrame = CreateFrame
local GameTooltip = GameTooltip

-- Constants (with fallbacks in case they're not loaded yet)
local LOCKED = LOCKED or "Locked"
local VIDEO_OPTIONS_ENABLED = VIDEO_OPTIONS_ENABLED or "Enabled"
local VIDEO_OPTIONS_DISABLED = VIDEO_OPTIONS_DISABLED or "Disabled"

-- Module variables
D.DeconstructMode = false
D.ItemTable = {
	['DoNotDE'] = {
		['49715'] = true, -- Rose helm
		['44731'] = true, -- Rose offhand
		['21524'] = true, -- Red winter hat
		['51525'] = true, -- Green winter hat
		['70923'] = true, -- Sweater
		['34486'] = true, -- Orgrimmar achievement fish
		['11287'] = true, -- Lesser Magic Wand
		['11288'] = true, -- Greater Magic Wand
		['11289'] = true, -- Lesser Mystic Wand
		['11290'] = true, -- Greater Mystic Wand
		['4614'] = true, -- Pendant of Myzrael
		['20406'] = true, -- Twilight Cultist Mantle
		['20407'] = true, -- Twilight Cultist Robe
		['20408'] = true, -- Twilight Cultist Cowl
		['21766'] = true, -- Opal Necklace of Impact
	},
	['Cooking'] = {
		['46349'] = true -- Chef's Hat
	},
	['Fishing'] = {
		['19022'] = true, -- Nat Pagle's Extreme Angler FC-5000
		['19970'] = true, -- Arcanite Fishing Pole
		['25978'] = true, -- Seth's Graphite Fishing Pole
		['44050'] = true, -- Mastercraft Kalu'ak Fishing Pole
		['45858'] = true, -- Nat's Lucky Fishing Pole
		['45991'] = true, -- Bone Fishing Pole
		['45992'] = true -- Jeweled Fishing Pole
	}
}

D.Keys = {}
D.BlacklistDE = {}
D.BlacklistLOCK = {}
D.BlacklistDEPatterns = {}
D.BlacklistLOCKPatterns = {}

-- Profession spell names
D.DEname = GetSpellInfo(13262) -- Disenchant
D.MILLname = GetSpellInfo(51005) -- Milling
D.PROSPECTname = GetSpellInfo(31252) -- Prospecting
D.LOCKname = GetSpellInfo(1804) -- Pick Lock

-- Check if player has any relevant professions
function D:HasRelevantProfession()
	if D.HasEnchanting then return true end
	if D.HasInscription then return true end
	if D.HasJewelcrafting then return true end
	if D.HasPickLock then return true end
	return false
end

-- Update button state (enabled/disabled)
function D:UpdateButtonState()
	if not D.DeconstructButton then return end
	
	local hasProf = D:HasRelevantProfession()
	
	if hasProf then
		D.DeconstructButton:Enable()
		D.DeconstructButton:SetAlpha(1)
	else
		D.DeconstructButton:Disable()
		D.DeconstructButton:SetAlpha(0.5)
	end
end

-- Check which professions the player has
function D:UpdateProfessions()
	D.HasEnchanting = false
	D.HasInscription = false
	D.HasJewelcrafting = false
	D.HasPickLock = false

	if D.DEname and GetSpellInfo(D.DEname) then D.HasEnchanting = true end
	if D.MILLname and GetSpellInfo(D.MILLname) then D.HasInscription = true end
	if D.PROSPECTname and GetSpellInfo(D.PROSPECTname) then D.HasJewelcrafting = true end
	if D.LOCKname and GetSpellInfo(D.LOCKname) then D.HasPickLock = true end
end

-- Helper function to check if player has a skeleton key
local function HaveKey() for key in pairs(D.Keys) do if GetItemCount(key) > 0 then return key end end end

function D:Blacklisting(skill)
	if skill == 'DE' then
		D:BuildBlacklistDE()
	elseif skill == 'LOCK' then
		D:BuildBlacklistLOCK()
	end
end

function D:BuildBlacklistDE()
	wipe(D.BlacklistDE)
	wipe(D.BlacklistDEPatterns)
	local db = E.db.bags.deconstructBlacklist or {}
	local g = E.global.bags.deconstructBlacklist or {}

	for key, value in pairs(db) do
		if value and value ~= "" then
			local entry = tostring(value)
			entry = entry:match("^%s*(.-)%s*$") or entry
			local itemName = GetItemInfo(entry)
			if itemName then
				D.BlacklistDE[itemName] = true
			else
				table.insert(D.BlacklistDEPatterns, entry)
			end
		end
	end

	for key, value in pairs(g) do
		if value and value ~= "" then
			local entry = tostring(value)
			entry = entry:match("^%s*(.-)%s*$") or entry
			local itemName = GetItemInfo(entry)
			if itemName then
				D.BlacklistDE[itemName] = true
			else
				table.insert(D.BlacklistDEPatterns, entry)
			end
		end
	end
end

function D:BuildBlacklistLOCK()
	wipe(D.BlacklistLOCK)
	wipe(D.BlacklistLOCKPatterns)
	local db = E.db.bags.lockBlacklist or {}
	local g = E.global.bags.lockBlacklist or {}

	for key, value in pairs(db) do
		if value and value ~= "" then
			local entry = tostring(value)
			entry = entry:match("^%s*(.-)%s*$") or entry
			local itemName = GetItemInfo(entry)
			if itemName then
				D.BlacklistLOCK[itemName] = true
			else
				table.insert(D.BlacklistLOCKPatterns, entry)
			end
		end
	end

	for key, value in pairs(g) do
		if value and value ~= "" then
			local entry = tostring(value)
			entry = entry:match("^%s*(.-)%s*$") or entry
			local itemName = GetItemInfo(entry)
			if itemName then
				D.BlacklistLOCK[itemName] = true
			else
				table.insert(D.BlacklistLOCKPatterns, entry)
			end
		end
	end
end

-- Check if item can be disenchanted
function D:IsBreakable(itemId, itemName, itemLink)
	if not itemId then return false end
	if type(itemId) == "number" then itemId = tostring(itemId) end

	-- Check blacklists
	if D.ItemTable['DoNotDE'][itemId] then return false end
	if D.ItemTable['Cooking'][itemId] then return false end
	if D.ItemTable['Fishing'][itemId] then return false end
	if itemName and D.BlacklistDE[itemName] then return false end

	-- Check pattern blacklist using LibItemSearch (supports full search syntax)
	for _, query in ipairs(D.BlacklistDEPatterns or {}) do
		if query and query ~= "" then
			local ok, result = pcall(Search.Matches, Search, itemLink or itemName, query)
			if ok and result then
				return false
			end
		end
	end

	return true
end

-- Check if item is disenchantable
function D:IsDisenchantable(itemId, itemName, itemLink, itemRarity, itemType, itemEquipLoc)
	if not itemId or not itemName or not D.HasEnchanting then return false end

	-- Quality: 2=Uncommon, 3=Rare, 4=Epic
	if not itemRarity or itemRarity < 2 or itemRarity > 4 then return false end
	if itemType ~= "Armor" and itemType ~= "Weapon" then return false end
	if not itemEquipLoc or itemEquipLoc == "" then return false end

	return true
end

-- Check if item can be prospected
function D:IsProspectable(itemId)
	if not itemId or not D.HasJewelcrafting then return false end

	-- Prospectable ores in WotLK (3.3.5a)
	local prospectableOres = {
		[2770] = true, -- Copper Ore
		[2771] = true, -- Tin Ore
		[2772] = true, -- Iron Ore
		[3858] = true, -- Mithril Ore
		[10620] = true, -- Thorium Ore
		[23424] = true, -- Fel Iron Ore
		[23425] = true, -- Adamantite Ore
		[36909] = true, -- Cobalt Ore
		[36912] = true, -- Saronite Ore
		[36910] = true -- Titanium Ore
	}

	return prospectableOres[tonumber(itemId)] or false
end

-- Check if item can be milled
function D:IsMillable(itemId)
	if not itemId or not D.HasInscription then return false end

	-- Millable herbs in WotLK (3.3.5a)
	local millableHerbs = {
		[765] = true, -- Silverleaf
		[2447] = true, -- Peacebloom
		[2449] = true, -- Earthroot
		[785] = true, -- Mageroyal
		[2450] = true, -- Briarthorn
		[2452] = true, -- Swiftthistle
		[2453] = true, -- Bruiseweed
		[3820] = true, -- Stranglekelp
		[3369] = true, -- Grave Moss
		[3356] = true, -- Kingsblood
		[3357] = true, -- Liferoot
		[3818] = true, -- Fadeleaf
		[3821] = true, -- Goldthorn
		[3358] = true, -- Khadgar's Whisker
		[3819] = true, -- Dragon's Teeth (Wintersbite)
		[8836] = true, -- Arthas' Tears
		[8838] = true, -- Sungrass
		[8839] = true, -- Blindweed
		[8845] = true, -- Ghost Mushroom
		[8846] = true, -- Gromsblood
		[13464] = true, -- Golden Sansam
		[13463] = true, -- Dreamfoil
		[13465] = true, -- Mountain Silversage
		[13466] = true, -- Plaguebloom
		[13467] = true, -- Icecap
		[22785] = true, -- Felweed
		[22786] = true, -- Dreaming Glory
		[22787] = true, -- Ragveil
		[22789] = true, -- Terocone
		[22790] = true, -- Ancient Lichen
		[22791] = true, -- Netherbloom
		[22792] = true, -- Nightmare Vine
		[22793] = true, -- Mana Thistle
		[36901] = true, -- Goldclover
		[36903] = true, -- Adder's Tongue
		[36904] = true, -- Tiger Lily
		[36905] = true, -- Lichbloom
		[36906] = true, -- Icethorn
		[36907] = true, -- Talandra's Rose
		[37921] = true, -- Deadnettle
		[39970] = true -- Fire Leaf
	}

	return millableHerbs[tonumber(itemId)] or false
end

-- Check if item is currently locked (scan tooltip)
function D:IsUnlockable(itemLink)
	if not itemLink then return false end

	-- Scan tooltip for "Locked" text
	GameTooltip:SetOwner(UIParent, "ANCHOR_NONE")
	GameTooltip:SetHyperlink(itemLink)

	for i = 2, GameTooltip:NumLines() do
		local line = _G["GameTooltipTextLeft" .. i]
		if line then
			local text = line:GetText()
			if text and strfind(text, LOCKED) then
				GameTooltip:Hide()
				return true
			end
		end
	end

	GameTooltip:Hide()
	return false
end

-- Apply the deconstruct overlay to a bag slot
function D:ApplyDeconstruct(itemLink, itemId, spell, spellType, r, g, b, slot)
	if not slot then return end
	if slot == D.DeconstructionReal then return end

	local bag = slot:GetParent():GetID()

	-- Verify the bag and slot exist in ElvUI's bag or bank structure
	local validBag = (B.BagFrame and B.BagFrame.Bags and B.BagFrame.Bags[bag]) or (B.BankFrame and B.BankFrame.Bags and B.BankFrame.Bags[bag])
	if not validBag then return end

	D.DeconstructionReal.Bag = bag
	D.DeconstructionReal.Slot = slot:GetID()

	-- Check if in trade window
	if GetTradeTargetItemLink and GetTradeTargetItemLink(7) == itemLink then
		return
	elseif GetContainerItemLink(bag, slot:GetID()) == itemLink then
		D.DeconstructionReal.ID = itemId
		D.DeconstructionReal:SetAttribute('type1', spellType)
		D.DeconstructionReal:SetAttribute(spellType, spell)
		D.DeconstructionReal:SetAttribute('target-bag', D.DeconstructionReal.Bag)
		D.DeconstructionReal:SetAttribute('target-slot', D.DeconstructionReal.Slot)
		D.DeconstructionReal:SetAllPoints(slot)
		D.DeconstructionReal:Show()

		-- Apply visual effect (ActionButton_ShowOverlayGlow confirmed on Ascension)
		ActionButton_ShowOverlayGlow(D.DeconstructionReal)
	end
end

-- Get deconstruct mode status text
function D:GetDeconMode()
	local text
	if D.DeconstructMode then
		text = '|cff00FF00 ' .. VIDEO_OPTIONS_ENABLED .. '|r'
	else
		text = '|cffFF0000 ' .. VIDEO_OPTIONS_DISABLED .. '|r'
	end
	return text
end

-- Toggle deconstruct mode (called from button click)
function D:ToggleMode()
	-- Don't toggle if player doesn't have required professions
	if not D:HasRelevantProfession() then return end
	
	D.DeconstructMode = not D.DeconstructMode

	if D.DeconstructButton then
		local normalTex = D.DeconstructButton:GetNormalTexture()
		if normalTex then
			if D.DeconstructMode then
				normalTex:SetTexture([[Interface\ICONS\INV_Enchant_EssenceCosmicGreater]])
				ActionButton_ShowOverlayGlow(D.DeconstructButton)
			else
				normalTex:SetTexture([[Interface\ICONS\INV_Rod_Enchantedcobalt]])
				ActionButton_HideOverlayGlow(D.DeconstructButton)
			end
		end

		D.DeconstructButton.ttText2 = format(L["Deconstruct Mode Desc"] .. "\n" .. L["Current state: %s."], D:GetDeconMode())
		if GameTooltip:IsOwned(D.DeconstructButton) then B.Tooltip_Show(D.DeconstructButton) end
	end

	-- Update both bag and bank slots
	if B.BagFrame then D:UpdateBagSlots(B.BagFrame, D.DeconstructMode) end
	if B.BankFrame then D:UpdateBagSlots(B.BankFrame, D.DeconstructMode) end
end

-- Create the actual deconstruct button overlay
function D:ConstructRealDecButton()
	D.DeconstructionReal = CreateFrame('Button', 'ElvUI_DeconReal', E.UIParent, 'SecureActionButtonTemplate')
	D.DeconstructionReal:SetScript('OnEvent', function(obj, event, ...) obj[event](obj, ...) end)
	D.DeconstructionReal:RegisterForClicks('AnyUp', 'AnyDown')
	D.DeconstructionReal:SetFrameStrata('TOOLTIP')

	D.DeconstructionReal.OnLeave = function(frame)
		if InCombatLockdown() then
			frame:SetAlpha(0)
			frame:RegisterEvent('PLAYER_REGEN_ENABLED')
		else
			frame:ClearAllPoints()
			frame:SetAlpha(1)
			if GameTooltip then GameTooltip:Hide() end

			-- Stop visual effects
			ActionButton_HideOverlayGlow(frame)

			frame:Hide()
		end
	end

	D.DeconstructionReal.SetTip = function(f)
		GameTooltip:SetOwner(f, 'ANCHOR_LEFT', 0, 4)
		GameTooltip:ClearLines()
		GameTooltip:SetBagItem(f.Bag, f.Slot)
	end

	D.DeconstructionReal:SetScript('OnEnter', D.DeconstructionReal.SetTip)
	D.DeconstructionReal:SetScript('OnLeave', function() D.DeconstructionReal:OnLeave() end)
	D.DeconstructionReal:Hide()

	function D.DeconstructionReal:PLAYER_REGEN_ENABLED()
		self:UnregisterEvent('PLAYER_REGEN_ENABLED')
		D.DeconstructionReal:OnLeave()
	end
end

-- Parse tooltip to determine if item should show deconstruct button
function D:DeconstructParser()
	if not D.DeconstructMode then return end
	if not GameTooltip:IsVisible() then return end

	local owner = GameTooltip:GetOwner()
	if not owner then return end

	local ownerName = owner.GetName and owner:GetName()
	if not ownerName then return end

	-- Only process ElvUI bag and bank slots
	if not (strfind(ownerName, 'ElvUI_ContainerFrameBag') or strfind(ownerName, 'ElvUI_BankContainerFrameBag')) then return end

	-- Get the bag and slot from the owner
	local bag, slot
	if owner.GetParent then
		local parent = owner:GetParent()
		if parent.GetID then bag = parent:GetID() end
	end
	if owner.GetID then slot = owner:GetID() end

	if not bag or not slot then return end

	local itemLink = GetContainerItemLink(bag, slot)
	if not itemLink then return end

	local itemId = tonumber(itemLink:match("item:(%d+)"))
	if not itemId then return end

	local itemName, _, itemRarity, _, _, itemType, itemSubType, _, itemEquipLoc = GetItemInfo(itemId)

	if InCombatLockdown() then return end

	-- Check what can be done with this item
	local r, g, b

	-- Check for lockboxes
	local hasKey = HaveKey()
	if (D.HasPickLock or hasKey) and D:IsUnlockable(itemLink) then
		-- Skip if lockbox is blacklisted (exact name or pattern)
		if itemName then
			if D.BlacklistLOCK[itemName] then
				return
			end
			for _, query in ipairs(D.BlacklistLOCKPatterns or {}) do
				if query and query ~= "" then
					local ok, result = pcall(Search.Matches, Search, itemLink, query)
					if ok and result then
						return
					end
				end
			end
		end

		r, g, b = 0, 1, 1
		if D.HasPickLock then
			D:ApplyDeconstruct(itemLink, itemId, D.LOCKname, 'spell', r, g, b, owner)
		elseif hasKey then
			D:ApplyDeconstruct(itemLink, itemId, hasKey, 'item', r, g, b, owner)
		end
		return
	end

	-- Check for prospectable ores (Jewelcrafting only)
	if D.HasJewelcrafting and D:IsProspectable(itemId) then
		r, g, b = 1, 0.5, 0
		D:ApplyDeconstruct(itemLink, itemId, D.PROSPECTname, 'spell', r, g, b, owner)
		return
	end

	-- Check for millable herbs (Inscription only)
	if D.HasInscription and D:IsMillable(itemId) then
		r, g, b = 0, 1, 0
		D:ApplyDeconstruct(itemLink, itemId, D.MILLname, 'spell', r, g, b, owner)
		return
	end

	-- Check for disenchantable items (Enchanting only)
	if D.HasEnchanting and D:IsDisenchantable(itemId, itemName, itemLink, itemRarity, itemType, itemEquipLoc) then
		if D:IsBreakable(itemId, itemName, itemLink) then
			r, g, b = 0.5, 0, 1
			D:ApplyDeconstruct(itemLink, itemId, D.DEname, 'spell', r, g, b, owner)
			return
		end
	end
end

-- Check if an item can be processed (disenchant/mill/prospect/unlock)
function D:CanProcessItem(itemLink, hasKey)
	if not itemLink then return false end

	local itemId = tonumber(itemLink:match("item:(%d+)"))
	if not itemId then return false end

	local itemName, _, itemRarity, _, _, itemType, _, _, itemEquipLoc = GetItemInfo(itemId)

	-- Check lockboxes (Rogues only)
	if (D.HasPickLock or hasKey) and D:IsUnlockable(itemLink) then
		if itemName then
			if D.BlacklistLOCK[itemName] then
				return false
			end
			for _, query in ipairs(D.BlacklistLOCKPatterns or {}) do
				if query and query ~= "" then
					local ok, result = pcall(Search.Matches, Search, itemLink, query)
					if ok and result then
						return false
					end
				end
			end
		end
		return true
	end

	-- Check prospectable (Jewelcrafting only)
	if D.HasJewelcrafting and D:IsProspectable(itemId) then return true end

	-- Check millable (Inscription only)
	if D.HasInscription and D:IsMillable(itemId) then return true end

	-- Check disenchantable (Enchanting only)
	if D.HasEnchanting and D:IsDisenchantable(itemId, itemName, itemLink, itemRarity, itemType, itemEquipLoc) then
		if D:IsBreakable(itemId, itemName, itemLink) then return true end
	end

	return false
end

-- Update all bag/bank slots to dim non-processable items
function D:UpdateBagSlots(frame, isActive)
	if not frame or not frame.Bags then return end

	local hasKey = HaveKey()
	for _, bagID in ipairs(frame.BagIDs) do
		if frame.Bags[bagID] then
			for slotID = 1, GetContainerNumSlots(bagID) do
				local slot = frame.Bags[bagID][slotID]
				if slot then
					if isActive then
						-- Dim items that can't be processed
						local itemLink = GetContainerItemLink(bagID, slotID)
						if itemLink and D:CanProcessItem(itemLink, hasKey) then
							slot:SetAlpha(1)
						else
							slot:SetAlpha(0.3)
						end
					else
						-- Restore normal alpha
						slot:SetAlpha(1)
					end
				end
			end
		end
	end
end

-- Helper function to create and setup the deconstruct button
local function CreateDeconstructButton(bagFrame)
	if not bagFrame or not bagFrame.holderFrame then return end
	if bagFrame.deconstructButton then return end -- Already created

	-- Create the button
	local button = CreateFrame("Button", nil, bagFrame.holderFrame)
	button:Size(16 + E.Border)
	button:SetTemplate()
	button:Point("RIGHT", bagFrame.vendorGraysButton, "LEFT", -5, 0)
	button:SetNormalTexture("Interface\\ICONS\\INV_Rod_Enchantedcobalt")
	button:GetNormalTexture():SetTexCoord(unpack(E.TexCoords))
	button:GetNormalTexture():SetInside()
	button:SetPushedTexture("Interface\\ICONS\\INV_Rod_Enchantedcobalt")
	button:GetPushedTexture():SetTexCoord(unpack(E.TexCoords))
	button:GetPushedTexture():SetInside()
	button:StyleButton(nil, true)
	button.ttText = L["Deconstruct Mode"]
	button.ttText2 = format(L["Deconstruct Mode Desc"] .. "\n" .. L["Current state: %s."], D:GetDeconMode())
	button:SetScript("OnEnter", B.Tooltip_Show)
	button:SetScript("OnLeave", GameTooltip_Hide)
	button:SetScript("OnClick", function() D:ToggleMode() end)

	bagFrame.deconstructButton = button
	D.DeconstructButton = button

	-- Re-anchor the search box to the deconstruct button
	if bagFrame.editBox then
		bagFrame.editBox:ClearAllPoints()
		bagFrame.editBox:Point("BOTTOMLEFT", bagFrame.holderFrame, "TOPLEFT", (E.Border * 2) + 18, E.Border * 2 + 2)
		bagFrame.editBox:Point("RIGHT", bagFrame.deconstructButton, "LEFT", -5, 0)
	end
end

-- Helper function to setup button and hooks (called once when bags are first opened)
local function SetupDeconstructButton()
	if D.DeconstructButton then return end

	-- Update professions first
	D:UpdateProfessions()

	if not B.BagFrame then return end

	-- Create the button (always show if module is enabled)
	CreateDeconstructButton(B.BagFrame)
	
	-- Update button state (enabled/disabled)
	D:UpdateButtonState()

	-- Only create the real deconstruct button and hooks once
	if not D.DeconstructionReal then
		D:ConstructRealDecButton()

		-- Hook GameTooltip to detect when mousing over items
		GameTooltip:HookScript('OnShow', function() D:DeconstructParser() end)
		GameTooltip:HookScript('OnUpdate', function() D:DeconstructParser() end)
	end

	-- Hide deconstruct mode when bags close
	B.BagFrame:HookScript('OnHide', function()
		D.DeconstructMode = false
		if D.DeconstructButton then
			local normalTex = D.DeconstructButton:GetNormalTexture()
			if normalTex then normalTex:SetTexture([[Interface\ICONS\INV_Rod_Enchantedcobalt]]) end
			ActionButton_HideOverlayGlow(D.DeconstructButton)
		end
		if B.BagFrame then D:UpdateBagSlots(B.BagFrame, false) end
		if B.BankFrame then D:UpdateBagSlots(B.BankFrame, false) end
		if D.DeconstructionReal then D.DeconstructionReal:OnLeave() end
	end)
end

-- Initialize the module
function D:Initialize()
	if not E.private.bags.enable then return end
	if not E.db.bags.deconstruct then return end -- Check if deconstruct is enabled

	-- Hook into Layout to setup button for bags and reapply dimming
	hooksecurefunc(B, "Layout", function(_, isBank)
		if not isBank then if B.BagFrame and not D.DeconstructButton then E:Delay(0.1, function() SetupDeconstructButton() end) end end

		-- Reapply dimming after layout (layout resets slot alpha)
		if D.DeconstructMode then
			E:Delay(0.05, function()
				if B.BagFrame then D:UpdateBagSlots(B.BagFrame, true) end
				if B.BankFrame then D:UpdateBagSlots(B.BankFrame, true) end
			end)
		end
	end)

	-- Build blacklists
	D:Blacklisting('DE')
	D:Blacklisting('LOCK')

	-- Register events
	D:RegisterEvent('BAG_UPDATE')
	D:RegisterEvent('SKILL_LINES_CHANGED')

	-- If bag frame already exists, setup button now
	if B.BagFrame and not D.DeconstructButton then E:Delay(0.1, function() SetupDeconstructButton() end) end
end

-- Handle SKILL_LINES_CHANGED event
function D:SKILL_LINES_CHANGED()
	D:UpdateProfessions()

	-- Update button state (enabled/disabled) based on professions
	D:UpdateButtonState()
end

-- Handle BAG_UPDATE event
function D:BAG_UPDATE()
	if D.DeconstructMode then
		if B.BagFrame then D:UpdateBagSlots(B.BagFrame, true) end
		if B.BankFrame then D:UpdateBagSlots(B.BankFrame, true) end
	end
end

-- Wait for ElvUI to fully load before initializing
hooksecurefunc(B, "Initialize", function() D:Initialize() end)
