local MonkeyGames = LibStub("AceAddon-3.0"):GetAddon("MonkeyGames")
local L = MonkeyGames.L
local Theme = MonkeyGames.Theme

local Widgets = {}
MonkeyGames.Widgets = Widgets

--- Create a themed, draggable window frame.
function Widgets:CreateWindow(name, width, height)
    local frame = CreateFrame("Frame", name, UIParent, BackdropTemplateMixin and "BackdropTemplate")
    frame:SetSize(width, height)
    frame:SetPoint("CENTER", UIParent, "CENTER", 0, 0)
    frame:SetMovable(true)
    frame:SetClampedToScreen(true)
    frame:SetFrameStrata("MEDIUM")
    frame:SetFrameLevel(5)
    frame:EnableMouse(true)

    -- Apply backdrop
    self:ApplyThemeBackdrop(frame)

    -- Drag handling
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", function(self)
        if not MonkeyGames.db.profile.Window.locked then
            self:StartMoving()
        end
    end)
    frame:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        Widgets:SaveWindowPosition(self)
    end)

    return frame
end

--- Apply the standard dark purple backdrop to a frame.
function Widgets:ApplyThemeBackdrop(frame)
    frame.backdropInfo = Theme.BACKDROP
    frame:ApplyBackdrop()
    frame:SetBackdropColor(Theme.BG_COLOR[1], Theme.BG_COLOR[2], Theme.BG_COLOR[3], MonkeyGames.db.profile.Theme.opacity)
    frame:SetBackdropBorderColor(unpack(Theme.BORDER_COLOR))
end

--- Apply a section-style backdrop (lighter border).
function Widgets:ApplySectionBackdrop(frame)
    frame.backdropInfo = Theme.BACKDROP_SECTION
    frame:ApplyBackdrop()
    frame:SetBackdropColor(Theme.BG_COLOR[1], Theme.BG_COLOR[2], Theme.BG_COLOR[3], 0.6)
    frame:SetBackdropBorderColor(Theme.BORDER_COLOR[1], Theme.BORDER_COLOR[2], Theme.BORDER_COLOR[3], 0.5)
end

--- Create a gradient header bar (XPTracker style).
function Widgets:CreateHeaderBar(parent, title)
    local bar = CreateFrame("Frame", nil, parent, BackdropTemplateMixin and "BackdropTemplate")
    bar:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, 0)
    bar:SetPoint("TOPRIGHT", parent, "TOPRIGHT", 0, 0)
    bar:SetHeight(30)

    bar.backdropInfo = {
        edgeFile = Theme.TEX_BORDER_TOOLTIP,
        edgeSize = 10,
        insets = { left = 2, right = 2, top = 2, bottom = 2 },
    }
    bar:ApplyBackdrop()
    bar:SetBackdropBorderColor(0.25, 0.25, 0.3, 0.8)
    bar:SetFrameLevel(parent:GetFrameLevel() + 2)

    -- Gradient background
    bar.bg = bar:CreateTexture(nil, "BACKGROUND")
    bar.bg:SetPoint("TOPLEFT", 2, -2)
    bar.bg:SetPoint("BOTTOMRIGHT", -2, 2)
    bar.bg:SetTexture(Theme.TEX_WHITE8X8)
    bar.bg:SetGradient("HORIZONTAL",
        CreateColor(unpack(Theme.HEADER_GRADIENT_LEFT)),
        CreateColor(unpack(Theme.HEADER_GRADIENT_RIGHT))
    )

    -- Title text
    bar.title = bar:CreateFontString(nil, "OVERLAY")
    bar.title:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_TITLE, "")
    bar.title:SetPoint("LEFT", bar, "LEFT", 12, 0)
    bar.title:SetText(title)
    bar.title:SetTextColor(unpack(Theme.TEXT_ACCENT))

    -- Close button
    local closeBtn = CreateFrame("Button", nil, bar)
    closeBtn:SetSize(20, 20)
    closeBtn:SetPoint("RIGHT", bar, "RIGHT", -6, 0)
    closeBtn:SetNormalTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Up")
    closeBtn:SetHighlightTexture("Interface\\Buttons\\UI-Panel-MinimizeButton-Highlight")
    closeBtn:SetScript("OnClick", function()
        parent:Hide()
    end)
    bar.closeBtn = closeBtn

    return bar
end

--- Create a styled button.
function Widgets:CreateButton(parent, text, width, height)
    local btn = CreateFrame("Button", nil, parent, BackdropTemplateMixin and "BackdropTemplate")
    btn:SetSize(width or 100, height or 24)

    btn.backdropInfo = {
        bgFile = Theme.TEX_WHITE8X8,
        edgeFile = Theme.TEX_BORDER_TOOLTIP,
        edgeSize = 8,
        insets = { left = 2, right = 2, top = 2, bottom = 2 },
    }
    btn:ApplyBackdrop()
    btn:SetBackdropColor(unpack(Theme.BUTTON_BG))
    btn:SetBackdropBorderColor(Theme.BORDER_COLOR[1], Theme.BORDER_COLOR[2], Theme.BORDER_COLOR[3], 0.6)

    btn.text = btn:CreateFontString(nil, "OVERLAY")
    btn.text:SetFont(Theme.BASE_FONT, Theme.FONT_SIZE_BUTTON, "")
    btn.text:SetPoint("CENTER", 0, 0)
    btn.text:SetText(text)
    btn.text:SetTextColor(unpack(Theme.BUTTON_TEXT))

    btn:SetScript("OnEnter", function(self)
        self:SetBackdropColor(unpack(Theme.BUTTON_BG_HOVER))
        self.text:SetTextColor(unpack(Theme.BUTTON_TEXT_HOVER))
    end)
    btn:SetScript("OnLeave", function(self)
        self:SetBackdropColor(unpack(Theme.BUTTON_BG))
        self.text:SetTextColor(unpack(Theme.BUTTON_TEXT))
    end)

    return btn
end

--- Create a label FontString.
function Widgets:CreateLabel(parent, text, size, color)
    local fs = parent:CreateFontString(nil, "OVERLAY")
    fs:SetFont(Theme.BASE_FONT, size or Theme.FONT_SIZE_BODY, "")
    fs:SetText(text or "")
    fs:SetTextColor(unpack(color or Theme.TEXT_DEFAULT))
    return fs
end

--- Save window position to DB.
function Widgets:SaveWindowPosition(frame)
    local pos = MonkeyGames.db.profile.Window
    local point, _, _, x, y = frame:GetPoint()
    pos.x = x
    pos.y = y
end

--- Restore window position from DB.
function Widgets:RestoreWindowPosition(frame)
    local pos = MonkeyGames.db.profile.Window
    if pos.x and pos.y then
        frame:ClearAllPoints()
        frame:SetPoint("CENTER", UIParent, "CENTER", pos.x, pos.y)
    end
end
