--------------------------------------------------------------------------------
-- Nanami-UI: Pet Stable Skin (PetStableSkin.lua)
-- Skins the Blizzard PetStableFrame with Nanami-UI theme
--------------------------------------------------------------------------------

SFrames = SFrames or {}
SFrames.PetStableSkin = {}
SFramesDB = SFramesDB or {}

local T = SFrames.ActiveTheme
local skinned = false

local function GetFont()
    if SFrames and SFrames.GetFont then return SFrames:GetFont() end
    return "Fonts\\ARIALN.TTF"
end

--------------------------------------------------------------------------------
-- Helpers
--------------------------------------------------------------------------------
local function NukeTextures(frame, exceptions)
    local regions = { frame:GetRegions() }
    for _, r in ipairs(regions) do
        if r:IsObjectType("Texture") and not r.sfKeep then
            local rName = r:GetName()
            local skip = false
            if exceptions and rName then
                for _, exc in ipairs(exceptions) do
                    if string.find(rName, exc) then
                        skip = true
                        break
                    end
                end
            end
            if not skip then
                r:SetTexture(nil)
                r:SetAlpha(0)
                r:Hide()
                r.sfNuked = true
                r:ClearAllPoints()
                r:SetPoint("CENTER", UIParent, "CENTER", 9999, 9999)
            end
        end
    end
end

local function NukeChildTextures(frame)
    local children = { frame:GetChildren() }
    for _, child in ipairs(children) do
        local cName = child:GetName() or ""
        if string.find(cName, "Inset") or string.find(cName, "Bg") then
            NukeTextures(child)
            if child.SetBackdrop then child:SetBackdrop(nil) end
        end
    end
end

local function SetRoundBackdrop(frame)
    frame: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 },
    })
    frame:SetBackdropColor(T.panelBg[1], T.panelBg[2], T.panelBg[3], T.panelBg[4])
    frame:SetBackdropBorderColor(T.panelBorder[1], T.panelBorder[2], T.panelBorder[3], T.panelBorder[4])
end

local function CreateShadow(parent)
    local s = CreateFrame("Frame", nil, parent)
    s:SetPoint("TOPLEFT", parent, "TOPLEFT", -4, 4)
    s:SetPoint("BOTTOMRIGHT", parent, "BOTTOMRIGHT", 4, -4)
    s: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 },
    })
    s:SetBackdropColor(0, 0, 0, 0.45)
    s:SetBackdropBorderColor(0, 0, 0, 0.6)
    s:SetFrameLevel(math.max(0, parent:GetFrameLevel() - 1))
    return s
end

local function MarkBackdropRegions(frame)
    local regions = { frame:GetRegions() }
    for _, r in ipairs(regions) do
        if not r.sfNuked then r.sfKeep = true end
    end
end

