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: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 = {}
f.icons = {}
T.frame = f

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

    if f.icons then
        for _, tex in ipairs(f.icons) do
            tex:Hide()
            tex:SetTexture(nil)
            tex:SetParent(nil)
        end
        wipe(f.icons)
    end
    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(lines)
    local maxW = 0

    for _, fs in ipairs(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

function T:ShowAt(owner, point, relPoint, x, y)
    local width = CalculateAutoWidth(f.lines)

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

    local height = 8
    for _, fs in ipairs(f.lines) do
        height = height + fs:GetStringHeight() + 4
    end
    height = height + 8

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

    local offX = x or 8
    local offY = y or 0
    local pt = point or "TOPLEFT"

	local scale = owner:GetEffectiveScale() / UIParent:GetEffectiveScale()

	local ox = (owner:GetLeft() or 0) * scale
	local oy = (owner:GetBottom() or 0) * scale
	local ow = (owner:GetWidth() or 0) * scale
	local oh = (owner:GetHeight() or 0) * scale

    local anchorX, anchorY
    if pt == "TOPLEFT" then
        anchorX = ox + offX
        anchorY = oy + oh + offY
    elseif pt == "TOPRIGHT" then
        anchorX = ox + ow + offX
        anchorY = oy + oh + offY
    elseif pt == "BOTTOMLEFT" then
        anchorX = ox + offX
        anchorY = oy + offY
    elseif pt == "BOTTOMRIGHT" then
        anchorX = ox + ow + offX
        anchorY = oy + offY
    else
        anchorX = ox + offX
        anchorY = oy + oh + offY
    end

    if anchorX + width > screenW then
        anchorX = screenW - width - 4
    elseif anchorX < 0 then
        anchorX = 4
    end

    if anchorY + height > screenH then
        anchorY = screenH - height - 4
    elseif anchorY < 0 then
        anchorY = 4
    end

    f:ClearAllPoints()
    f:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", anchorX, anchorY)

    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
        prev = fs
    end

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

function T:ShowAtCursor(x, y)
    local cx, cy = GetCursorPosition()
    local scale = UIParent:GetScale()

    local cursorX = cx / scale + (x or 16)
    local cursorY = cy / scale + (y or 16)

    local width = CalculateAutoWidth(f.lines)

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

    local height = 8
    for _, fs in ipairs(f.lines) do
        height = height + fs:GetStringHeight() + 4
    end
    height = height + 8

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

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

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

    f:ClearAllPoints()
    f:SetPoint("BOTTOMLEFT", UIParent, "BOTTOMLEFT", cursorX, cursorY)

    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
        prev = fs
    end

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