local PT = AhUI
if not PT or not PT.InfoPanel then return end

local IP = PT.InfoPanel
local Tooltip = PT.Tooltip
local L = PT.L

local function GetCharacterKey()
    local name = UnitName("player") or "Unknown"
    local realm = GetNormalizedRealmName and GetNormalizedRealmName() or select(2, UnitName("player")) or ""
    return name .. "-" .. realm
end

local function GetItemSlotDB(uid)
    AhUI_CharConfig = AhUI_CharConfig or {}
    AhUI_CharConfig.infopanel_itemslot =
        AhUI_CharConfig.infopanel_itemslot or {}

    local charKey = GetCharacterKey()

    AhUI_CharConfig.infopanel_itemslot[charKey] =
        AhUI_CharConfig.infopanel_itemslot[charKey] or {}

    AhUI_CharConfig.infopanel_itemslot[charKey][uid] =
        AhUI_CharConfig.infopanel_itemslot[charKey][uid] or {}

    return AhUI_CharConfig.infopanel_itemslot[charKey][uid]
end

local function RefreshSettingsList()
    if PT
       and PT.Settings
       and PT.Settings.InfoPanel
       and PT.Settings.InfoPanel.RebuildLists
    then
        PT.Settings.InfoPanel:RebuildLists()
    end
end

IP:RegisterElementInfo("itemslot", {
    name  = L["Item Slot"],
    order = 80,
    multi = true,
})

local function GetSlotIconSize(h)
    return math.max(14, math.floor((h or 24) * 0.8))
end

local function ShowTooltip(self)
    if not Tooltip then return end

    local element = self.__element
    local id = element and element.data and element.data.itemID

    Tooltip:Clear()

    if not id then
        Tooltip:AddLine(L["Item Slot"], 14, 1, 1, 1)
        Tooltip:AddLine(" ")
        Tooltip:AddLine(L["ItemSlotDragHint1"], 12, 0.8, 0.8, 0.8)
        Tooltip:AddLine(L["ItemSlotDragHint2"], 12, 0.8, 0.8, 0.8)
        Tooltip:AddLine(" ")
        Tooltip:AddLine(L["ItemSlotClear"], 11, 0.7, 0.7, 0.7)
        Tooltip:AddLine(L["ItemSlotRemove"], 11, 0.7, 0.7, 0.7)
        Tooltip:ShowSmart(self)
        return
    end

    local name = C_Item.GetItemNameByID(id)
    local count = GetItemCount(id, true)

    Tooltip:AddLine(name or L["Item Slot"], 14, 1, 1, 1)
    Tooltip:AddLine(" ")

    if count and count > 0 then
        Tooltip:AddLine(
            string.format(L["ItemSlotCount"], BreakUpLargeNumbers(count)),
            12, 0.9, 0.9, 0.9
        )
    end

    Tooltip:AddLine(" ")
    Tooltip:AddLine(L["ItemSlotClear"], 11, 0.7, 0.7, 0.7)
    Tooltip:AddLine(L["ItemSlotRemove"], 11, 0.7, 0.7, 0.7)

    Tooltip:ShowSmart(self)
end

