-- Archivo: QuestNpc-Icon.lua

-- Definir los IDs de los NPCs que tienen misiones personalizadas
local questNPCs = {
    [8583] = true,  -- Dirania Brillargente (ejemplo)
    -- Añade más NPCs aquí si es necesario
}

-- Crear tablas para almacenar los frames de iconos y modelos de cada NPC
local npcIconFrames = {}
local npcModelFrames = {}

-- Ruta del icono personalizado
local ICON_PATH = "Interface\\AddOns\\AI_VoiceOver\\Textures\\Quest_Danger_Ico.tga"  -- Ruta relativa

-- Función para obtener el ID del NPC
local function GetNPCID(unit)
    local guid = UnitGUID(unit)
    if guid then
        local _, _, _, _, _, npcID = strsplit("-", guid)
        return tonumber(npcID)
    end
    return nil
end

-- Función para verificar si una unidad es un NPC amistoso
local function IsFriendlyNPC(unit)
    return not UnitIsPlayer(unit) and UnitIsFriend("player", unit)
end

-- Función para crear o actualizar el icono y el modelo sobre el NPC
local function UpdateNPCIcon(namePlate)
    local unitFrame = namePlate.UnitFrame
    if not unitFrame then return end
    
    local unit = unitFrame.unit
    if not unit then return end

    local npcID = GetNPCID(unit)
    if not npcID or not questNPCs[npcID] or not IsFriendlyNPC(unit) then
        if npcIconFrames[unit] then
            npcIconFrames[unit]:Hide()
            npcIconFrames[unit] = nil
        end
        if npcModelFrames[unit] then
            npcModelFrames[unit]:Hide()
            npcModelFrames[unit] = nil
        end
        return
    end

    if not npcIconFrames[unit] then
        -- Frame para el icono
        local iconFrame = CreateFrame("Frame", nil, namePlate)
        iconFrame:SetSize(64, 64)  -- Tamaño del icono

        -- Crear el icono
        local icon = iconFrame:CreateTexture(nil, "OVERLAY")
        icon:SetAllPoints(iconFrame)
        icon:SetTexture(ICON_PATH)
        icon:SetDrawLayer("ARTWORK", 1)

        -- Agregar glow al icono usando LibCustomGlow
        if LibCustomGlow then
            LibCustomGlow.PixelGlow_Start(iconFrame, {1, 1, 0, 1}, 8, 0.25, 2, 2, 2, 2, false, nil, "glow")  -- Glow amarillo
        end

        npcIconFrames[unit] = iconFrame
    end

    if not npcModelFrames[unit] then
        -- Crear el frame para contener el modelo
        local modelFrame = CreateFrame("Frame", nil, namePlate)
        modelFrame:SetSize(72, 72)  -- Tamaño del frame para el modelo

        -- Crear el modelo dentro del frame
        local model = CreateFrame("PlayerModel", nil, modelFrame)
        model:SetSize(72, 72)  -- Tamaño del frame del modelo
        model:SetPoint("CENTER", modelFrame, "CENTER", 0, 0)  -- Centrar el modelo en el frame
        model:SetModel(937418)  -- ID del modelo a usar

        -- Habilitar control de cámara personalizado
        model:SetCustomCamera(1)

        -- Ajustar la distancia de la cámara
        model:SetCamDistanceScale(1.5)  -- Escala de la distancia de la cámara (1.5 aleja la cámara)

        -- Ajustar la orientación del modelo
        model:SetFacing(math.rad(-50))  -- Rotar el modelo 50 grados en sentido negativo (en radianes)

        -- Asignar una animación
        model:SetAnimation(0)  -- Animación por defecto

        -- Controlar la capa y nivel del modelo
        model:SetFrameStrata("BACKGROUND")  -- Poner el modelo detrás del resto
        model:SetFrameLevel(1)

        -- Guardar el frame del modelo para futuras referencias
        npcModelFrames[unit] = modelFrame
    end

    local iconFrame = npcIconFrames[unit]
    local modelFrame = npcModelFrames[unit]

    iconFrame:SetParent(namePlate)
    iconFrame:SetPoint("BOTTOM", namePlate, "TOP", 0, 8)
    iconFrame:SetFrameStrata("HIGH")
    iconFrame:Show()

    modelFrame:SetParent(namePlate)
    modelFrame:SetPoint("BOTTOM", namePlate, "TOP", 0, 8)
    modelFrame:SetFrameStrata("MEDIUM")
    modelFrame:Show()
