-- ApiVault safe-pattern snippet library. Added in v1.2.0 must-have tooling rebuild.
-- Documentation/snippet metadata only. Snippets are not executed automatically.
local addonName, ApiVault = ...

ApiVault.SnippetLibrary = ApiVault.SnippetLibrary or {}
local Library = ApiVault.SnippetLibrary

Library.snippets = {
	{
		key = "savedvariables-defaults",
		title = "SavedVariables Defaults",
		risk = "safe",
		body = [[
local ADDON_NAME, ns = ...

local defaults = {
    schemaVersion = 1,
    settings = {},
}

local function CopyDefaults(src, dst)
    for key, value in pairs(src) do
        if type(value) == "table" then
            dst[key] = dst[key] or {}
            CopyDefaults(value, dst[key])
        elseif dst[key] == nil then
            dst[key] = value
        end
    end
end

local frame = CreateFrame("Frame")
frame:RegisterEvent("ADDON_LOADED")
frame:SetScript("OnEvent", function(_, event, addonName)
    if addonName ~= ADDON_NAME then return end
    MyAddonDB = MyAddonDB or {}
    CopyDefaults(defaults, MyAddonDB)
end)
]],
	},
	{
		key = "event-registration",
		title = "Safe Event Registration",
		risk = "safe",
		body = [[
local frame = CreateFrame("Frame")
frame:RegisterEvent("PLAYER_LOGIN")
frame:SetScript("OnEvent", function(_, event, ...)
    if event == "PLAYER_LOGIN" then
        -- initialize runtime-only state here
    end
end)
]],
	},
	{
		key = "onupdate-throttle",
		title = "Throttled OnUpdate",
		risk = "review",
		body = [[
local elapsedTotal = 0
frame:SetScript("OnUpdate", function(_, elapsed)
    elapsedTotal = elapsedTotal + elapsed
    if elapsedTotal < 0.20 then return end
    elapsedTotal = 0

    -- Do batched/limited work here.
end)
]],
	},
	{
		key = "hooksecurefunc",
		title = "hooksecurefunc Pattern",
		risk = "combat-sensitive",
		body = [[
if type(TargetFunction) == "function" then
    hooksecurefunc("TargetFunction", function(...)
        -- observe after Blizzard function runs
        -- do not mutate protected state in combat
    end)
end
]],
	},
	{
		key = "slash-command",
		title = "Slash Command Pattern",
		risk = "safe",
		body = [[
SLASH_MYADDON1 = "/myaddon"
SlashCmdList.MYADDON = function(message)
    message = tostring(message or "")
    print("MyAddon command:", message)
end
]],
	},
	{
		key = "scroll-output",
		title = "Scrollable Output Panel",
		risk = "safe",
		body = [[
local scroll = CreateFrame("ScrollFrame", nil, parent, "UIPanelScrollFrameTemplate")
scroll:SetPoint("TOPLEFT", 10, -10)
scroll:SetPoint("BOTTOMRIGHT", -30, 10)

local output = CreateFrame("EditBox", nil, scroll)
output:SetMultiLine(true)
output:SetAutoFocus(false)
output:SetFontObject(ChatFontNormal)
output:SetWidth(600)
scroll:SetScrollChild(output)
]],
	},
}

function Library:GetSnippets()
	return self.snippets or {}
end

function Library:Find(query)
	query = string.lower(tostring(query or ""))
	local results = {}
	for _, snippet in ipairs(self.snippets or {}) do
		local hay = string.lower(tostring(snippet.key) .. " " .. tostring(snippet.title) .. " " .. tostring(snippet.risk))
		if query == "" or string.find(hay, query, 1, true) then
			table.insert(results, snippet)
		end
	end
	return results
end

function Library:Format(query)
	local lines = {}
	table.insert(lines, "ApiVault Snippet Library")
	table.insert(lines, "Snippets are copyable metadata. They are not executed automatically.")
	table.insert(lines, "")
	for _, snippet in ipairs(self:Find(query)) do
		table.insert(lines, "## " .. tostring(snippet.title) .. " [" .. tostring(snippet.risk) .. "]")
		table.insert(lines, "```lua")
		table.insert(lines, tostring(snippet.body or ""))
		table.insert(lines, "```")
		table.insert(lines, "")
	end
	return table.concat(lines, "\n")
end

function Library:GetStats()
	return #(self.snippets or {})
end