--------------------------------------------------------------------------------
-- Slot styling (ItemButton-type pet slot buttons)
--------------------------------------------------------------------------------
local function StyleSlot(btn)
    if not btn or btn.sfSkinned then return end
    btn.sfSkinned = true

    local bname = btn:GetName() or ""

    local normalTex = _G[bname .. "NormalTexture"]
    if normalTex then normalTex:SetAlpha(0) end

    NukeTextures(btn, { "Icon", "Count" })

    local iconTex = _G[bname .. "IconTexture"]
    if iconTex then
        iconTex:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        iconTex.sfKeep = true
    end

    local bg = btn:CreateTexture(nil, "BACKGROUND")
    bg:SetTexture("Interface\\Tooltips\\UI-Tooltip-Background")
    bg:SetAllPoints()
    bg:SetVertexColor(T.slotBg[1], T.slotBg[2], T.slotBg[3], T.slotBg[4] or 0.8)
    bg.sfKeep = true

    local border = CreateFrame("Frame", nil, btn)
    border:SetPoint("TOPLEFT", btn, "TOPLEFT", -2, 2)
    border:SetPoint("BOTTOMRIGHT", btn, "BOTTOMRIGHT", 2, -2)
    border:SetBackdrop({
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        edgeSize = 10,
        insets = { left = 2, right = 2, top = 2, bottom = 2 },
    })
    border:SetBackdropBorderColor(T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
    btn.sfBorder = border

    local origEnter = btn:GetScript("OnEnter")
    local origLeave = btn:GetScript("OnLeave")

    btn:SetScript("OnEnter", function()
        if origEnter then origEnter() end
        if this.sfBorder then
            this.sfBorder:SetBackdropBorderColor(
                T.slotHover[1], T.slotHover[2], T.slotHover[3], T.slotHover[4] or 1)
        end
    end)

    btn:SetScript("OnLeave", function()
        if origLeave then origLeave() end
        if this.sfBorder then
            this.sfBorder:SetBackdropBorderColor(
                T.slotBorder[1], T.slotBorder[2], T.slotBorder[3], T.slotBorder[4])
        end
    end)
end

--------------------------------------------------------------------------------
-- Close button styling
--------------------------------------------------------------------------------
local function StyleCloseButton(btn)
    if not btn or btn.sfSkinned then return end
    btn.sfSkinned = true

    btn:SetWidth(22)
    btn:SetHeight(22)
    btn:ClearAllPoints()
    btn:SetPoint("TOPRIGHT", btn:GetParent(), "TOPRIGHT", -6, -6)

    if btn.GetNormalTexture and btn:GetNormalTexture() then
        btn:GetNormalTexture():SetAlpha(0)
    end
    if btn.GetPushedTexture and btn:GetPushedTexture() then
        btn:GetPushedTexture():SetAlpha(0)
    end
    if btn.GetHighlightTexture and btn:GetHighlightTexture() then
        btn:GetHighlightTexture():SetAlpha(0)
    end

    btn:SetBackdrop({
        bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
        edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
        tile = true, tileSize = 8, edgeSize = 8,
        insets = { left = 2, right = 2, top = 2, bottom = 2 },
    })

    local cbg  = { 0.5, 0.1, 0.1, 0.85 }
    local cbd  = { 0.6, 0.2, 0.2, 0.8 }
    local cbgH = { 0.7, 0.15, 0.15, 1 }
    local cbdH = { 0.9, 0.3, 0.3, 1 }

    btn:SetBackdropColor(cbg[1], cbg[2], cbg[3], cbg[4])
    btn:SetBackdropBorderColor(cbd[1], cbd[2], cbd[3], cbd[4])

    local xLabel = btn:CreateFontString(nil, "OVERLAY")
    xLabel:SetFont(GetFont(), 11, "OUTLINE")
    xLabel:SetPoint("CENTER", 0, 0)
    xLabel:SetText("X")
    xLabel:SetTextColor(0.9, 0.8, 0.8)

    local origEnter = btn:GetScript("OnEnter")
    local origLeave = btn:GetScript("OnLeave")

    btn:SetScript("OnEnter", function()
        if origEnter then origEnter() end
        this:SetBackdropColor(cbgH[1], cbgH[2], cbgH[3], cbgH[4])
        this:SetBackdropBorderColor(cbdH[1], cbdH[2], cbdH[3], cbdH[4])
    end)

    btn:SetScript("OnLeave", function()
        if origLeave then origLeave() end
        this:SetBackdropColor(cbg[1], cbg[2], cbg[3], cbg[4])
        this:SetBackdropBorderColor(cbd[1], cbd[2], cbd[3], cbd[4])
    end)
end

--------------------------------------------------------------------------------
-- UIPanelButton styling (purchase button etc.)
--------------------------------------------------------------------------------
local function StyleActionButton(btn)
    if not btn or btn.sfSkinned then return end
    btn.sfSkinned = true

    btn: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 },
    })

    local bg = T.btnBg
    local bd = T.btnBorder
    btn:SetBackdropColor(bg[1], bg[2], bg[3], bg[4])
    btn:SetBackdropBorderColor(bd[1], bd[2], bd[3], bd[4])

    if btn.GetNormalTexture and btn:GetNormalTexture() then
        btn:GetNormalTexture():SetTexture(nil)
    end
    if btn.GetPushedTexture and btn:GetPushedTexture() then
        btn:GetPushedTexture():SetTexture(nil)
    end
    if btn.GetHighlightTexture and btn:GetHighlightTexture() then
        btn:GetHighlightTexture():SetAlpha(0)
    end
    if btn.GetDisabledTexture and btn:GetDisabledTexture() then
        btn:GetDisabledTexture():SetTexture(nil)
    end

    local name = btn:GetName() or ""
    for _, suffix in ipairs({ "Left", "Right", "Middle" }) do
        local tex = _G[name .. suffix]
        if tex then tex:SetAlpha(0); tex:Hide() end
    end

    local fs = btn:GetFontString()
    if fs then
        fs:SetFont(GetFont(), 11, "OUTLINE")
        fs:SetTextColor(T.text[1], T.text[2], T.text[3])
    end

    local hoverBg = T.btnHoverBg
    local hoverBd = T.btnHoverBd

    local origEnter = btn:GetScript("OnEnter")
    local origLeave = btn:GetScript("OnLeave")

    btn:SetScript("OnEnter", function()
        if origEnter then origEnter() end
        this:SetBackdropColor(hoverBg[1], hoverBg[2], hoverBg[3], hoverBg[4])
        this:SetBackdropBorderColor(hoverBd[1], hoverBd[2], hoverBd[3], hoverBd[4])
    end)

    btn:SetScript("OnLeave", function()
        if origLeave then origLeave() end
        this:SetBackdropColor(bg[1], bg[2], bg[3], bg[4])
        this:SetBackdropBorderColor(bd[1], bd[2], bd[3], bd[4])
    end)