local function Create(uid)
    IP:InitConfig()

    local parent = IP.frame and IP.frame.content or UIParent
    local height = IP.config.appearance.height or 24

    local f = CreateFrame("Button", nil, parent)
    f:SetHeight(height)
    f:SetWidth(height)
    f:EnableMouse(true)
    f:RegisterForClicks("AnyUp")

    local icon = f:CreateTexture(nil, "ARTWORK")
    icon:SetPoint("CENTER")
    icon:SetTexCoord(0.08, 0.92, 0.08, 0.92)

    local highlight = f:CreateTexture(nil, "HIGHLIGHT")
    highlight:SetAllPoints(icon)
    highlight:SetTexture("Interface\\Buttons\\ButtonHilight-Square")
    highlight:SetBlendMode("ADD")
    highlight:Hide()

    local count = f:CreateFontString(nil, "OVERLAY", "NumberFontNormalSmall")
    count:SetPoint("BOTTOM", icon, "BOTTOM", 0, 1)
    count:SetJustifyH("CENTER")

    local element = {
        _type     = "ItemSlot",
        id        = uid,
        frame     = f,
        icon      = icon,
        count     = count,
        highlight = highlight,
        width     = height,
    }

    element.data = GetItemSlotDB(uid)

    local eventFrame = CreateFrame("Frame")
    eventFrame:RegisterEvent("BAG_UPDATE_DELAYED")
    eventFrame:RegisterEvent("ITEM_COUNT_CHANGED")

    eventFrame:SetScript("OnEvent", function(_, event, arg1)
        local id = element.data and element.data.itemID
        if not id then return end

        if event == "ITEM_COUNT_CHANGED" and arg1 ~= id then
            return
        end

        element:Update()
    end)

    IP.config.elements[uid] = IP.config.elements[uid] or {}
    element.db = IP.config.elements[uid]

    f.__element = element

    f:SetScript("OnUpdate", function(self)
        if self:IsMouseOver() and CursorHasItem() then
            element.highlight:Show()
        else
            element.highlight:Hide()
        end
    end)

    f:SetScript("OnEnter", ShowTooltip)

    f:SetScript("OnLeave", function()
        if Tooltip then Tooltip:Clear() end
        element.highlight:Hide()
    end)

    if IP.EnableDrag then
        IP:EnableDrag(element)
    end

    f:SetScript("OnReceiveDrag", function()
        local infoType, itemID = GetCursorInfo()
        if infoType ~= "item" or not itemID then return end

        ClearCursor()

        element.data.itemID = itemID
        element:Update()
        RefreshSettingsList()
    end)

    f:SetScript("OnMouseUp", function(self)
        if CursorHasItem() then
            local receiveDrag = self:GetScript("OnReceiveDrag")
            if receiveDrag then
                receiveDrag(self)
            end
        end
    end)

    f:SetScript("OnClick", function(_, btn)
        if IsShiftKeyDown() then
            IP:RemoveElementFromPanel(uid)
            RefreshSettingsList()
            return
        end

        if btn == "RightButton" then
            element.data.itemID = nil
            element:Update()
            RefreshSettingsList()
        end
    end)

    function element:Update()
        local h = IP.config.appearance.height or 24

        self.frame:SetHeight(h)
        self.frame:SetWidth(h)

        local iconSize = GetSlotIconSize(h)

        self.icon:SetSize(iconSize, iconSize)
        self.icon:ClearAllPoints()
        self.icon:SetPoint("CENTER")

        self.highlight:ClearAllPoints()
        self.highlight:SetAllPoints(self.icon)

        self.width = h

        local id = self.data and self.data.itemID

        if not id then
            self.icon:SetTexture(nil)
            self.count:SetText("")

            if not self.text then
                self.text = self.frame:CreateFontString(nil, "OVERLAY")
                self.text:SetPoint("CENTER")
                self.text:SetFontObject(PT.fonts.normal)
                self.text:SetTextColor(1, 1, 1)
                self.text:SetText("ReadMe")
            end

            self.text:Show()
            return
        end

        if self.text then
            self.text:Hide()
        end

        local _, _, _, _, iconFile = C_Item.GetItemInfoInstant(id)
        self.icon:SetTexture(iconFile)

        local total = GetItemCount(id, true)
        self.count:SetText(total > 1 and total or "")
    end

    function element:ApplyHeight(h)
        self.frame:SetHeight(h)
        self.frame:SetWidth(h)

        local iconSize = GetSlotIconSize(h)

        self.icon:SetSize(iconSize, iconSize)
        self.icon:ClearAllPoints()
        self.icon:SetPoint("CENTER")

        self.highlight:ClearAllPoints()
        self.highlight:SetAllPoints(self.icon)

        if self.text then
            self.text:SetFont(PT.FONT, math.max(10, h - 8), "")
        end

        self.width = h
    end

    element:Update()
    return element
end

IP:RegisterElementType("itemslot", function(uid)
    return Create(uid)
end)