local PT = AhUI
local L = PT.L
local Tracker = PT.Tracker
local Tooltip = PT.Tooltip
local ICON_DB = {
    DF  = "Interface\\AddOns\\AhUI\\media\\DF.tga",
    TWW = "Interface\\AddOns\\AhUI\\media\\TWW.tga",
}

if PT.IS_MID_AVAILABLE then
    ICON_DB.MID = "Interface\\AddOns\\AhUI\\media\\MID.tga"
end

local FONT = "Interface\\AddOns\\AhUI\\fonts\\GothamXNarrow-Medium.ttf"

local pendingItems = {}

local function NormalizeItemId(v)
    if type(v) == "number" then
        return v
    end
    if type(v) == "table" then
        if type(v.id) == "number" then return v.id end
        if type(v[1]) == "number" then return v[1] end
    end
    return nil
end

local function WarmupItemsForActiveDB()
    if not AhUI or not AhUI.professions then return end

    for _, prof in pairs(AhUI.professions) do
        if prof.entries then
            for _, entry in ipairs(prof.entries) do
local id = NormalizeItemId(entry.itemId)
if id then
    C_Item.RequestLoadItemDataByID(id)
end
            end
        end
    end
end

local function WarmupProfessionInfo()
    if not AhUI or not AhUI.professions then return end

    for _, p in pairs(AhUI.professions) do
        C_TradeSkillUI.GetProfessionInfoBySkillLineID(p.id)
        C_TradeSkillUI.GetChildProfessionInfo(p.id)
        C_TradeSkillUI.GetTradeSkillTexture(p.id)
    end
end

local function ApplyBackdrop(frame, r,g,b,a)
    frame.bg = frame:CreateTexture(nil, "BACKGROUND")
    frame.bg:SetAllPoints()
    frame.bg:SetColorTexture(r,g,b,a)
end

local function SortItems(a, b)
    local A, B = a:GetType() or 99, b:GetType() or 99
    if A ~= B then return A < B end
    return (a:GetName() or "") < (b:GetName() or "")
end

local function SavePosition(frame)
    AhUI_DB = AhUI_DB or {}
    AhUI_DB.positions = AhUI_DB.positions or {}

    local left = frame:GetLeft()
    local top  = frame:GetTop()

    if not left or not top then return end

    local uiTop = UIParent:GetTop()
    local x = left
    local y = top - uiTop

    AhUI_DB.positions.professions = {
        x = x,
        y = y,
    }
end

local function LoadPosition(frame)
    AhUI_DB = AhUI_DB or {}
    AhUI_DB.positions = AhUI_DB.positions or {}

    frame:ClearAllPoints()

    local p = AhUI_DB.positions.professions
    if p and p.x and p.y then
        frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", p.x, p.y)
    else
        frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", 20, -20)
    end
end

local function CreateDBSelector(frame)
    local btn = CreateFrame("Button", nil, frame)
    btn:SetPoint("TOPRIGHT", -2, -5)
    btn:SetSize(45, 28)
	btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    btn.icon = btn:CreateTexture(nil, "ARTWORK")
    btn.icon:SetAllPoints()
    btn.icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)

    local mask = btn:CreateMaskTexture()
    mask:SetTexture(
        "Interface\\CharacterFrame\\TempPortraitAlphaMask",
        "CLAMPTOBLACKADDITIVE",
        "CLAMPTOBLACKADDITIVE"
    )
    mask:SetAllPoints(btn.icon)
    btn.icon:AddMaskTexture(mask)

    function btn:Update()
        local db = AhUI_CharConfig.activeDB or "DF"
        btn.icon:SetTexture(ICON_DB[db])
    end
	
function btn:UpdateTooltip()
    Tooltip:Clear()
    Tooltip:AddLine("Database", 14, 1, 1, 1)
    Tooltip:AddLine(" ")

    local db = AhUI_CharConfig.activeDB or "DF"

    if db == "MID" and PT.IS_MID_AVAILABLE then
        Tooltip:AddLine("Midnight", 12, 0.7, 0.6, 1)
    elseif db == "TWW" then
        Tooltip:AddLine("The War Within", 12, 1, 0.6, 0.2)
    else
        Tooltip:AddLine("Dragonflight", 12, 0.6, 0.8, 1)
    end

    Tooltip:ShowAtCursor()
end

