local PT = AhUI
local Tooltip = PT.Tooltip
local L = PT.L
if not PT or not PT.SkinningCheck then return end

local SC = PT.SkinningCheck
local UI = {}
PT.UI_SkinningCheck = UI

if not UI._tooltipHooked then
    UI._tooltipHooked = true
end

local FONT = AhUI.FONT
local ICON_TEXTURE = "Interface\\AddOns\\AhUI\\media\\skinning.tga"

PT.config.skinningCheckEnabled = PT.config.skinningCheckEnabled ~= false
PT.config.skinningIconSize = PT.config.skinningIconSize or 50

local function GetIconSize()
    local v = PT.config.skinningIconSize or 50
    return math.max(20, math.min(300, v))
end

function UI:CreateIcon()
    if self.icon then return self.icon end

    if not SC:IsAvailable() then
        return nil
    end
	
    AhUI_DB = AhUI_DB or {}
    AhUI_DB.positions = AhUI_DB.positions or {}

    if not AhUI_DB.positions.skinningIcon then
        AhUI_DB.positions.skinningIcon = {
            point = "CENTER",
            relPoint = "CENTER",
            x = 0,
            y = 0,
        }
    end

    local cfg = AhUI_DB.positions.skinningIcon

    local f = CreateFrame("Button", "AhUISkinningIcon", UIParent)

    local size = GetIconSize()
    f:SetSize(size, size)

    f:SetPoint(cfg.point, UIParent, cfg.relPoint or cfg.point, cfg.x, cfg.y)

    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", f.StartMoving)
    f:SetScript("OnDragStop", function(self)
        self:StopMovingOrSizing()
        local point, _, relPoint, x, y = self:GetPoint()
        cfg.point = point
        cfg.relPoint = relPoint
        cfg.x = x
        cfg.y = y
    end)

    local tex = f:CreateTexture(nil, "ARTWORK")
    tex:SetAllPoints()
    tex:SetTexture(ICON_TEXTURE)
    f.iconTex = tex

    local ring = f:CreateTexture(nil, "OVERLAY")
    ring:SetTexture("Interface\\AddOns\\AhUI\\media\\glow_ring.tga")
    ring:SetPoint("TOPLEFT", f, "TOPLEFT", -12, 12)
    ring:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 12, -12)
    ring:SetAlpha(1)
    ring:Hide()
    f.ring = ring
    f.ringFadeAlpha = 0
    f.ringFadeDir   = 1

    f:SetScript("OnUpdate", function(self, elapsed)
        if not self.ring or not self.ring:IsShown() then return end

        local speed = 1.2
        self.ringFadeAlpha = self.ringFadeAlpha + elapsed * speed * self.ringFadeDir

        if self.ringFadeAlpha >= 1 then
            self.ringFadeAlpha = 1
            self.ringFadeDir = -1
        elseif self.ringFadeAlpha <= 0 then
            self.ringFadeAlpha = 0
            self.ringFadeDir = 1
        end

        self.ring:SetAlpha(self.ringFadeAlpha)
    end)

    f:SetScript("OnEnter", function()
		if not SC:IsAvailable() then return end
	
        Tooltip:Clear()
        Tooltip:AddLine(L["SKINNING_TITLE"], 14, 1, 1, 1)
        Tooltip:AddLine(SC:GetIconTooltip(), 12, 0.85, 0.85, 0.85)
        Tooltip:ShowAtCursor()
    end)

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

    f:SetScript("OnClick", function(_, btn)
        if btn == "LeftButton" then
            UI:ToggleMenu()
        end
    end)

    self.icon = f
    PT:RegisterVisibilityFrame(
        f,
        "hideSkinningInCombat",
        "hideSkinningInInstance",
        "skinningCheckEnabled"
    )

    PT:UpdateVisibility()
    return f
end

function UI:Update()

    if not PT.config.skinningCheckEnabled then
        if self.icon then
            self.icon:Hide()
        end
        return
    end

    if not SC:IsAvailable() then
        if self.icon then
            self.icon:Hide()
        end
        return
    end

    if not self.icon then
        self:CreateIcon()
    end

    if not self.icon then
        return
    end

    if PT.UpdateVisibility then
        PT:UpdateVisibility()
    end

    local size = GetIconSize()
    self.icon:SetSize(size, size)

    if SC:HasMissingItems() then
        self.icon:SetAlpha(1)
        if self.icon.ring then
            self.icon.ring:Show()
            self.icon.ringFadeAlpha = 0
            self.icon.ringFadeDir   = 1
        end
    else
        self.icon:SetAlpha(0.5)
        if self.icon.ring then
            self.icon.ring:Hide()
        end
    end
