local PT = AhUI
if not PT then return end

PT.Tooltip = PT.Tooltip or {}
local T = PT.Tooltip

T.MIN_WIDTH = 60
T.MAX_WIDTH = 360
T.PADDING_X = 16

local FONT = AhUI.FONT

local f = CreateFrame("Frame", "AhUITooltip", UIParent, "BackdropTemplate")
f:SetFrameStrata("TOOLTIP")
f:SetFrameLevel(9999)
f:SetBackdrop({
    bgFile   = "Interface\\Buttons\\WHITE8x8",
    edgeFile = "Interface\\Buttons\\WHITE8x8",
    edgeSize = 1,
})
f:SetBackdropColor(0, 0, 0, 0.95)
f:SetBackdropBorderColor(1, 1, 1, 1)
f:Hide()

f.lines = {}
T.frame = f

function T:Clear()
    f:SetScript("OnUpdate", nil)

    for _, fs in ipairs(f.lines) do
        fs:Hide()
        fs:SetParent(nil)
    end

    wipe(f.lines)
    f:Hide()
end

function T:AddLine(text, size, r, g, b)
    local fs = f:CreateFontString(nil, "OVERLAY")
    fs:SetFont(FONT, size or 13, "")
    fs:SetTextColor(r or 1, g or 1, b or 1)
    fs:SetJustifyH("LEFT")
    fs:SetJustifyV("TOP")
    fs:SetWordWrap(true)
    fs:SetWidth(1)
    fs:SetText(text)

    table.insert(f.lines, fs)
    return fs
end

local function CalculateAutoWidth()
    local maxW = 0

    for _, fs in ipairs(f.lines) do
        fs:SetWordWrap(false)
        fs:SetWidth(0)
        local w = fs:GetStringWidth()
        if w and w > maxW then
            maxW = w
        end
    end

    maxW = maxW + T.PADDING_X
    maxW = math.max(T.MIN_WIDTH, math.min(T.MAX_WIDTH, maxW))

    return math.floor(maxW + 0.5)
end

local function Layout(width)
    for _, fs in ipairs(f.lines) do
        fs:SetWordWrap(true)
        fs:SetWidth(width - T.PADDING_X)
    end

    local height = 8
    local prev

    for i, fs in ipairs(f.lines) do
        fs:ClearAllPoints()
        if i == 1 then
            fs:SetPoint("TOPLEFT", f, "TOPLEFT", 8, -8)
        else
            fs:SetPoint("TOPLEFT", prev, "BOTTOMLEFT", 0, -4)
        end
        height = height + fs:GetStringHeight() + 4
        prev = fs
    end

    height = height + 8
    return height
end

function T:ShowAt(owner, point, offsetX, offsetY)
    local width = CalculateAutoWidth()
    local height = Layout(width)

    f:SetSize(width, height)
    f:ClearAllPoints()

    offsetX = offsetX or 0
    offsetY = offsetY or 0
    point = point or "TOP"

    f:SetPoint(point, owner, point, offsetX, offsetY)
    f:Show()
end

function T:ShowSmart(owner, offset)
    offset = offset or 6

    local width = CalculateAutoWidth()
    local height = Layout(width)

    f:SetSize(width, height)
    f:ClearAllPoints()

    local ownerTop = owner:GetTop()
    local ownerBottom = owner:GetBottom()
    local screenH = UIParent:GetHeight()

    local spaceAbove = ownerTop and (screenH - ownerTop) or 0
    local spaceBelow = ownerBottom or 0

    if spaceAbove >= height + offset then
        f:SetPoint("BOTTOM", owner, "TOP", 0, offset)
    elseif spaceBelow >= height + offset then
        f:SetPoint("TOP", owner, "BOTTOM", 0, -offset)
    else
        if spaceAbove > spaceBelow then
            f:SetPoint("BOTTOM", owner, "TOP", 0, offset)
        else
            f:SetPoint("TOP", owner, "BOTTOM", 0, -offset)
        end
    end

    f:Show()
end

function T:ShowAtCursor(offsetX, offsetY)
    offsetX = offsetX or 16
    offsetY = offsetY or 16

    local width = CalculateAutoWidth()
    local height = Layout(width)

    f:SetSize(width, height)
    f:Show()

    f:SetScript("OnUpdate", function(self)
        local cx, cy = GetCursorPosition()
        local scale = UIParent:GetEffectiveScale()

        local x = cx / scale + offsetX
        local y = cy / scale + offsetY

        local screenW = UIParent:GetWidth()
        local screenH = UIParent:GetHeight()

        if x + width > screenW then
            x = x - width - 24
        end

        if y + height > screenH then
            y = y - height - 24
        end

        self:ClearAllPoints()
        self:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", x, y)
    end)
end