local pluginName, pluginShared = ...
local Bookmark = {}
pluginShared.Bookmark = Bookmark

local BOOKMARK_TEXTURE = "Interface\\AddOns\\" .. pluginName .. "\\Media\\Textures\\AppearanceMatic-icon.png"

local guarded = pluginShared.guarded
local L = LibStub("AceLocale-3.0"):GetLocale("AppearanceMatic")

function Bookmark:IsSaved(category, page)
    local bm = AppearanceMaticDB and AppearanceMaticDB.bookmark
    return (bm and category and page and bm.category == category and bm.page == page) and true or false
end

function Bookmark:Save(category, page)
    if not (category and page) then
        return
    end
    AppearanceMaticDB = AppearanceMaticDB or {}
    if self:IsSaved(category, page) then
        AppearanceMaticDB.bookmark = nil
    else
        AppearanceMaticDB.bookmark = { category = category, page = page }
    end
end

function Bookmark:ShouldRestore(category, maxPages)
    local bm = AppearanceMaticDB and AppearanceMaticDB.bookmark
    if not (bm and category and bm.category == category) then
        return nil
    end
    if maxPages and bm.page > maxPages then
        return nil
    end
    return bm.page
end

function Bookmark:CurrentCategory()
    local items = WardrobeCollectionFrame and WardrobeCollectionFrame.ItemsCollectionFrame
    if items and type(items.GetActiveCategory) == "function" then
        local ok, category = guarded(items.GetActiveCategory, items)
        if ok then
            return category
        end
    end
    return nil
end

function Bookmark:CurrentPage()
    local items = WardrobeCollectionFrame and WardrobeCollectionFrame.ItemsCollectionFrame
    local pf = items and items.PagingFrame
    if pf and type(pf.GetCurrentPage) == "function" then
        local ok, page = guarded(pf.GetCurrentPage, pf)
        if ok then
            return page
        end
    end
    return nil
end

function Bookmark:UpdateIcon()
    if not (self.button and self.button.Icon) then
        return
    end
    local saved = self:IsSaved(self:CurrentCategory(), self:CurrentPage())
    guarded(self.button.Icon.SetDesaturated, self.button.Icon, not saved)
    guarded(self.button.Icon.SetAlpha, self.button.Icon, saved and 1 or 0.6)
end

function Bookmark:OnClick()
    self:Save(self:CurrentCategory(), self:CurrentPage())
    self:UpdateIcon()
end

function Bookmark:RestoreOnShow()
    if self.restoredForShow then
        return
    end
    local items = WardrobeCollectionFrame and WardrobeCollectionFrame.ItemsCollectionFrame
    local pf = items and items.PagingFrame
    if not (pf and type(pf.SetCurrentPage) == "function") then
        return
    end
    local maxPages
    if type(pf.GetMaxPages) == "function" then
        local ok, mp = guarded(pf.GetMaxPages, pf)
        if ok then
            maxPages = mp
        end
    end
    local target = self:ShouldRestore(self:CurrentCategory(), maxPages)
    if target then
        self.restoredForShow = true
        guarded(pf.SetCurrentPage, pf, target)
        if type(items.UpdateItems) == "function" then
            guarded(items.UpdateItems, items)
        end
    end
    self:UpdateIcon()
end

function Bookmark:EnsureButton(pf)
    if self.button or type(CreateFrame) ~= "function" then
        return
    end
    local btn = CreateFrame("Button", nil, pf)
    btn:SetSize(20, 24)
    btn:SetPoint("RIGHT", pf.PageText, "LEFT", -4, 0)
    local icon = btn:CreateTexture(nil, "ARTWORK")
    icon:SetTexture(BOOKMARK_TEXTURE)
    icon:SetPoint("CENTER")
    icon:SetSize(18, 18)
    btn.Icon = icon
    btn:SetScript("OnClick", function()
        Bookmark:OnClick()
    end)
    btn:SetScript("OnEnter", function(owner)
        if GameTooltip then
            GameTooltip:SetOwner(owner, "ANCHOR_TOP")
            GameTooltip:SetText(L["bm_tooltip_title"])
            GameTooltip:AddLine(L["bm_tooltip_desc"], 0.8, 0.8, 0.8, true)
            GameTooltip:Show()
        end
    end)
    btn:SetScript("OnLeave", function()
        if GameTooltip then
            GameTooltip:Hide()
        end
    end)
    self.button = btn
    self:UpdateIcon()
end

function Bookmark:InstallHooks()
    if self.hooked or type(hooksecurefunc) ~= "function" then
        return
    end
    local items = WardrobeCollectionFrame and WardrobeCollectionFrame.ItemsCollectionFrame
    local pf = items and items.PagingFrame
    if not (pf and pf.PageText and type(items.UpdateItems) == "function") then
        return
    end
    self.hooked = true
    self:EnsureButton(pf)
    if type(items.HookScript) == "function" then
        items:HookScript("OnShow", function()
            Bookmark.restoredForShow = false
            Bookmark:RestoreOnShow()
        end)
        items:HookScript("OnHide", function()
            Bookmark.restoredForShow = false
        end)
    end
    hooksecurefunc(items, "UpdateItems", function()
        Bookmark:UpdateIcon()
    end)
end

local bookmarkLoader = CreateFrame and CreateFrame("Frame")
if bookmarkLoader then
    bookmarkLoader:RegisterEvent("ADDON_LOADED")
    bookmarkLoader:SetScript("OnEvent", function(_, event, name)
        if event == "ADDON_LOADED" and (name == "Blizzard_Collections" or name == pluginName) then
            Bookmark:InstallHooks()
        end
    end)
    local isLoaded = C_AddOns and C_AddOns.IsAddOnLoaded or IsAddOnLoaded
    if type(isLoaded) == "function" then
        local ok, loaded = guarded(isLoaded, "Blizzard_Collections")
        if ok and loaded then
            Bookmark:InstallHooks()
        end
    end
end