end

function UI:CreateMenu()
    if self.menu then return self.menu end

    local f = CreateFrame("Frame", "AhUISkinningMenu", UIParent, "BackdropTemplate")
    f:SetFrameStrata("HIGH")
    f:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8x8",
        edgeFile = "Interface\\Buttons\\WHITE8x8",
        edgeSize = 2,
    })
    f:SetBackdropColor(0, 0, 0, 0.7)
    f:SetBackdropBorderColor(0, 0, 0, 1)
    f:Hide()
    self.menu = f
    return f
end

function UI:CreateClickCatcher()
    if self.clickCatcher then return end

    local f = CreateFrame("Frame", nil, UIParent)
    f:SetAllPoints()
	f:SetFrameStrata("BACKGROUND")
	f:SetFrameLevel(0)
	f:EnableMouse(true)
    f:Hide()

    f:SetScript("OnMouseDown", function()
        if UI.menu then UI.menu:Hide() end
        f:Hide()
    end)

    self.clickCatcher = f
end

function UI:ToggleMenu()
    if not self.menu then self:CreateMenu() end
    if not self.clickCatcher then self:CreateClickCatcher() end

    if self.menu:IsShown() then
        self.menu:Hide()
        self.clickCatcher:Hide()
        return
    end

    self:BuildMenu()
    self.clickCatcher:Show()
end

function UI:BuildMenu()
    local menu = self.menu
    menu:Show()
    menu:ClearAllPoints()
    menu:SetPoint("TOPLEFT", self.icon, "TOPRIGHT", 6, 0)

    if menu.items then
        for _, row in ipairs(menu.items) do
            row:Hide()
        end
    end
    menu.items = {}

    local missing = SC:GetMissingItems()
    local y = -6
    local width = 260

    for _, item in ipairs(missing) do
        local row = CreateFrame("Button", nil, menu)
        row:SetSize(width, 20)
        row:SetPoint("TOPLEFT", 6, y)
        row:EnableMouse(true)

        row:SetScript("OnClick", function()
            SC:SetPendingWaypoint(item)
        end)
		row:SetScript("OnEnter", function(self)
			local guideText = SC:GetGuideTooltip(item)
			if not guideText then return end

			Tooltip:Clear()
			Tooltip:AddLine(L["SKINNING_GUIDE"] or "Guide", 13, 1, 0.82, 0)
			Tooltip:AddLine(guideText, 12, 0.85, 0.85, 0.85)
			Tooltip:ShowSmart(self)
		end)

		row:SetScript("OnLeave", function()
			Tooltip:Clear()
		end)
        local iconButton = CreateFrame("Button", nil, row)
        iconButton:SetSize(16, 16)
        iconButton:SetPoint("LEFT", row, "LEFT", 0, 0)
        iconButton:EnableMouse(false)

        local icon = iconButton:CreateTexture(nil, "ARTWORK")
        icon:SetAllPoints()
        icon:SetTexture(item.itemId and C_Item.GetItemIconByID(item.itemId) or 134400)

        local text = row:CreateFontString(nil, "OVERLAY")
        text:SetFont(FONT, 13, "")
        text:SetPoint("LEFT", iconButton, "RIGHT", 6, 0)
        text:SetText(SC:GetTargetName(item))

        table.insert(menu.items, row)
        y = y - 22
    end

    menu:SetSize(width + 12, -y + 6)
end

local f = CreateFrame("Frame")
f:RegisterEvent("PLAYER_ENTERING_WORLD")
f:RegisterEvent("QUEST_LOG_UPDATE")
f:RegisterEvent("SKILL_LINES_CHANGED")
f:RegisterEvent("TRADE_SKILL_SHOW")

f:SetScript("OnEvent", function()
    if not PT.config.skinningCheckEnabled then
        if UI.icon then UI.icon:Hide() end
        return
    end

    UI:CreateIcon()
    UI:Update()
    PT:UpdateVisibility()
end)