local _, Ns = ...
local L = Ns.L

-- Delves/Prety tracker
local SECONDS_PER_WEEK = 604800
local US_RESET_EPOCH = 1736262000
local EU_RESET_EPOCH = 1736319600

local function GetWeekID()
	local region = GetCurrentRegion()
	local epoch = (region == 3) and EU_RESET_EPOCH or US_RESET_EPOCH
	return floor((GetServerTime() - epoch) / SECONDS_PER_WEEK)
end

function Ns.GetTrackerData()
	if not SinStatsDB.delveTracker then SinStatsDB.delveTracker = {} end
	local key = Ns.ProfileKey
	local weekID = GetWeekID()
	if not SinStatsDB.delveTracker[key] or SinStatsDB.delveTracker[key].weekID ~= weekID then
		SinStatsDB.delveTracker[key] = { weekID = weekID, runs = {}, countAll = 0, countTier8 = 0 }
	end
	return SinStatsDB.delveTracker[key]
end

function Ns.GetVaultTier1Bonus()
	local trackerData = Ns.GetTrackerData()
	local activities = C_WeeklyRewards.GetActivities(6)
	local vaultTotal = 0

	if activities then
		for i = 1, #activities do
			local p = activities[i].progress or 0
			if p > vaultTotal then
				vaultTotal = p
			end
		end
		if vaultTotal > 0 then
			trackerData.vaultTotal = vaultTotal
		end
	end

	if vaultTotal == 0 then
		vaultTotal = trackerData.vaultTotal or 0
	end

	local trackedCount = #trackerData.runs
	local bonus = vaultTotal - trackedCount
	return bonus > 0 and bonus or 0
end

local DELVES_WIDGET_ID = 6183

local cachedPreyQuestID

local PREY_WORDS_BY_LOCALE = {
	enUS = { "nightmare", "hard" },
	enGB = { "nightmare", "hard" },
	frFR = { "cauchemar", "difficile" },
	deDE = { "albtraum", "schwer" },
	esES = { "pesadilla", "dificil" },
	esMX = { "pesadilla", "dificil" },
	ptBR = { "pesadelo" },
	itIT = { "incubo" },
	ruRU = { "кошмар", "сложный" },
	koKR = { "악몽", "어려움" },
	zhCN = { "梦魇", "困难" },
	zhTW = { "夢魘", "困難" },
}

local localeWords = PREY_WORDS_BY_LOCALE[GetLocale()] or PREY_WORDS_BY_LOCALE.enUS

local function GetPreyTierFromTitle(questID)
	local title = C_QuestLog.GetTitleForQuestID(questID)
	if not title then return 1 end
	local lower = title:lower()
	if localeWords[1] and lower:find(localeWords[1], 1, true) then return 8 end
	if localeWords[2] and lower:find(localeWords[2], 1, true) then return 5 end
	return 1
end

local vaultHooked = false
local vaultShowHooked = false
local function TryHookGreatVault()
	if vaultHooked then return end
	local frame = WeeklyRewardsFrame
	if not frame then return end
	if not frame.Activities or #frame.Activities == 0 then
		if not vaultShowHooked then
			vaultShowHooked = true
			frame:HookScript("OnShow", TryHookGreatVault)
		end
		return
	end
	vaultHooked = true

	local function AddTrackerLines()
		local opts = Ns.Profile and Ns.Profile.Stats and Ns.Profile.Stats["DelvesPrey"]
		if not opts or not opts.Vault_Tooltip then return end
		local trackerData = Ns.GetTrackerData()
		local runs = trackerData.runs
		local vaultBonus = Ns.GetVaultTier1Bonus()
		if #runs == 0 and vaultBonus == 0 then return end

		local tiers = {}
		local maxTier = 0
		for i = 1, #runs do
			local run = runs[i]
			local tier = type(run) == "table" and run.tier or run
			tiers[tier] = (tiers[tier] or 0) + 1
			if tier > maxTier then maxTier = tier end
		end

		if vaultBonus > 0 then
			tiers[1] = (tiers[1] or 0) + vaultBonus
			if maxTier < 1 then maxTier = 1 end
		end

		GameTooltip:AddLine(" ")
		GameTooltip:AddLine("SinStats " .. (L["VT_Header"] or ": Weekly runs"))
		for tier = 1, maxTier do
			if tiers[tier] then
				GameTooltip:AddDoubleLine(Ns.Colors.Green .. (L["VT_Tier"] or "Tier") .. " " .. tier .. "|r", tiers[tier], 1, 1, 1)
			end
		end
		GameTooltip:Show()
	end

	for _, actFrame in ipairs(frame.Activities) do
		if actFrame.info and actFrame.info.type == 6 then -- Only world section (delves)
			actFrame:HookScript("OnEnter", AddTrackerLines)
		end
	end