end

-- Frame para gestionar los eventos
local eventFrame = CreateFrame("Frame")
eventFrame:RegisterEvent("NAME_PLATE_UNIT_ADDED")
eventFrame:RegisterEvent("NAME_PLATE_UNIT_REMOVED")
eventFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
eventFrame:RegisterEvent("ZONE_CHANGED_NEW_AREA")

eventFrame:SetScript("OnEvent", function(self, event, ...)
    if event == "NAME_PLATE_UNIT_ADDED" then
        local unit = ...
        local namePlate = C_NamePlate.GetNamePlateForUnit(unit)
        if namePlate then
            UpdateNPCIcon(namePlate)
        end
    elseif event == "NAME_PLATE_UNIT_REMOVED" then
        local unit = ...
        if npcIconFrames[unit] then
            npcIconFrames[unit]:Hide()
            npcIconFrames[unit] = nil
        end
        if npcModelFrames[unit] then
            npcModelFrames[unit]:Hide()
            npcModelFrames[unit] = nil
        end
    elseif event == "PLAYER_ENTERING_WORLD" or event == "ZONE_CHANGED_NEW_AREA" then
        -- Limpiar todos los iconos y modelos existentes
        for unit, frame in pairs(npcIconFrames) do
            frame:Hide()
            npcIconFrames[unit] = nil
        end
        for unit, frame in pairs(npcModelFrames) do
            frame:Hide()
            npcModelFrames[unit] = nil
        end
        -- Actualizar para todas las placas de nombre visibles
        for _, namePlate in pairs(C_NamePlate.GetNamePlates()) do
            UpdateNPCIcon(namePlate)
        end
    end
end)

-- Variables para la animación suave
local animationSpeed = 2 -- Velocidad de la animación (ajusta según sea necesario)
local maxOffset = 5 -- Amplitud máxima de la animación (ajusta según sea necesario)

-- Función para actualizar la posición de los iconos y modelos con animación suave
local function UpdatePositions()
    local time = GetTime() * animationSpeed
    local offset = math.sin(time) * maxOffset
    
    for unit, iconFrame in pairs(npcIconFrames) do
        local namePlate = C_NamePlate.GetNamePlateForUnit(unit)
        if namePlate then
            iconFrame:SetParent(namePlate)
            iconFrame:SetPoint("BOTTOM", namePlate, "TOP", 0, 8 + offset)
            
            -- Actualizar también la posición del modelo si existe
            if npcModelFrames[unit] then
                npcModelFrames[unit]:SetParent(namePlate)
                npcModelFrames[unit]:SetPoint("BOTTOM", namePlate, "TOP", 0, 8 + offset)
            end
        else
            iconFrame:Hide()
            npcIconFrames[unit] = nil
            if npcModelFrames[unit] then
                npcModelFrames[unit]:Hide()
                npcModelFrames[unit] = nil
            end
        end
    end
end

-- Usar C_Timer.NewTicker con un intervalo más corto para una animación más suave
local updateInterval = 0.016 -- Aproximadamente 60 FPS

-- Optimización: Limitar las actualizaciones cuando la interfaz está oculta
local function OnEvent(self, event)
    if event == "PLAYER_ENTERING_WORLD" then
        self:UnregisterEvent("PLAYER_ENTERING_WORLD")
        self:RegisterEvent("PLAYER_LEAVING_WORLD")
        C_Timer.NewTicker(updateInterval, UpdatePositions)
    elseif event == "PLAYER_LEAVING_WORLD" then
        self:UnregisterEvent("PLAYER_LEAVING_WORLD")
        self:RegisterEvent("PLAYER_ENTERING_WORLD")
        -- Detener el ticker aquí si es necesario
    end
end

local optimizationFrame = CreateFrame("Frame")
optimizationFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
optimizationFrame:SetScript("OnEvent", OnEvent)