SFrames.Pet = {}
local _A = SFrames.ActiveTheme

local function Clamp(value, minValue, maxValue)
    if value < minValue then return minValue end
    if value > maxValue then return maxValue end
    return value
end

function SFrames.Pet:ShowContextMenu()
    if not self.contextMenu then
        self.contextMenu = CreateFrame("Frame", "SFramesPetContextDD", UIParent, "UIDropDownMenuTemplate")
    end
    UIDropDownMenu_Initialize(self.contextMenu, function()
        local info

        info = {}
        info.text = "查看属性"
        info.notCheckable = 1
        info.func = function()
            ToggleCharacter("PetPaperDollFrame")
        end
        UIDropDownMenu_AddButton(info)

        local hasPetUI, isHunterPet = HasPetUI()
        if isHunterPet then
            info = {}
            info.text = "重命名"
            info.notCheckable = 1
            info.func = function() SFrames.Pet:ShowRenameDialog() end
            UIDropDownMenu_AddButton(info)

            info = {}
            info.text = "解散宠物"
            info.notCheckable = 1
            info.func = function() if PetDismiss then PetDismiss() end end
            UIDropDownMenu_AddButton(info)

            info = {}
            info.text = "放弃宠物"
            info.notCheckable = 1
            info.textR = 1; info.textG = 0.3; info.textB = 0.3
            info.func = function() if PetAbandon then PetAbandon() end end
            UIDropDownMenu_AddButton(info)
        else
            info = {}
            info.text = "解散宠物"
            info.notCheckable = 1
            info.func = function() if PetDismiss then PetDismiss() end end
            UIDropDownMenu_AddButton(info)
        end

        info = {}
        info.text = CANCEL or "取消"
        info.notCheckable = 1
        info.func = function() CloseDropDownMenus() end
        UIDropDownMenu_AddButton(info)
    end, "MENU")
    ToggleDropDownMenu(1, nil, self.contextMenu, "SFramesPetFrame", 106, 27)
end

function SFrames.Pet:CreateRenameFrame()
    local T = SFrames.ActiveTheme
    local font = SFrames:GetFont()
    local outline = (SFrames.Media and SFrames.Media.fontOutline) or "OUTLINE"

    local f = CreateFrame("Frame", "SFramesPetRenameDialog", UIParent)
    f:SetWidth(300)
    f:SetHeight(120)
    f:SetPoint("CENTER", UIParent, "CENTER", 0, 80)
    f:SetFrameStrata("DIALOG")
    f:SetToplevel(true)
    f:EnableMouse(true)
    f:SetMovable(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", function() this:StartMoving() end)
    f:SetScript("OnDragStop", function() this:StopMovingOrSizing() end)

    f:SetBackdrop({
        bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 14,
        insets = { left = 3, right = 3, top = 3, bottom = 3 },
    })
    f:SetBackdropColor(T.panelBg[1], T.panelBg[2], T.panelBg[3], T.panelBg[4])
    f:SetBackdropBorderColor(T.panelBorder[1], T.panelBorder[2], T.panelBorder[3], T.panelBorder[4])

    local shadow = CreateFrame("Frame", nil, f)
    shadow:SetPoint("TOPLEFT", f, "TOPLEFT", -4, 4)
    shadow:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", 4, -4)
    shadow:SetBackdrop({
        bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 16, edgeSize = 16,
        insets = { left = 4, right = 4, top = 4, bottom = 4 },
    })
    shadow:SetBackdropColor(0, 0, 0, 0.45)
    shadow:SetBackdropBorderColor(0, 0, 0, 0.6)
    shadow:SetFrameLevel(math.max(0, f:GetFrameLevel() - 1))

    local header = CreateFrame("Frame", nil, f)
    header:SetPoint("TOPLEFT", f, "TOPLEFT", 3, -3)
    header:SetPoint("TOPRIGHT", f, "TOPRIGHT", -3, -3)
    header:SetHeight(26)
    header:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
    header:SetBackdropColor(T.headerBg[1], T.headerBg[2], T.headerBg[3], T.headerBg[4])

    local titleFS = header:CreateFontString(nil, "OVERLAY")
    titleFS:SetFont(font, 12, outline)
    titleFS:SetPoint("CENTER", header, "CENTER", 0, 0)
    titleFS:SetText("宠物重命名")
    titleFS:SetTextColor(T.gold[1], T.gold[2], T.gold[3])

    local hsep = f:CreateTexture(nil, "ARTWORK")
    hsep:SetTexture("Interface\\Buttons\\WHITE8X8")
    hsep:SetHeight(1)
    hsep:SetPoint("TOPLEFT", f, "TOPLEFT", 4, -29)
    hsep:SetPoint("TOPRIGHT", f, "TOPRIGHT", -4, -29)
    hsep:SetVertexColor(T.divider[1], T.divider[2], T.divider[3], T.divider[4])

    local eb = CreateFrame("EditBox", "SFramesPetRenameEditBox", f)
    eb:SetWidth(260)
    eb:SetHeight(24)
    eb:SetPoint("TOP", f, "TOP", 0, -42)
    eb:SetFont(font, 12, outline)
    eb:SetAutoFocus(false)
    eb:SetMaxLetters(24)
    eb:SetBackdrop({
        bgFile   = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        tile = false, tileSize = 0, edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 },
    })
    eb:SetBackdropColor(T.inputBg[1], T.inputBg[2], T.inputBg[3], T.inputBg[4])
    eb:SetBackdropBorderColor(T.inputBorder[1], T.inputBorder[2], T.inputBorder[3], T.inputBorder[4])
    eb:SetTextInsets(8, 8, 0, 0)
    eb:SetTextColor(1, 1, 1)

    eb:SetScript("OnEnterPressed", function()
        SFrames.Pet:DoRename(this:GetText())
    end)
    eb:SetScript("OnEscapePressed", function()
        SFrames.Pet.renameFrame:Hide()
    end)
    eb:SetScript("OnEditFocusGained", function()
        this:SetBackdropBorderColor(T.accent[1], T.accent[2], T.accent[3], 1)
    end)
    eb:SetScript("OnEditFocusLost", function()
        this:SetBackdropBorderColor(T.inputBorder[1], T.inputBorder[2], T.inputBorder[3], T.inputBorder[4])
    end)

    f.editBox = eb

    local function CreateBtn(text, parent)
        local btn = CreateFrame("Button", nil, parent)
        btn:SetWidth(120)
        btn:SetHeight(26)
        btn:SetBackdrop({
            bgFile   = "Interface\\Buttons\\WHITE8X8",
            edgeFile = "Interface\\Buttons\\WHITE8X8",
            tile = false, tileSize = 0, edgeSize = 1,
            insets = { left = 1, right = 1, top = 1, bottom = 1 },
        })
        btn:SetBackdropColor(T.btnBg[1], T.btnBg[2], T.btnBg[3], T.btnBg[4])
        btn:SetBackdropBorderColor(T.btnBorder[1], T.btnBorder[2], T.btnBorder[3], T.btnBorder[4])
        local fs = btn:CreateFontString(nil, "OVERLAY")
        fs:SetFont(font, 11, outline)
        fs:SetPoint("CENTER", 0, 0)
        fs:SetText(text)
        fs:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
        btn.label = fs
        btn:SetScript("OnEnter", function()
            this:SetBackdropColor(T.btnHoverBg[1], T.btnHoverBg[2], T.btnHoverBg[3], T.btnHoverBg[4])
            this:SetBackdropBorderColor(T.btnHoverBd[1], T.btnHoverBd[2], T.btnHoverBd[3], T.btnHoverBd[4])
            this.label:SetTextColor(T.btnActiveText[1], T.btnActiveText[2], T.btnActiveText[3])
        end)
        btn:SetScript("OnLeave", function()
            this:SetBackdropColor(T.btnBg[1], T.btnBg[2], T.btnBg[3], T.btnBg[4])
            this:SetBackdropBorderColor(T.btnBorder[1], T.btnBorder[2], T.btnBorder[3], T.btnBorder[4])
            this.label:SetTextColor(T.btnText[1], T.btnText[2], T.btnText[3])
        end)
        return btn
    end

    local confirmBtn = CreateBtn("确定", f)
    confirmBtn:SetPoint("BOTTOMRIGHT", f, "BOTTOM", -4, 10)
    confirmBtn:SetScript("OnClick", function()
        SFrames.Pet:DoRename(f.editBox:GetText())
    end)

    local cancelBtn = CreateBtn("取消", f)
    cancelBtn:SetPoint("BOTTOMLEFT", f, "BOTTOM", 4, 10)
    cancelBtn:SetScript("OnClick", function()
        f:Hide()
    end)

    f:Hide()
    table.insert(UISpecialFrames, "SFramesPetRenameDialog")
    self.renameFrame = f
