local PT = AhUI
if not PT then return end

PT.SkinningCheck = PT.SkinningCheck or {}
local SC = PT.SkinningCheck
local L  = PT.L

local function GetSkinningDisabledDB()
    PT.config.skinningDisabledTargets =
        PT.config.skinningDisabledTargets or {}
    return PT.config.skinningDisabledTargets
end

if AhUI_CharConfig and AhUI_CharConfig.skinningDisabledTargets then
    PT.config.skinningDisabledTargets =
        PT.config.skinningDisabledTargets or AhUI_CharConfig.skinningDisabledTargets
    AhUI_CharConfig.skinningDisabledTargets = nil
end

SC.PROFESSION_ID = 2882
SC.SKINNING_SPELL_ID = 8613

SC.TARGETS = {
    {
        id = "cobra_skin",
        questId = 74235,
        itemId = 205413,
        guide = {
            lureItem = 193906,
            craftFrom = 197741,
            zone = {
                map = 2133,
                x = 0.4400,
                y = 0.4780,
                text = "zone_zaralek",
            },
            npc = {
                name = "npc_magma_cobra",
                spawn = "spawn_zaralek_cobra",
                minLevel = 60,
            },
        },
    },
    {
        id = "slatefang",
        questId = 84259,
        itemId = 219013,
        guide = {
            lureItem = 219008,
            craftFrom = 222739,
            zone = {
                map = 2214,
                x = 0.5704,
                y = 0.4715,
                text = "zone_zaralek",
            },
            npc = {
                name = "npc_slatefang",
                spawn = "spawn_ringed_wastes",
                minLevel = 71,
            },
        },
    },
}

function SC:GetTargetName(target)
    return target and L[target.id] or L["Unknown"]
end

SC.pendingWaypoint = nil

function SC:SetPendingWaypoint(item)
    if not item or not item.guide or not item.guide.zone then return end
    self.pendingWaypoint = item
end

if not SC._waypointTicker then
    SC._waypointTicker = C_Timer.NewTicker(0.2, function()
        SC:ProcessPendingWaypoint()
    end)
end

function SC:ProcessPendingWaypoint()
    local t = self.pendingWaypoint
    if not t then return end

    local zone = t.guide and t.guide.zone
    if not zone or not zone.map or not zone.x or not zone.y then return end

    if TomTom then
        TomTom:AddWaypoint(zone.map, zone.x, zone.y, {
            title = self:GetTargetName(t),
            persistent = false,
        })
        self.pendingWaypoint = nil
        return
    end

    if not C_Map.CanSetUserWaypointOnMap(zone.map) then
        return
    end

    C_Map.ClearUserWaypoint()

    local point = UiMapPoint.CreateFromCoordinates(zone.map, zone.x, zone.y)
    C_Map.SetUserWaypoint(point)

    if C_SuperTrack then
        C_SuperTrack.SetSuperTrackedUserWaypoint(true)
    end

    self.pendingWaypoint = nil
end

function SC:GetGuideTooltip(target)
    if not target or not target.guide then return nil end
    local g = target.guide
    local lines = {}

    if g.lureItem then
        table.insert(lines, ("• %s: %s"):format(
            L["SKINNING_LURE"],
            C_Item.GetItemNameByID(g.lureItem) or L["Unknown"]
        ))
    end

    if g.craftFrom then
        table.insert(lines, ("• %s: %s"):format(
            L["SKINNING_CRAFT_FROM"],
            C_Item.GetItemNameByID(g.craftFrom) or L["Unknown"]
        ))
    end

    if g.zone then
        table.insert(lines, ("• %s: %s"):format(
            L["SKINNING_LOCATION"],
            L[g.zone.text]
        ))
    end

    if g.npc then
        table.insert(lines, ("• %s: %s (%s, %s+)"):format(
            L["SKINNING_TARGET"],
            L[g.npc.name],
            L[g.npc.spawn],
            g.npc.minLevel or "?"
        ))
    end

    return table.concat(lines, "\n")
end

function SC:IsSkinningLearned()
    return IsPlayerSpell(self.SKINNING_SPELL_ID)
end

function SC:IsAvailable()
    return self:IsSkinningLearned()
end

function SC:IsTargetEnabled(target)
    local db = GetSkinningDisabledDB()
    return not db[target.id]
end

function SC:IsTargetCompleted(target)
    if not target or not target.questId then return false end
    return C_QuestLog.IsQuestFlaggedCompleted(target.questId)
end

function SC:HasMissingItems()
    if not self:IsAvailable() then return false end

    for _, target in ipairs(self.TARGETS) do
        if self:IsTargetEnabled(target)
           and not self:IsTargetCompleted(target)
        then
            return true
        end
    end

    return false
end

function SC:GetMissingItems()
    local result = {}

    if not self:IsAvailable() then
        return result
    end

    for _, target in ipairs(self.TARGETS) do
        if self:IsTargetEnabled(target)
           and not self:IsTargetCompleted(target)
        then
            if not target.icon and target.itemId then
                target.icon = C_Item.GetItemIconByID(target.itemId)
            end
            table.insert(result, target)
        end
    end

    return result
end

function SC:GetIconTooltip()
    if not self:IsAvailable() then
        return L["SKINNING_NOT_LEARNED"]
    end

    local missing = self:GetMissingItems()
    if #missing == 0 then
        return L["SKINNING_ALL_DONE"]
    end

    local lines = { L["SKINNING_AVAILABLE"] }
    for _, t in ipairs(missing) do
        table.insert(lines, "• " .. self:GetTargetName(t))
    end

    return table.concat(lines, "\n")
end