end

local delveTrackerFrame = CreateFrame("Frame")

function Ns.OnVaultTooltipToggle(self, key, settings)
	if settings[key] and not vaultHooked then
		if C_AddOns.IsAddOnLoaded("Blizzard_WeeklyRewards") then
			TryHookGreatVault()
		else
			delveTrackerFrame:RegisterEvent("ADDON_LOADED")
		end
	end
end

delveTrackerFrame:RegisterEvent("SCENARIO_COMPLETED")
delveTrackerFrame:RegisterEvent("QUEST_ACCEPTED")
delveTrackerFrame:RegisterEvent("QUEST_TURNED_IN")
delveTrackerFrame:RegisterEvent("QUEST_REMOVED")
delveTrackerFrame:RegisterEvent("PLAYER_ENTERING_WORLD")
delveTrackerFrame:RegisterEvent("WEEKLY_REWARDS_UPDATE")
delveTrackerFrame:SetScript("OnEvent", function(self, event, ...)
	if event == "WEEKLY_REWARDS_UPDATE" then
		Ns.GetVaultTier1Bonus()
		return
	end

	if event == "PLAYER_ENTERING_WORLD" or event == "QUEST_ACCEPTED" then
		if C_QuestLog.GetActivePreyQuest then
			cachedPreyQuestID = C_QuestLog.GetActivePreyQuest()
		end
		if event == "PLAYER_ENTERING_WORLD" and not vaultHooked then
			local statOpts = Ns.Profile and Ns.Profile.Stats and Ns.Profile.Stats["DelvesPrey"]
			if statOpts and statOpts.Vault_Tooltip then
				if C_AddOns.IsAddOnLoaded("Blizzard_WeeklyRewards") then
					TryHookGreatVault()
				else
					self:RegisterEvent("ADDON_LOADED")
				end
			end
		end
		return
	end

	if event == "ADDON_LOADED" then
		local addonName = ...
		if addonName == "Blizzard_WeeklyRewards" then
			self:UnregisterEvent("ADDON_LOADED")
			local statOpts = Ns.Profile and Ns.Profile.Stats and Ns.Profile.Stats["DelvesPrey"]
			if statOpts and statOpts.Vault_Tooltip then
				C_Timer.After(0, TryHookGreatVault)
			end
		end
		return
	end

	if event == "QUEST_TURNED_IN" then
		local questID = ...
		if cachedPreyQuestID and cachedPreyQuestID == questID then
			local title = C_QuestLog.GetTitleForQuestID(questID) or "Prey"
			local tier = GetPreyTierFromTitle(questID)
			local data = Ns.GetTrackerData()
			tinsert(data.runs, { name = title, tier = tier, source = "prey" })
			data.countAll = (data.countAll or 0) + 1
			if tier >= 8 then data.countTier8 = (data.countTier8 or 0) + 1 end
			cachedPreyQuestID = nil
		end
		return
	end

	if event == "QUEST_REMOVED" then
		local questID = ...
		if cachedPreyQuestID and cachedPreyQuestID == questID then
			cachedPreyQuestID = nil
		end
		return
	end

	if event == "SCENARIO_COMPLETED" then
		local widgetInfo = C_UIWidgetManager.GetScenarioHeaderDelvesWidgetVisualizationInfo(DELVES_WIDGET_ID)
		if not widgetInfo or not widgetInfo.tierText then return end
		local tier = tonumber(widgetInfo.tierText)
		if not tier or tier < 1 then return end
		local name = widgetInfo.headerText or "Delve"
		local data = Ns.GetTrackerData()
		tinsert(data.runs, { name = name, tier = tier, source = "delve" })
		data.countAll = (data.countAll or 0) + 1
		if tier >= 8 then data.countTier8 = (data.countTier8 or 0) + 1 end
	end
end)