btn:SetScript("OnClick", function(self, mouseButton)
    local list = { "DF", "TWW" }

	if PT.IS_MID_AVAILABLE then
		table.insert(list, "MID")
	end

    local cur  = AhUI_CharConfig.activeDB or "DF"
    local pos  = 1

    for i, v in ipairs(list) do
        if v == cur then
            pos = i
            break
        end
    end

    if mouseButton == "RightButton" then
        pos = pos - 1
        if pos < 1 then pos = #list end
    else
        pos = pos + 1
        if pos > #list then pos = 1 end
    end

    local newDB = list[pos]

    AhUI_CharConfig.activeDB = newDB
    PT.config.activeDB = newDB

    PT.LoadActiveDB()
    PT:RefreshData()

    C_Timer.After(0, function()
        WarmupProfessionInfo()
        WarmupItemsForActiveDB()

        C_Timer.After(0.1, function()
            PT:RefreshUI()
        end)
    end)

    self:Update()
	PT.UpdateAllProfessionNames()
	PT:RefreshUI()
    if self:IsMouseOver() then
        self:UpdateTooltip()
    end
end)

    btn:SetScript("OnEnter", function()
		btn:UpdateTooltip()
    end)

    btn:SetScript("OnLeave", function()
        Tooltip:Clear()
    end)

    btn:Update()
    frame.dbSelector = btn
end

local UI = {}
PT.UI = UI

function UI:CreateMainFrame()
    if self.frame then return self.frame end

    local f = CreateFrame("Frame", "AhUIFrame", UIParent, "BackdropTemplate")
    f:SetSize(330, 70)

    f:SetBackdrop({
        bgFile   = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Buttons\\WHITE8x8",
        edgeSize = 2,
    })
    f:SetBackdropColor(0, 0, 0, 0)
    f:SetBackdropBorderColor(0, 0, 0, 1)

    ApplyBackdrop(f, 0, 0, 0, 0.55)

    LoadPosition(f)

    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")

    f:SetScript("OnDragStart", function(self)
        self:StartMoving()
    end)

f:SetScript("OnDragStop", function(self)
    self:StopMovingOrSizing()

    local left = self:GetLeft()
    local top  = self:GetTop()
    local uiTop = UIParent:GetTop()

    self:ClearAllPoints()
    self:SetPoint("TOPLEFT", UIParent, "TOPLEFT", left, top - uiTop)

    SavePosition(self)
end)

    f:SetClampedToScreen(true)

    local title = f:CreateFontString(nil, "OVERLAY")
    title:SetFont(FONT, 14)
    title:SetPoint("TOPLEFT", 10, -10)
    title:SetJustifyH("LEFT")
    title:SetText(L["PROF_WINDOW_TITLE"])
    f.title = title

    CreateDBSelector(f)

    local content = CreateFrame("Frame", nil, f)
    content:SetPoint("TOPLEFT", 10, -35)
    content:SetPoint("TOPRIGHT", -10, -35)
    content:SetHeight(1)

    self.content = content
    self.frame   = f

if PT.config.showProfessionsWindow == false then
    f:Hide()
end

    return f
end

local function CreateProfessionHeader(parent, profession)
    local header = CreateFrame("Button", nil, parent, "BackdropTemplate")
    header:SetSize(310, 20)
header:SetBackdrop({
    bgFile   = "Interface\\Buttons\\WHITE8x8",
    edgeFile = "Interface\\Buttons\\WHITE8x8",
    edgeSize = 1,
})

header:SetBackdropColor(0.10, 0.10, 0.10, 0.85)
header:SetBackdropBorderColor(0, 0, 0, 0.2)

    header.icon = header:CreateTexture(nil, "ARTWORK")
    header.icon:SetSize(16,16)
    header.icon:SetPoint("LEFT", 4, 0)
    header.icon:SetTexture(profession.icon)

    header.text = header:CreateFontString(nil, "OVERLAY")
	header.text:SetFont(FONT, 12)
    header.text:SetPoint("LEFT", header, "LEFT", 24, 0)
    header.text:SetJustifyH("LEFT")
    header.text:SetText(profession.name or "Profession")

    header.kpText = header:CreateFontString(nil, "OVERLAY")
	header.kpText:SetFont(FONT, 11)
    header.kpText:SetPoint("RIGHT", header, "RIGHT", -20, 0)
    header.kpText:SetJustifyH("RIGHT")
    header.kpText:SetTextColor(0, 1, 0)

local totalKP = 0
for _, entry in ipairs(profession.entries or {}) do
    if entry.GetRemainingKnowledgePoints
       and entry.MeetRequirements
       and entry:MeetRequirements()
    then
        local val = entry:GetRemainingKnowledgePoints()
        if val and val > 0 then
            totalKP = totalKP + val
        end
    end