end

function SFrames.Pet:ShowRenameDialog()
    if not UnitExists("pet") then return end
    if not self.renameFrame then
        self:CreateRenameFrame()
    end
    local currentName = UnitName("pet") or ""
    self.renameFrame.editBox:SetText(currentName)
    self.renameFrame:Show()
    self.renameFrame.editBox:SetFocus()
    self.renameFrame.editBox:HighlightText()
end

function SFrames.Pet:DoRename(name)
    if not name or name == "" then return end
    if PetRename then
        PetRename(name)
    end
    if self.renameFrame then
        self.renameFrame:Hide()
    end
end

function SFrames.Pet:Initialize()
    local f = CreateFrame("Button", "SFramesPetFrame", UIParent)
    f:SetWidth(150)
    f:SetHeight(30)
    
    if SFramesDB and SFramesDB.Positions and SFramesDB.Positions["PetFrame"] then
        local pos = SFramesDB.Positions["PetFrame"]
        f:SetPoint(pos.point, UIParent, pos.relativePoint, pos.xOfs, pos.yOfs)
    else
        f:SetPoint("TOPLEFT", SFramesPlayerFrame, "BOTTOMLEFT", 10, -55)
    end
    
    local frameScale = (SFramesDB and type(SFramesDB.petFrameScale) == "number") and SFramesDB.petFrameScale or 1
    f:SetScale(Clamp(frameScale, 0.7, 1.8))
    
    f:SetMovable(true)
    f:EnableMouse(true)
    f:RegisterForDrag("LeftButton")
    f:SetScript("OnDragStart", function() if IsAltKeyDown() or SFrames.isUnlocked then f:StartMoving() end end)
    f:SetScript("OnDragStop", function()
        f:StopMovingOrSizing()
        if not SFramesDB then SFramesDB = {} end
        if not SFramesDB.Positions then SFramesDB.Positions = {} end
        local point, relativeTo, relativePoint, xOfs, yOfs = f:GetPoint()
        SFramesDB.Positions["PetFrame"] = { point = point, relativePoint = relativePoint, xOfs = xOfs, yOfs = yOfs }
    end)
    
    f:RegisterForClicks("LeftButtonUp", "RightButtonUp")
    f:SetScript("OnClick", function()
        if arg1 == "LeftButton" then
            if SpellIsTargeting() then
                SpellTargetUnit("pet")
            elseif CursorHasItem() then
                DropItemOnUnit("pet")
            else
                TargetUnit("pet")
            end
        else
            SFrames.Pet:ShowContextMenu()
        end
    end)
    
    f:SetScript("OnReceiveDrag", function()
        if CursorHasItem() then
            DropItemOnUnit("pet")
        end
    end)
    
    f:SetScript("OnEnter", function()
        GameTooltip_SetDefaultAnchor(GameTooltip, this)
        GameTooltip:SetUnit("pet")
        GameTooltip:Show()
    end)
    f:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)
    
    SFrames:CreateUnitBackdrop(f)
    
    -- Health Bar
    f.health = SFrames:CreateStatusBar(f, "SFramesPetHealth")
    f.health:SetPoint("TOPLEFT", f, "TOPLEFT", 1, -1)
    f.health:SetPoint("TOPRIGHT", f, "TOPRIGHT", -1, -1)
    f.health:SetHeight(18)
    
    local hbg = CreateFrame("Frame", nil, f)
    hbg:SetPoint("TOPLEFT", f.health, "TOPLEFT", -1, 1)
    hbg:SetPoint("BOTTOMRIGHT", f.health, "BOTTOMRIGHT", 1, -1)
    hbg:SetFrameLevel(f:GetFrameLevel() - 1)
    SFrames:CreateUnitBackdrop(hbg)
    
    f.health.bg = f.health:CreateTexture(nil, "BACKGROUND")
    f.health.bg:SetAllPoints()
    f.health.bg:SetTexture(SFrames:GetTexture())
    f.health.bg:SetVertexColor(_A.slotBg[1], _A.slotBg[2], _A.slotBg[3], _A.slotBg[4] or 1)

    -- Power Bar
    f.power = SFrames:CreateStatusBar(f, "SFramesPetPower")
    f.power:SetPoint("TOPLEFT", f.health, "BOTTOMLEFT", 0, -1)
    f.power:SetPoint("BOTTOMRIGHT", f, "BOTTOMRIGHT", -1, 1)
    
    local pbg = CreateFrame("Frame", nil, f)
    pbg:SetPoint("TOPLEFT", f.power, "TOPLEFT", -1, 1)
    pbg:SetPoint("BOTTOMRIGHT", f.power, "BOTTOMRIGHT", 1, -1)
    pbg:SetFrameLevel(f:GetFrameLevel() - 1)
    SFrames:CreateUnitBackdrop(pbg)
    
    f.power.bg = f.power:CreateTexture(nil, "BACKGROUND")
    f.power.bg:SetAllPoints()
    f.power.bg:SetTexture(SFrames:GetTexture())
    f.power.bg:SetVertexColor(_A.slotBg[1], _A.slotBg[2], _A.slotBg[3], _A.slotBg[4] or 1)
    
    -- Texts
    local fontPath = SFrames:GetFont()
    local outline = (SFrames and SFrames.Media and SFrames.Media.fontOutline) or "OUTLINE"
    
    f.nameText = SFrames:CreateFontString(f.health, 10, "LEFT")
    f.nameText:SetPoint("LEFT", f.health, "LEFT", 4, 0)
    f.nameText:SetWidth(75)
    f.nameText:SetHeight(12)
    f.nameText:SetJustifyH("LEFT")
    f.nameText:SetFont(fontPath, 10, outline)
    f.nameText:SetShadowColor(0, 0, 0, 1)
    f.nameText:SetShadowOffset(1, -1)
    
    f.healthText = SFrames:CreateFontString(f.health, 10, "RIGHT")
    f.healthText:SetPoint("RIGHT", f.health, "RIGHT", -4, 0)
    f.healthText:SetFont(fontPath, 10, outline)
    f.healthText:SetShadowColor(0, 0, 0, 1)
    f.healthText:SetShadowOffset(1, -1)

    -- Happiness Icon (for hunters)
    local hBG = CreateFrame("Frame", nil, f)
    hBG:SetWidth(20)
    hBG:SetHeight(20)
    hBG:SetPoint("RIGHT", f, "LEFT", -2, 0)
    SFrames:CreateUnitBackdrop(hBG)

    f.happiness = hBG:CreateTexture(nil, "OVERLAY")
    f.happiness:SetPoint("TOPLEFT", hBG, "TOPLEFT", 1, -1)
    f.happiness:SetPoint("BOTTOMRIGHT", hBG, "BOTTOMRIGHT", -1, 1)
    f.happiness:SetTexture("Interface\\PetPaperDollFrame\\UI-PetHappiness")
    
    f.happinessBG = hBG
    f.happinessBG:Hide()

    self.frame = f
    self.frame.unit = "pet"
    f:Hide()
    
    self:CreateCastbar()
    
    SFrames:RegisterEvent("UNIT_PET", function() if arg1 == "player" then self:UpdateAll() end end)
    SFrames:RegisterEvent("PET_BAR_UPDATE", function() self:UpdateAll() end)
    SFrames:RegisterEvent("UNIT_HEALTH", function() if arg1 == "pet" then self:UpdateHealth() end end)
    SFrames:RegisterEvent("UNIT_MAXHEALTH", function() if arg1 == "pet" then self:UpdateHealth() end end)
    SFrames:RegisterEvent("UNIT_MANA", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_MAXMANA", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_ENERGY", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_MAXENERGY", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_FOCUS", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_MAXFOCUS", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_RAGE", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_MAXRAGE", function() if arg1 == "pet" then self:UpdatePower() end end)
    SFrames:RegisterEvent("UNIT_DISPLAYPOWER", function() if arg1 == "pet" then self:UpdatePowerType() end end)
    SFrames:RegisterEvent("UNIT_HAPPINESS", function() if arg1 == "pet" then self:UpdateHappiness() end end)
    SFrames:RegisterEvent("UNIT_NAME_UPDATE", function() if arg1 == "pet" then self:UpdateAll() end end)
    SFrames:RegisterEvent("PLAYER_ENTERING_WORLD", function() self:UpdateAll() end)
    
    self:InitFoodFeature()
    self:UpdateAll()

    if SFrames.Movers and SFrames.Movers.RegisterMover and self.frame then
        SFrames.Movers:RegisterMover("PetFrame", self.frame, "宠物",
            "TOPLEFT", "SFramesPlayerFrame", "BOTTOMLEFT", 10, -55)
    end

    if StaticPopup_Show then
        local origStaticPopupShow = StaticPopup_Show
        StaticPopup_Show = function(which, a1, a2, a3)
            if which == "RENAME_PET" then
                SFrames.Pet:ShowRenameDialog()
                return
            end
            return origStaticPopupShow(which, a1, a2, a3)
        end
    end
end

function SFrames.Pet:UpdateAll()
    if UnitExists("pet") then
        if SFramesDB and SFramesDB.showPetFrame == false then
            self.frame:Hide()
            if self.foodPanel then self.foodPanel:Hide() end
            return
        end
        
        self.frame:Show()
        self:UpdateHealth()
        self:UpdatePowerType()
        self:UpdatePower()
        self:UpdateHappiness()
        
        local name = UnitName("pet")
        if name == UNKNOWNOBJECT or name == "未知目标" or name == "Unknown" then
            name = "宠物"
        end
        self.frame.nameText:SetText(name)
        
        local r, g, b = 0.33, 0.59, 0.33
        self.frame.health:SetStatusBarColor(r, g, b)
    else
        self.frame:Hide()
        if self.foodPanel then self.foodPanel:Hide() end
    end
end

function SFrames.Pet:UpdateHealth()
    local hp = UnitHealth("pet")
    local maxHp = UnitHealthMax("pet")
    self.frame.health:SetMinMaxValues(0, maxHp)
    self.frame.health:SetValue(hp)
    
    if maxHp > 0 then
        self.frame.healthText:SetText(hp .. " / " .. maxHp)
    else
        self.frame.healthText:SetText("")
    end
end

function SFrames.Pet:UpdatePowerType()
    local powerType = UnitPowerType("pet")
    local color = SFrames.Config.colors.power[powerType]
    if color then
        self.frame.power:SetStatusBarColor(color.r, color.g, color.b)
    else
        self.frame.power:SetStatusBarColor(0, 0, 1)
    end
end

function SFrames.Pet:UpdatePower()
    local power = UnitMana("pet")
    local maxPower = UnitManaMax("pet")
    self.frame.power:SetMinMaxValues(0, maxPower)
    self.frame.power:SetValue(power)
end

function SFrames.Pet:UpdateHappiness()
    local happiness = GetPetHappiness()
    if not happiness then
        self.frame.happinessBG:Hide()
        self:UpdateFoodButton()
        return
    end

    local isHunter = false
    local _, class = UnitClass("player")
    if class == "HUNTER" then isHunter = true end

    if isHunter then
        if happiness == 1 then
            self.frame.happiness:SetTexCoord(0.375, 0.5625, 0, 0.359375)
            self.frame.happinessBG:Show()
        elseif happiness == 2 then
            self.frame.happiness:SetTexCoord(0.1875, 0.375, 0, 0.359375)
            self.frame.happinessBG:Show()
        elseif happiness == 3 then
            self.frame.happiness:SetTexCoord(0, 0.1875, 0, 0.359375)
            self.frame.happinessBG:Show()
        end
    else
        self.frame.happinessBG:Hide()
    end
    self:UpdateFoodButton()
end

--------------------------------------------------------------------------------
-- Pet Food Feature (Hunter only)
-- Food button on pet frame, food selection panel, quick-feed via right-click
--------------------------------------------------------------------------------

local petFoodScanTip
local cachedFeedSpell

local function EnsureFoodScanTooltip()
    if not petFoodScanTip then
        petFoodScanTip = CreateFrame("GameTooltip", "NanamiPetFoodScanTip", UIParent, "GameTooltipTemplate")
        petFoodScanTip:SetOwner(UIParent, "ANCHOR_NONE")
    end
    return petFoodScanTip
end

local function GetFeedPetSpell()
    if cachedFeedSpell then return cachedFeedSpell end
    for tab = 1, GetNumSpellTabs() do
        local _, _, offset, numSpells = GetSpellTabInfo(tab)
        for i = offset + 1, offset + numSpells do
            local spellName = GetSpellName(i, BOOKTYPE_SPELL)
            if spellName and (spellName == "Feed Pet" or spellName == "喂养宠物") then
                cachedFeedSpell = spellName
                return cachedFeedSpell
            end
        end
    end
    cachedFeedSpell = "Feed Pet"
    return cachedFeedSpell
end

local REJECT_NAME_PATTERNS = {
    "Potion", "potion", "药水",
    "Elixir", "elixir", "药剂",
    "Flask", "flask", "合剂",
    "Bandage", "bandage", "绷带",
    "Scroll", "scroll", "卷轴",
    "Healthstone", "healthstone", "治疗石",
    "Mana Gem", "法力宝石",
    "Thistle Tea", "蓟花茶",
    "Firewater", "火焰花水",
    "Juju", "符咒",
}

local function NameIsRejected(itemName)
    for i = 1, table.getn(REJECT_NAME_PATTERNS) do
        if string.find(itemName, REJECT_NAME_PATTERNS[i], 1, true) then
            return true
        end
    end
    return false
end

local function IsItemPetFood(bag, slot)
    local link = GetContainerItemLink(bag, slot)
    if not link then return false end

    local texture = GetContainerItemInfo(bag, slot)

    local _, _, itemIdStr = string.find(link, "item:(%d+)")
    local name, itemType, subType

    if itemIdStr then
        local n, _, _, _, _, t, st = GetItemInfo("item:" .. itemIdStr)
        name = n
        itemType = t
        subType = st
    end

    if not name then
        local _, _, parsed = string.find(link, "%[(.+)%]")
        name = parsed
    end
    if not name then return false end

    if NameIsRejected(name) then
        return false
    end

    if itemType then
        if itemType ~= "Consumable" and itemType ~= "消耗品" then
            return false
        end
        if subType then
            if string.find(subType, "Potion", 1, true) or string.find(subType, "药水", 1, true)
               or string.find(subType, "Elixir", 1, true) or string.find(subType, "药剂", 1, true)
               or string.find(subType, "Flask", 1, true) or string.find(subType, "合剂", 1, true)
               or string.find(subType, "Bandage", 1, true) or string.find(subType, "绷带", 1, true)
               or string.find(subType, "Scroll", 1, true) or string.find(subType, "卷轴", 1, true) then
                return false
            end
            if string.find(subType, "Food", 1, true) or string.find(subType, "食物", 1, true) then
                return true, name, texture
            end
        end
    end

    local tip = EnsureFoodScanTooltip()
    tip:SetOwner(UIParent, "ANCHOR_NONE")
    tip:SetBagItem(bag, slot)

    local found = false
    local rejected = false
    for i = 1, tip:NumLines() do
        local leftObj = _G["NanamiPetFoodScanTipTextLeft" .. i]
        if leftObj then
            local text = leftObj:GetText()
            if text then
                if string.find(text, "进食", 1, true) or string.find(text, "eating", 1, true) then
                    found = true
                end
                if string.find(text, "Well Fed", 1, true) or string.find(text, "充分进食", 1, true) then
                    found = true
                end
                if string.find(text, "Restores", 1, true) and string.find(text, "health", 1, true)
                   and string.find(text, "over", 1, true) then
                    found = true
                end
                if string.find(text, "恢复", 1, true) and string.find(text, "生命", 1, true)
                   and string.find(text, "秒", 1, true) then
                    found = true
                end
                if string.find(text, "Potion", 1, true) or string.find(text, "药水", 1, true)
                   or string.find(text, "Elixir", 1, true) or string.find(text, "药剂", 1, true)
                   or string.find(text, "Bandage", 1, true) or string.find(text, "绷带", 1, true) then
                    rejected = true
                end
            end
        end
    end
    tip:Hide()

    if found and not rejected then
        return true, name, texture
    end

    if itemType and subType then
        if (itemType == "Consumable" or itemType == "消耗品")
           and (subType == "Food & Drink" or subType == "食物和饮料") then
            return true, name, texture
        end
    end

    return false
end

function SFrames.Pet:ScanBagsForFood()
    local foods = {}
    for bag = 0, 4 do
        for slot = 1, GetContainerNumSlots(bag) do
            local isFood, name, itemTex = IsItemPetFood(bag, slot)
            if isFood then
                local texture, itemCount = GetContainerItemInfo(bag, slot)
                local link = GetContainerItemLink(bag, slot)
                table.insert(foods, {
                    bag = bag,
                    slot = slot,
                    name = name,
                    link = link,
                    texture = texture or itemTex,
                    count = itemCount or 1,
                })
            end
        end
    end
    return foods
end

function SFrames.Pet:FeedPet(bag, slot)
    if not UnitExists("pet") then return end
    local link = GetContainerItemLink(bag, slot)
    local tex = GetContainerItemInfo(bag, slot)
    local spell = GetFeedPetSpell()
    CastSpellByName(spell)
    PickupContainerItem(bag, slot)
    if link then
        local _, _, itemId = string.find(link, "item:(%d+)")
        if itemId then
            if not SFramesDB then SFramesDB = {} end
            SFramesDB.lastPetFoodId = tonumber(itemId)
        end
    end
    if tex and self.foodButton then
        self.foodButton.icon:SetTexture(tex)
        if not SFramesDB then SFramesDB = {} end
        SFramesDB.lastPetFoodIcon = tex
    end
end

function SFrames.Pet:QuickFeed()
    if not UnitExists("pet") then return end
    local foods = self:ScanBagsForFood()
    if table.getn(foods) == 0 then
        DEFAULT_CHAT_FRAME:AddMessage("|cffff9900[Nanami]|r 背包中没有可喂食的食物")
        return
    end
    local preferred = SFramesDB and SFramesDB.lastPetFoodId
    if preferred then
        for i = 1, table.getn(foods) do
            local f = foods[i]
            if f.link then
                local _, _, itemId = string.find(f.link, "item:(%d+)")
                if itemId and tonumber(itemId) == preferred then
                    self:FeedPet(f.bag, f.slot)
                    return
                end
            end
        end
    end
    self:FeedPet(foods[1].bag, foods[1].slot)
end

--------------------------------------------------------------------------------
-- Food Button & Panel UI
--------------------------------------------------------------------------------

local FOOD_COLS = 6
local FOOD_SLOT_SIZE = 30
local FOOD_SLOT_GAP = 2
local FOOD_PAD = 8

function SFrames.Pet:CreateFoodButton()
    local f = self.frame
    local A = SFrames.ActiveTheme

    local btn = CreateFrame("Button", "SFramesPetFoodBtn", f)
    btn:SetWidth(20)
    btn:SetHeight(20)
    btn:SetPoint("TOP", f.happinessBG, "BOTTOM", 0, -2)
    SFrames:CreateUnitBackdrop(btn)

    local icon = btn:CreateTexture(nil, "ARTWORK")
    icon:SetPoint("TOPLEFT", btn, "TOPLEFT", 1, -1)
    icon:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", -1, 1)
    icon:SetTexture("Interface\\Icons\\INV_Misc_Food_14")
    btn.icon = icon

    btn:RegisterForClicks("LeftButtonUp", "RightButtonUp")

    local pet = self
    btn:SetScript("OnClick", function()
        if CursorHasItem() then
            local curTex = pet:GetCursorItemTexture()
            DropItemOnUnit("pet")
            if curTex then
                pet:SetFoodIcon(curTex)
            end
            return
        end
        if arg1 == "RightButton" then
            pet:QuickFeed()
        else
            if pet.foodPanel and pet.foodPanel:IsShown() then
                pet.foodPanel:Hide()
            else
                pet:ShowFoodPanel()
            end
        end
    end)

    btn:SetScript("OnEnter", function()
        GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
        GameTooltip:AddLine("喂养宠物", 1, 1, 1)
        GameTooltip:AddLine("左键: 选择食物", 0.7, 0.7, 0.7)
        GameTooltip:AddLine("右键: 快速喂食", 0.7, 0.7, 0.7)
        GameTooltip:AddLine("可拖拽背包食物到此按钮", 0.7, 0.7, 0.7)
        GameTooltip:Show()
    end)

    btn:SetScript("OnLeave", function()
        GameTooltip:Hide()
    end)

    btn:SetScript("OnReceiveDrag", function()
        if CursorHasItem() then
            DropItemOnUnit("pet")
        end
    end)

    self.foodButton = btn
    btn:Hide()
end

function SFrames.Pet:CreateFoodPanel()
    if self.foodPanel then return self.foodPanel end

    local A = SFrames.ActiveTheme

    local panel = CreateFrame("Frame", "SFramesPetFoodPanel", UIParent)
    panel:SetFrameStrata("DIALOG")
    panel:SetFrameLevel(20)
    panel:SetWidth(FOOD_COLS * (FOOD_SLOT_SIZE + FOOD_SLOT_GAP) + FOOD_PAD * 2 - FOOD_SLOT_GAP)
    panel:SetHeight(80)
    panel:SetPoint("BOTTOMLEFT", self.frame, "TOPLEFT", -22, 4)
    SFrames:CreateUnitBackdrop(panel)
    panel:EnableMouse(true)
    panel:Hide()

    local titleBar = CreateFrame("Frame", nil, panel)
    titleBar:SetPoint("TOPLEFT", panel, "TOPLEFT", 1, -1)
    titleBar:SetPoint("TOPRIGHT", panel, "TOPRIGHT", -1, -1)
    titleBar:SetHeight(18)
    titleBar:SetBackdrop({ bgFile = "Interface\\Buttons\\WHITE8X8" })
    local hdr = A.headerBg or A.panelBg
    titleBar:SetBackdropColor(hdr[1], hdr[2], hdr[3], (hdr[4] or 0.9) * 0.6)

    local titleText = titleBar:CreateFontString(nil, "OVERLAY")
    titleText:SetFont(SFrames:GetFont(), 10, SFrames.Media.fontOutline or "OUTLINE")
    titleText:SetPoint("LEFT", titleBar, "LEFT", FOOD_PAD, 0)
    titleText:SetTextColor(A.title[1], A.title[2], A.title[3])
    titleText:SetText("选择食物")
    panel.titleText = titleText

    local hintText = panel:CreateFontString(nil, "OVERLAY")
    hintText:SetFont(SFrames:GetFont(), 9, SFrames.Media.fontOutline or "OUTLINE")
    hintText:SetPoint("BOTTOMLEFT", panel, "BOTTOMLEFT", FOOD_PAD, 4)
    hintText:SetPoint("BOTTOMRIGHT", panel, "BOTTOMRIGHT", -FOOD_PAD, 4)
    hintText:SetJustifyH("LEFT")
    local dim = A.dimText or { 0.5, 0.5, 0.5 }
    hintText:SetTextColor(dim[1], dim[2], dim[3])
    hintText:SetText("点击喂食 | 可拖拽食物到此面板")
    panel.hintText = hintText

    local emptyText = panel:CreateFontString(nil, "OVERLAY")
    emptyText:SetFont(SFrames:GetFont(), 10, SFrames.Media.fontOutline or "OUTLINE")
    emptyText:SetPoint("CENTER", panel, "CENTER", 0, 0)
    emptyText:SetTextColor(dim[1], dim[2], dim[3])
    emptyText:SetText("背包中没有可喂食的食物")
    emptyText:Hide()
    panel.emptyText = emptyText

    local pet = self
    panel:SetScript("OnReceiveDrag", function()
        if CursorHasItem() then
            local curTex = pet:GetCursorItemTexture()
            DropItemOnUnit("pet")
            if curTex then
                pet:SetFoodIcon(curTex)
            end
        end
    end)

    table.insert(UISpecialFrames, "SFramesPetFoodPanel")

    panel.slots = {}
    self.foodPanel = panel
    return panel
end

function SFrames.Pet:CreateFoodSlot(parent, index)
    local A = SFrames.ActiveTheme

    local slot = CreateFrame("Button", "SFramesPetFoodSlot" .. index, parent)
    slot:SetWidth(FOOD_SLOT_SIZE)
    slot:SetHeight(FOOD_SLOT_SIZE)
    slot:SetBackdrop({
        bgFile = "Interface\\Buttons\\WHITE8X8",
        edgeFile = "Interface\\Buttons\\WHITE8X8",
        tile = false, tileSize = 0, edgeSize = 1,
        insets = { left = 1, right = 1, top = 1, bottom = 1 }
    })
    slot:SetBackdropColor(A.slotBg[1], A.slotBg[2], A.slotBg[3], A.slotBg[4] or 0.9)
    slot:SetBackdropBorderColor(0, 0, 0, 1)

    local icon = slot:CreateTexture(nil, "ARTWORK")
    icon:SetPoint("TOPLEFT", 2, -2)
    icon:SetPoint("BOTTOMRIGHT", -2, 2)
    slot.icon = icon

    local count = slot:CreateFontString(nil, "OVERLAY")
    count:SetFont(SFrames:GetFont(), 10, "OUTLINE")
    count:SetPoint("BOTTOMRIGHT", -2, 2)
    count:SetJustifyH("RIGHT")
    count:SetTextColor(1, 1, 1)
    slot.count = count

    slot:RegisterForClicks("LeftButtonUp", "RightButtonUp")

    local pet = self
    slot:SetScript("OnClick", function()
        if CursorHasItem() then
            local curTex = pet:GetCursorItemTexture()
            DropItemOnUnit("pet")
            if curTex then
                pet:SetFoodIcon(curTex)
            end
            return
        end
        if IsShiftKeyDown() and this.foodLink then
            if ChatFrameEditBox and ChatFrameEditBox:IsVisible() then
                ChatFrameEditBox:Insert(this.foodLink)
            end
            return
        end
        if this.foodBag and this.foodSlot then
            pet:FeedPet(this.foodBag, this.foodSlot)
            if pet.foodPanel then pet.foodPanel:Hide() end
        end
    end)

    slot:SetScript("OnEnter", function()
        if this.foodBag and this.foodSlot then
            GameTooltip:SetOwner(this, "ANCHOR_RIGHT")
            GameTooltip:SetBagItem(this.foodBag, this.foodSlot)
            GameTooltip:AddLine(" ")
            GameTooltip:AddLine("点击: 喂食宠物", 0.5, 1, 0.5)
            GameTooltip:AddLine("Shift+点击: 链接到聊天", 0.7, 0.7, 0.7)
            GameTooltip:Show()
        end
        this:SetBackdropBorderColor(0.4, 0.4, 0.4, 1)
    end)

    slot:SetScript("OnLeave", function()
        GameTooltip:Hide()
        this:SetBackdropBorderColor(0, 0, 0, 1)
    end)

    slot:SetScript("OnReceiveDrag", function()
        if CursorHasItem() then
            DropItemOnUnit("pet")
        end
    end)

    return slot
end

function SFrames.Pet:ShowFoodPanel()
    self:CreateFoodPanel()
    self:RefreshFoodPanel()
    self.foodPanel:Show()
end

function SFrames.Pet:RefreshFoodPanel()
    local panel = self.foodPanel
    if not panel then return end

    local foods = self:ScanBagsForFood()
    local numFoods = table.getn(foods)

    for i = 1, table.getn(panel.slots) do
        panel.slots[i]:Hide()
    end

    if numFoods == 0 then
        panel:SetHeight(60)
        panel.emptyText:Show()
        panel.hintText:Hide()
        return
    end

    panel.emptyText:Hide()
    panel.hintText:Show()

    local rows = math.ceil(numFoods / FOOD_COLS)
    local panelH = FOOD_PAD + 20 + rows * (FOOD_SLOT_SIZE + FOOD_SLOT_GAP) + 18
    panel:SetHeight(panelH)

    for i = 1, numFoods do
        local food = foods[i]
        local slot = panel.slots[i]
        if not slot then
            slot = self:CreateFoodSlot(panel, i)
            panel.slots[i] = slot
        end

        local col = mod(i - 1, FOOD_COLS)
        local row = math.floor((i - 1) / FOOD_COLS)

        slot:ClearAllPoints()
        slot:SetPoint("TOPLEFT", panel, "TOPLEFT",
            FOOD_PAD + col * (FOOD_SLOT_SIZE + FOOD_SLOT_GAP),
            -(FOOD_PAD + 18 + row * (FOOD_SLOT_SIZE + FOOD_SLOT_GAP)))

        slot.icon:SetTexture(food.texture)
        slot.count:SetText(food.count > 1 and tostring(food.count) or "")
        slot.foodBag = food.bag
        slot.foodSlot = food.slot
        slot.foodName = food.name
        slot.foodLink = food.link
        slot:Show()
    end
end

function SFrames.Pet:GetCursorItemTexture()
    for bag = 0, 4 do
        for slot = 1, GetContainerNumSlots(bag) do
            local texture, count, locked = GetContainerItemInfo(bag, slot)
            if locked and texture then
                return texture
            end
        end
    end
    return nil
end

function SFrames.Pet:SetFoodIcon(tex)
    if not tex or not self.foodButton then return end
    self.foodButton.icon:SetTexture(tex)
    if not SFramesDB then SFramesDB = {} end
    SFramesDB.lastPetFoodIcon = tex
end

function SFrames.Pet:InitFoodFeature()
    local _, playerClass = UnitClass("player")
    if playerClass ~= "HUNTER" then return end

    self:CreateFoodButton()

    if SFramesDB and SFramesDB.lastPetFoodIcon then
        self.foodButton.icon:SetTexture(SFramesDB.lastPetFoodIcon)
    end

    local pet = self
    SFrames:RegisterEvent("BAG_UPDATE", function()
        if pet.foodPanel and pet.foodPanel:IsShown() then
            pet:RefreshFoodPanel()
        end
    end)
end

function SFrames.Pet:UpdateFoodButton()
    if not self.foodButton then return end

    local _, class = UnitClass("player")
    if class == "HUNTER" and UnitExists("pet") then
        self.foodButton:Show()
        local happiness = GetPetHappiness()
        if happiness and happiness == 1 then
            self.foodButton.icon:SetVertexColor(1, 0.3, 0.3)
        elseif happiness and happiness == 2 then
            self.foodButton.icon:SetVertexColor(1, 0.8, 0.4)
        else
            self.foodButton.icon:SetVertexColor(1, 1, 1)
        end
    else
        self.foodButton:Hide()
        if self.foodPanel then self.foodPanel:Hide() end
    end
end

--------------------------------------------------------------------------------
-- Pet Castbar
--------------------------------------------------------------------------------

function SFrames.Pet:CreateCastbar()
    local f = self.frame
    local cbHeight = SFrames.Config.castbarHeight

    local cb = SFrames:CreateStatusBar(f, "SFramesPetCastbar")
    cb:SetHeight(cbHeight)
    cb:SetPoint("BOTTOMLEFT", f, "TOPLEFT", 0, 4)
    cb:SetPoint("BOTTOMRIGHT", f, "TOPRIGHT", -(cbHeight + 6), 4)

    local cbbg = CreateFrame("Frame", nil, f)
    cbbg:SetPoint("TOPLEFT", cb, "TOPLEFT", -1, 1)
    cbbg:SetPoint("BOTTOMRIGHT", cb, "BOTTOMRIGHT", 1, -1)
    cbbg:SetFrameLevel(cb:GetFrameLevel() - 1)
    SFrames:CreateUnitBackdrop(cbbg)

    cb.bg = cb:CreateTexture(nil, "BACKGROUND")
    cb.bg:SetAllPoints()
    cb.bg:SetTexture(SFrames:GetTexture())
    cb.bg:SetVertexColor(_A.slotBg[1], _A.slotBg[2], _A.slotBg[3], _A.slotBg[4] or 1)
    cb:SetStatusBarColor(1, 0.7, 0)

    cb.text = SFrames:CreateFontString(cb, 10, "LEFT")
    cb.text:SetPoint("LEFT", cb, "LEFT", 4, 0)

    cb.time = SFrames:CreateFontString(cb, 10, "RIGHT")
    cb.time:SetPoint("RIGHT", cb, "RIGHT", -4, 0)

    cb.icon = cb:CreateTexture(nil, "ARTWORK")
    cb.icon:SetWidth(cbHeight + 2)
    cb.icon:SetHeight(cbHeight + 2)
    cb.icon:SetPoint("LEFT", cb, "RIGHT", 4, 0)
    cb.icon:SetTexCoord(0.07, 0.93, 0.07, 0.93)

    local ibg = CreateFrame("Frame", nil, f)
    ibg:SetPoint("TOPLEFT", cb.icon, "TOPLEFT", -1, 1)
    ibg:SetPoint("BOTTOMRIGHT", cb.icon, "BOTTOMRIGHT", 1, -1)
    ibg:SetFrameLevel(cb:GetFrameLevel() - 1)
    SFrames:CreateUnitBackdrop(ibg)

    cb:Hide()
    cbbg:Hide()
    cb.icon:Hide()
    ibg:Hide()

    f.castbar = cb
    f.castbar.cbbg = cbbg
    f.castbar.ibg = ibg

    f.castbarUpdater = CreateFrame("Frame", nil, f)
    f.castbarUpdater:SetScript("OnUpdate", function() SFrames.Pet:CastbarOnUpdate() end)
end

function SFrames.Pet:CastbarOnUpdate()
    local cb = self.frame.castbar
    if not UnitExists("pet") then
        cb:Hide()
        cb.cbbg:Hide()
        cb.icon:Hide()
        cb.ibg:Hide()
        return
    end

    local cast, texture, startTime, endTime, channel

    -- 1) Try native UnitCastingInfo / UnitChannelInfo (TurtleWoW extended API)
    local _UnitCastingInfo = UnitCastingInfo or (ShaguTweaks and ShaguTweaks.UnitCastingInfo)
    if _UnitCastingInfo then
        local c, _, _, tex, st, et = _UnitCastingInfo("pet")
        if c then
            cast, texture, startTime, endTime = c, tex, st, et
        end
    end

    if not cast then
        local _UnitChannelInfo = UnitChannelInfo or (ShaguTweaks and ShaguTweaks.UnitChannelInfo)
        if _UnitChannelInfo then
            local c, _, _, tex, st, et = _UnitChannelInfo("pet")
            if c then
                cast, texture, startTime, endTime = c, tex, st, et
                channel = true
            end
        end
    end

    -- 2) Fallback: SuperWoW castdb (GUID-based)
    if not cast and SFrames.castdb and UnitGUID then
        local guid = UnitGUID("pet")
        if guid then
            local entry = SFrames.castdb[guid]
            if entry and entry.cast and entry.start and entry.casttime then
                local elapsed = GetTime() - entry.start
                local duration = entry.casttime / 1000
                if elapsed < duration + 0.5 then
                    cast = entry.cast
                    texture = entry.icon
                    startTime = entry.start * 1000
                    endTime = (entry.start + duration) * 1000
                    channel = entry.channel
                end
            end
        end
    end

    if cast and startTime and endTime then
        local duration = (endTime - startTime) / 1000
        local cur = GetTime() - (startTime / 1000)

        if channel then
            cur = duration + (startTime / 1000) - GetTime()
        end

        if cur > duration then cur = duration end
        if cur < 0 then cur = 0 end

        cb:SetMinMaxValues(0, duration)
        cb:SetValue(cur)
        cb.text:SetText(cast)
        cb.time:SetText(string.format("%.1f", channel and cur or math.max(duration - cur, 0)))

        if texture then
            cb.icon:SetTexture(texture)
        end

        cb:SetAlpha(1)
        cb.cbbg:SetAlpha(1)
        cb.icon:SetAlpha(1)
        cb.ibg:SetAlpha(1)

        cb:Show()
        cb.cbbg:Show()
        cb.icon:Show()
        cb.ibg:Show()
    else
        if cb:IsShown() then
            local alpha = cb:GetAlpha() - 0.05
            if alpha > 0 then
                cb:SetAlpha(alpha)
                cb.cbbg:SetAlpha(alpha)
                cb.icon:SetAlpha(alpha)
                cb.ibg:SetAlpha(alpha)
            else
                cb:Hide()
                cb.cbbg:Hide()
                cb.icon:Hide()
                cb.ibg:Hide()
            end
        end
    end
end
