---@class AddonPrivate
local Private = select(2, ...)

---@class UI
local ui = {
    ---@class Meta_Frame
    frame = nil,
    ---@class AceGUITreeGroup
    tree = nil,
    queuedUpdate = false
}
Private.UI = ui

local const = Private.constants

function ui:CreateUI()
    local aceGUI = Private.AceGUI
    ---@class Meta_Frame
    local mainUI = aceGUI:Create("Meta_Frame")
    mainUI:SetWidth(500)
    mainUI:SetHeight(620)
    mainUI:SetTitle(const.ADDON_NAME)
    mainUI:SetLayout("Fill")

    ---@class AceGUITreeGroup
    local treeGroup = aceGUI:Create("Meta_ListGroup")
    treeGroup:SetFullWidth(true)
    treeGroup:SetFullHeight(true)
    treeGroup:SetFilterFunction(Private.WaypointsUtil.FilterFunction)
    mainUI:AddChild(treeGroup)
    treeGroup:SetCallback("OnTabSelected", function (_, _, selected)
        self:UpdateSelection(selected)
    end)
    treeGroup:SetCallback("OnExpandRightClick", function (_, _, data)
        if not data.waypointData or #data.waypointData <= 0 then return end
        Private.WaypointsUtil:AddCustomPins(unpack(data.waypointData))
        WorldMapFrame:Show()
    end)

    treeGroup:SetElementInitializer(function (frame, data)
        if not frame.btn then
			local button = CreateFrame("Button", nil, frame, "BackdropTemplate")
			button:SetBackdrop({
				bgFile = "Interface\\AchievementFrame\\UI-Achievement-Parchment-Horizontal",
				edgeFile = "Interface\\DialogFrame\\UI-DialogBox-Gold-Border",
				tile = false,
				tileSize = 0,
				edgeSize = 16,
				insets = { left = 5, right = 5, top = 5, bottom = 5 },
			})
			button:SetBackdropColor(0.3, 0.3, 0.3, 1)
			button:SetBackdropBorderColor(1, 1, 1, 1)
            button:RegisterForClicks("AnyDown")

			local text = button:CreateFontString()
            text:SetAllPoints()
			text:SetFontObject("GameFontNormal")
			button.text = text

			local highlightTexture = button:CreateTexture(nil, "HIGHLIGHT")
			highlightTexture:SetTexture("Interface\\Buttons\\WHITE8X8")
			highlightTexture:SetVertexColor(0.3, 0.3, 0, 0.5)
			highlightTexture:SetBlendMode("ADD")
			button:SetHighlightTexture(highlightTexture)

			button:SetScript("OnClick", function (_, btnType)
                treeGroup:Expand(frame, btnType)
            end)
			button:SetScript("OnEnter",function ()
                treeGroup:ShowTooltip(frame)
            end)
			button:SetScript("OnLeave",function ()
                treeGroup:HideTooltip(frame)
            end)

			button.text:SetHeight(14) -- Prevents text wrapping
			button:SetPoint("TOPLEFT")
			button:SetPoint("BOTTOMRIGHT", 0, 5)

			frame.btn = button
		end
        frame.data = data
		local button = frame.btn
        if data.children then
			button:SetBackdropColor(0.3, 0.3, 0.3, 1)
			button:SetBackdropBorderColor(1, 1, 1, 1)
        else
			button:SetBackdropColor(0.3, 0.3, 0.3, 0)
			button:SetBackdropBorderColor(1, 1, 1, 0)
        end
        button.text:SetText(data.icon and string.format("|T%s:16|t %s", data.icon, data.text) or data.text)
		button:SetSize(200, data.height)
    end)
    treeGroup:SetElementExtentCalculator(function (_, data)
        return data.height
    end)
    treeGroup:EnableButtonTooltips(true)
    mainUI:UpdateHelpText(self:CreateMissingText())

    mainUI:Hide()
    self.frame = mainUI
    self.tree = treeGroup

    self:UpdateTabs()
    self:UpdateSelection(1)
end

function ui:UpdateTabs()
    if not self.tree or not self.frame then return end
    self.tree:SetTabs(Private.ExpansionUtil:GetExpansions(), self.frame.frame)
end

function ui:UpdateSelection(selection)
    selection = selection or 1
    local tree = Private.WaypointsUtil:BuildTree(Private.ExpansionUtil:GetExpansion(selection))
    self.tree:SetProgress(Private.WaypointsUtil:GetProgress(Private.ExpansionUtil:GetExpansion(selection)))
    self.tree:SetData(tree)
end

function ui:ToggleUI()
    if not self.frame then return end
    self:SetShown(not self.frame:IsVisible())

    if self.frame:IsVisible() then
        if self.queuedUpdate then
            self:UpdateData()
        end
    end
end

function ui:QueueUpdate()
    self.queuedUpdate = true
end

function ui:SetShown(shown)
    if not self.frame then return end
    if shown then
        self.frame:Show()
    else
        self.frame:Hide()
    end
end

function ui:CreateMissingText()
    return "Did you know that you can now download expansions ?\nYou're missing out on the following expansions:\n" .. table.concat(Private.ExpansionUtil:GetUnloadedExpansions(), "\n")
end