end


    if totalKP > 0 then
        header.kpText:SetText("+" .. totalKP)
    else
        header.kpText:SetText("")
    end

    header.arrow = header:CreateTexture(nil,"ARTWORK")
    header.arrow:SetSize(10,10)
    header.arrow:SetPoint("RIGHT", -6, 0)
    header.arrow:SetTexture("Interface\\Buttons\\UI-PlusMinus-Buttons")

    header:SetScript("OnClick", function()
        profession.expanded = not profession.expanded
        PT.collapsedProfessions[profession.id] = not profession.expanded
        PT:RefreshUI()
    end)

    return header
end

local function CreateItemRow(parent, item)
	if not item or not item.profession then
    return nil
	end
    local row = CreateFrame("Button", nil, parent)
    row:SetSize(310, 18)

    row.bg = row:CreateTexture(nil, "BACKGROUND")
    row.bg:SetAllPoints()
    row.bg:SetColorTexture(1, 0.8, 0, 0.25)
    row.bg:SetShown(item.isTracked)

row.iconBtn = CreateFrame("Button", nil, row)
row.iconBtn:SetSize(16, 16)
row.iconBtn:SetPoint("LEFT", 14, 0)
row.iconBtn:EnableMouse(true)

row.icon = row.iconBtn:CreateTexture(nil, "ARTWORK")
row.icon:SetAllPoints()
row.icon:SetTexture(item.GetIcon and item:GetIcon() or 134400)

row.iconBtn:SetScript("OnEnter", function()
    GameTooltip:SetOwner(row.iconBtn, "ANCHOR_RIGHT")

    local id = NormalizeItemId(item.itemId)
    if id then
        GameTooltip:SetItemByID(id)
    else
        GameTooltip:SetText(item:GetName() or "Unknown")
    end

    GameTooltip:Show()
end)

row.iconBtn:SetScript("OnLeave", function()
    GameTooltip:Hide()
end)

row.iconBtn:SetScript("OnClick", function()
end)

    local markup = item.GetCategoryIcon and item:GetCategoryIcon()
    if markup then
        row.typeFS = row:CreateFontString(nil, "OVERLAY")
		row.typeFS:SetFont(FONT, 12)
        row.typeFS:SetPoint("LEFT", row.icon, "RIGHT", 2, 0)
        row.typeFS:SetText(markup)
    end
    row.text = row:CreateFontString(nil, "OVERLAY")
	row.text:SetFont(FONT, 11)

    if row.typeFS then
        row.text:SetPoint("LEFT", row.typeFS, "RIGHT", 4, 0)
    else
        row.text:SetPoint("LEFT", row.icon, "RIGHT", 6, 0)
    end

    row.text:SetWidth(220)
    row.text:SetJustifyH("LEFT")

    local nm = item.GetName and item:GetName() or ""
    if nm == "" then nm = "Loading…" end
    row.text:SetText(nm)

    if item.itemId then
        pendingItems[item.itemId] = row
    end

    if not item:MeetRequirements() then
        row.text:SetTextColor(1, 0.2, 0.2)
    end

    row.value = row:CreateFontString(nil, "OVERLAY")
	row.value:SetFont(FONT, 11)
    row.value:SetPoint("RIGHT", -4, 0)
    row.value:SetWidth(40)
    row.value:SetJustifyH("RIGHT")

    local val = item.GetRemainingKnowledgePoints and item:GetRemainingKnowledgePoints() or 0

    if val > 0 then
        row.value:SetText("+" .. val)
        if not item:MeetRequirements() then
            row.value:SetTextColor(1, 0.2, 0.2)
        elseif item:IsCatchUp() then
            row.value:SetTextColor(0.2, 1, 0.2)
        else
            row.value:SetTextColor(1, 0.7, 0.2)
        end
    else
        row.value:SetText("")
    end

    row.check = row:CreateTexture(nil, "ARTWORK")
    row.check:SetSize(12, 12)
    row.check:SetPoint("RIGHT", row.value, "LEFT", -4, 0)
    row.check:SetTexture("Interface\\Buttons\\UI-CheckBox-Check")
    row.check:SetVertexColor(0.4, 1, 0.4)
    if item.GetRemainingKnowledgePoints then
        row.check:SetShown(item:GetRemainingKnowledgePoints() == 0)
    else
        row.check:Hide()
    end