end

--------------------------------------------------------------------------------
-- Style all FontStrings on a frame with our themed font
--------------------------------------------------------------------------------
local function StyleFontStrings(frame, size, color)
    local regions = { frame:GetRegions() }
    local font = GetFont()
    for _, r in ipairs(regions) do
        if r:IsObjectType("FontString") then
            r:SetFont(font, size or 11, "OUTLINE")
            if color then
                r:SetTextColor(color[1], color[2], color[3])
            end
        end
    end
end

--------------------------------------------------------------------------------
-- Main skin application
--------------------------------------------------------------------------------
local function ApplySkin()
    if skinned then return end
    if not PetStableFrame then return end
    if SFramesDB.enablePetStable == false then return end
    skinned = true

    local frame = PetStableFrame
    local font = GetFont()

    -- 1) Remove Blizzard decorative textures from main frame
    NukeTextures(frame, { "Icon", "Food", "Diet", "Selected" })

    -- 2) Remove textures from sub-inset frames
    NukeChildTextures(frame)

    -- 3) Apply themed backdrop
    SetRoundBackdrop(frame)
    MarkBackdropRegions(frame)

    -- 4) Shadow for depth (tagged so auto-compact ignores it)
    local shadow = CreateShadow(frame)
    shadow.sfOverlay = true

    -- 5) Free drag support with position persistence
    frame:SetMovable(true)
    frame:EnableMouse(true)
    frame:SetClampedToScreen(true)
    frame:RegisterForDrag("LeftButton")
    frame:SetScript("OnDragStart", function()
        this:StartMoving()
    end)
    frame:SetScript("OnDragStop", function()
        this:StopMovingOrSizing()
        local point, _, relPoint, xOfs, yOfs = this:GetPoint()
        SFramesDB.petStablePos = {
            point = point, relPoint = relPoint,
            x = xOfs, y = yOfs,
        }
    end)

    -- 6) Title
    local titleFS = PetStableFrameTitleText
    if titleFS then
        titleFS:SetFont(font, 13, "OUTLINE")
        titleFS:SetTextColor(T.title[1], T.title[2], T.title[3])
        titleFS.sfKeep = true
    end

    -- 7) Close button
    if PetStableFrameCloseButton then
        StyleCloseButton(PetStableFrameCloseButton)
    end

    -- 8) Style pet info FontStrings (try various naming patterns)
    local infoFS = {
        "PetStablePetName", "PetStableSelectedPetName",
        "PetStablePetLevel", "PetStableSelectedPetLevel",
        "PetStablePetFamily", "PetStableSelectedPetFamily",
        "PetStablePetLoyalty", "PetStableSelectedPetLoyalty",
    }
    for _, n in ipairs(infoFS) do
        local fs = _G[n]
        if fs and fs.SetFont then
            fs:SetFont(font, 11, "OUTLINE")
            fs:SetTextColor(T.text[1], T.text[2], T.text[3])
        end
    end

    local labelFS = {
        "PetStableDietLabel", "PetStableTypeLabel",
        "PetStableNameLabel", "PetStableLevelLabel",
        "PetStableLoyaltyLabel", "PetStableFamilyLabel",
        "PetStableDietText",
    }
    for _, n in ipairs(labelFS) do
        local fs = _G[n]
        if fs and fs.SetFont then
            fs:SetFont(font, 10, "OUTLINE")
            fs:SetTextColor(T.dimText[1], T.dimText[2], T.dimText[3])
        end
    end

    -- Also style any remaining FontStrings on the main frame
    StyleFontStrings(frame, 11, T.text)

    -- 9) Current pet slot
    if PetStableCurrentPet then
        StyleSlot(PetStableCurrentPet)
    end

    -- 10) Stable slots (dynamic count for Turtle WoW, check up to 20)
    for i = 1, 20 do
        local slot = _G["PetStableStableSlot" .. i]
        if slot then
            StyleSlot(slot)
        end
    end
    -- Alternate naming pattern
    for i = 1, 20 do
        local slot = _G["PetStableSlot" .. i]
        if slot and not slot.sfSkinned then
            StyleSlot(slot)
        end
    end

    -- 11) Purchase button
    if PetStablePurchaseButton then
        StyleActionButton(PetStablePurchaseButton)
    end

    -- 12) Model frame background (tagged so auto-compact ignores it)
    if PetStableModel then
        local modelBg = CreateFrame("Frame", nil, frame)
        modelBg.sfOverlay = true
        modelBg:SetPoint("TOPLEFT", PetStableModel, "TOPLEFT", -3, 3)
        modelBg:SetPoint("BOTTOMRIGHT", PetStableModel, "BOTTOMRIGHT", 3, -3)
        modelBg:SetBackdrop({
            bgFile   = "Interface\\Tooltips\\UI-Tooltip-Background",
            edgeFile = "Interface\\Tooltips\\UI-Tooltip-Border",
            tile = true, tileSize = 16, edgeSize = 10,
            insets = { left = 2, right = 2, top = 2, bottom = 2 },
        })
        modelBg:SetBackdropColor(
            T.modelBg[1], T.modelBg[2], T.modelBg[3], T.modelBg[4] or 0.5)
        modelBg:SetBackdropBorderColor(
            T.modelBorder[1], T.modelBorder[2], T.modelBorder[3], T.modelBorder[4])
        modelBg:SetFrameLevel(math.max(0, PetStableModel:GetFrameLevel() - 1))
    end

    -- 13) Food/diet icons
    for i = 1, 10 do
        local food = _G["PetStableFood" .. i] or _G["PetStableDietIcon" .. i]
        if food and food.SetTexCoord then
            food:SetTexCoord(0.08, 0.92, 0.08, 0.92)
        end
    end

    -- 14) Any additional child frames that look like insets
    local insets = {
        "PetStableLeftInset", "PetStableBottomInset",
        "PetStableRightInset", "PetStableTopInset",
    }
    for _, iname in ipairs(insets) do
        local inset = _G[iname]
        if inset then
            NukeTextures(inset)
            if inset.SetBackdrop then inset:SetBackdrop(nil) end
        end
    end

    -- 14b) Cleanup: only target known decorative inset/background children
    local knownFrames = {}
    if PetStableModel then knownFrames[PetStableModel] = true end
    if PetStableFrameCloseButton then knownFrames[PetStableFrameCloseButton] = true end
    if PetStablePurchaseButton then knownFrames[PetStablePurchaseButton] = true end
    if PetStableCurrentPet then knownFrames[PetStableCurrentPet] = true end
    for si = 1, 20 do
        local ss = _G["PetStableStableSlot" .. si]
        if ss then knownFrames[ss] = true end
        local ps = _G["PetStableSlot" .. si]
        if ps then knownFrames[ps] = true end
    end
    local allCh = { frame:GetChildren() }
    for _, child in ipairs(allCh) do
        if not knownFrames[child] and not child.sfSkinned
           and not child.sfOverlay and not child.sfBorder then
            local cName = child:GetName() or ""
            if string.find(cName, "Inset") or string.find(cName, "Bg")
               or string.find(cName, "Border") or string.find(cName, "Tab") then
                NukeTextures(child)
                if child.SetBackdrop then child:SetBackdrop(nil) end
            end
        end
    end

end

--------------------------------------------------------------------------------
-- Restore saved position (runs every time the frame is shown)
--------------------------------------------------------------------------------
local function RestorePosition()
    if not PetStableFrame then return end
    if not SFramesDB.petStablePos then return end
    local pos = SFramesDB.petStablePos
    PetStableFrame:ClearAllPoints()
    PetStableFrame:SetPoint(pos.point, UIParent, pos.relPoint, pos.x, pos.y)
end

--------------------------------------------------------------------------------
-- Event-driven skin application + position restore
--------------------------------------------------------------------------------
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("PET_STABLE_SHOW")
eventFrame:SetScript("OnEvent", function()
    if event == "PET_STABLE_SHOW" then
        ApplySkin()
        RestorePosition()
    end
end)

if PetStableFrame then
    local origOnShow = PetStableFrame:GetScript("OnShow")
    PetStableFrame:SetScript("OnShow", function()
        if origOnShow then origOnShow() end
        ApplySkin()
        RestorePosition()
    end)
end
