--[[
============================================================================
SavedSearches.lua  (added in v14.6.0, Tier 2 Feature 2.2)
============================================================================

Lets users save the current filter state under a name and restore it
later. State captured:
  - searchText
  - sourceType, quality, expansion
  - armorType, weaponType, showWeaponsOnly
  - classFilter
  - sortBy, sortAscending

NOT captured:
  - category (the slot/category dropdown is usually what the user wants
    to keep across searches; restoring it would override the slot they
    just clicked into)
  - collected (collected/uncollected toggle is usually a transient UI
    decision, not a "search shape")

Storage: ETB_SavedSearches saved variable. Each entry is named and dated.

Why a separate module:
  - Snapshot/restore semantics are isolated from the filter logic itself.
  - UI for naming/loading lives in FilterBar but the data layer should
    not be entangled with the rendering code.
  - Easy to extend later (export/import strings, share between alts, etc).
============================================================================
]]--
local ADDON_NAME, NS = ...
local ETB = NS.ETB
NS.ETB.SavedSearches = NS.ETB.SavedSearches or {}
local SS = NS.ETB.SavedSearches

SS.searches = SS.searches or {}

-- Fields we capture when saving a search. Adding a new filter? Add it here.
local CAPTURED_FIELDS = {
    "searchText", "sourceType", "quality", "expansion",
    "armorType", "weaponType", "showWeaponsOnly", "classFilter",
}

-- =============================================================================
-- INIT / PERSIST
-- =============================================================================

function SS:Initialize()
    ETB_SavedSearches = ETB_SavedSearches or {}
    self.searches = ETB_SavedSearches
    if ETB.Debug then
        ETB:Debug("SavedSearches", "Loaded " .. self:GetCount() .. " saved searches")
    end
end

function SS:Save()
    ETB_SavedSearches = self.searches
end

-- =============================================================================
-- CAPTURE
-- =============================================================================
-- Reads current state from ETB.Filtering and ETB.Filtering.sortBy/Ascending,
-- producing a serializable snapshot.

function SS:CaptureCurrent()
    if not ETB.Filtering or not ETB.Filtering.filters then return nil end
    local snap = { _capturedAt = time() }
    for _, field in ipairs(CAPTURED_FIELDS) do
        snap[field] = ETB.Filtering.filters[field]
    end
    snap._sortBy = ETB.Filtering.sortBy
    snap._sortAscending = ETB.Filtering.sortAscending
    return snap
end

-- =============================================================================
-- RESTORE
-- =============================================================================
-- Writes captured state back into Filtering. Intentionally does NOT call
-- the per-field setters because those each trigger refresh events; we'd
-- rather make the change atomically and let the FilterBar refresh once.

function SS:Restore(name)
    local search = self.searches[name]
    if not search then return false, "no such search" end
    if not ETB.Filtering or not ETB.Filtering.filters then return false, "filtering not loaded" end
    for _, field in ipairs(CAPTURED_FIELDS) do
        if search[field] ~= nil then
            ETB.Filtering.filters[field] = search[field]
        end
    end
    if search._sortBy then ETB.Filtering.sortBy = search._sortBy end
    if search._sortAscending ~= nil then ETB.Filtering.sortAscending = search._sortAscending end
    if ETB.EventBus then ETB.EventBus:Fire("ETB_FILTERS_CHANGED") end
    return true
end

-- =============================================================================
-- CRUD
-- =============================================================================

function SS:SaveAs(name)
    if not name or name == "" then return false, "empty name" end
    local snap = self:CaptureCurrent()
    if not snap then return false, "could not capture" end
    snap.name = name
    self.searches[name] = snap
    self:Save()
    if ETB.Print then ETB:Print("Search saved: " .. name) end
    return true
end

function SS:Delete(name)
    if not self.searches[name] then return false end
    self.searches[name] = nil
    self:Save()
    if ETB.Print then ETB:Print("Search deleted: " .. name) end
    return true
end

function SS:GetCount()
    local n = 0
    for _ in pairs(self.searches) do n = n + 1 end
    return n
end

function SS:GetAll()
    local list = {}
    for name, data in pairs(self.searches) do
        list[#list + 1] = { name = name, data = data }
    end
    table.sort(list, function(a, b)
        return (a.data._capturedAt or 0) > (b.data._capturedAt or 0)
    end)
    return list
end