row:SetScript("OnEnter", function()
    Tooltip:Clear()
    Tooltip:AddLine(item:GetName() or "Unknown", 14, 1, 1, 1)
    if item:IsCatchUp() then
        Tooltip:AddLine(" ")
        Tooltip:AddLine(L["CATCHUP_REQUIREMENTS"], 12, 1, 0.82, 0)
        local reqs = item.unlockRequirements or {}
        for _, req in ipairs(reqs) do
            local ok = req:GetRemainingKnowledgePoints() == 0
            local nm2 = req:GetName() or "Unknown"

            if ok then
                Tooltip:AddLine(" + " .. nm2, 12, 0.2, 1, 0.2)
            else
                Tooltip:AddLine(" × " .. nm2, 12, 1, 0.2, 0.2)
            end
        end
    else
        local reqText = item.GetRequirementsText and item:GetRequirementsText()
        if reqText then
            Tooltip:AddLine(" ")
            Tooltip:AddLine(L["REQUIREMENTS"], 12, 1, 0.82, 0)
            Tooltip:AddLine(reqText, 12, 0.9, 0.9, 0.9)
        else
            local desc = item:GetDescription()
            if desc then
                Tooltip:AddLine(" ")
                Tooltip:AddLine(desc, 12, 0.9, 0.9, 0.9)
            end
        end
    end
    Tooltip:ShowAtCursor()
end)

row:SetScript("OnLeave", function()
    Tooltip:Clear()
end)

row:SetScript("OnClick", function()
    if not Tracker or not Tracker.ToggleTrackedItem then
        return
    end

    Tracker:ToggleTrackedItem(item)

end)


    return row
end

local warmupStarted = false
local warmupFinished = false

local function WarmupItems()
    if warmupStarted then return end
    warmupStarted = true

    C_Timer.NewTicker(0.2, function(self)
        if warmupFinished then
            self:Cancel()
            return
        end

        local profs = PT.GetProfessions(true)
        if not profs then return end

        local waiting = false

        for _, prof in pairs(profs) do
            for _, entry in ipairs(prof.entries or {}) do
local id = NormalizeItemId(entry.itemId)
if id then
    local name = entry:GetName()
    if not name or name == "" then
        waiting = true
        C_Item.GetItemInfo(id)
    end
end
            end
        end

        if not waiting then
            warmupFinished = true
            C_Timer.After(0.05, function() 
                PT:RefreshUI()
            end)
        else
            PT:RefreshUI()
        end
    end)
end

C_Timer.After(0.5, WarmupItems)

local function PlayerHasAnyProfessions()
    local prof1, prof2, arch, fish, cook = GetProfessions()

    if prof1 or prof2 then
        return true
    end

    return false
end

function PT:RefreshUI()
if PT.config.showProfessionsWindow == false then
    if PT.UI and PT.UI.frame then
        PT.UI.frame:Hide()
    end
    return
end

    if not PlayerHasAnyProfessions() then
        if PT.UI and PT.UI.frame then
            PT.UI.frame:Hide()
        end
        return
    end

    local frame = UI:CreateMainFrame()
    frame:Show()

    local parent = UI.content
    if not parent then return end

    for _, child in ipairs({ parent:GetChildren() }) do
        child:SetParent(nil)
        child:Hide()
    end

    local profs = PT.GetProfessions(true) or {}

    local ordered = {}
    for _, p in pairs(profs) do
        table.insert(ordered, p)
    end

    table.sort(ordered, function(a, b)
        return a.index < b.index
    end)

    local y = -2

    for _, profession in ipairs(ordered) do
        if PT.collapsedProfessions[profession.id] == nil then
            profession.expanded = false
        else
            profession.expanded = not PT.collapsedProfessions[profession.id]
        end

        local header = CreateProfessionHeader(parent, profession)
        header:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, y)
        y = y - 20

        if profession.expanded then
            local items = {}

            for _, item in ipairs(profession.entries or {}) do
                if item.Show and item:Show() then
                    table.insert(items, item)
                end
            end

            table.sort(items, SortItems)

            for _, item in ipairs(items) do
                local row = CreateItemRow(parent, item)
                row:SetPoint("TOPLEFT", parent, "TOPLEFT", 0, y)
                y = y - 18
            end

            y = y - 4
        end
    end

    local contentHeight = math.abs(y) + 20
    parent:SetHeight(contentHeight)

    local left = frame:GetLeft()
    local top  = frame:GetTop()
    local uiTop = UIParent:GetTop()

    frame:ClearAllPoints()
    frame:SetPoint("TOPLEFT", UIParent, "TOPLEFT", left, top - uiTop)
    frame:SetHeight(math.min(contentHeight + 35, 2000))
end
