-- Portal Pro :: UI/Tab_Stats.lua
-- Net rather than gross, everywhere. Gross is flattering; net is the number that tells
-- you whether the evening was worth it.

local ADDON_NAME, PP = ...
local UI, T, U = PP.UI, PP.Theme, PP.U
local L = PP.L

local function build(parent)
	local frame = CreateFrame("Frame", nil, parent)
	frame.window = "session"

	local bar = CreateFrame("Frame", nil, frame)
	bar:SetPoint("TOPLEFT", T.space.lg, -T.space.lg)
	bar:SetPoint("TOPRIGHT", -T.space.lg, -T.space.lg)
	bar:SetHeight(T.size.buttonHeight)

	local heading = UI:Text(bar, L["Stats"], T.fontSize.lg, "", "textPrimary")
	heading:SetPoint("LEFT")

	local segmented = UI:Segmented(bar, {
		{ value = "session", label = L["Session"] },
		{ value = "today",   label = L["Today"] },
		{ value = "week",    label = L["This week"] },
		{ value = "all",     label = L["All time"] },
	}, "session", function(value)
		frame.window = value
		frame.__def.refresh(frame)
	end)
	segmented:SetPoint("RIGHT")
	segmented:SetWidth(300)

	-- Tile row
	local tiles = {}
	local specs = {
		{ key = "net",     label = L["Net"] },
		{ key = "gph",     label = L["Gold / hour"] },
		{ key = "portals", label = L["Portals"] },
		-- The funnel is session-scoped regardless of the window selector, so it says so
		-- in the label rather than repeating "session:" inside the sub-line.
		{ key = "conv",    label = L["Conversion"] .. " (session)" },
	}
	local prev
	for i, spec in ipairs(specs) do
		local tile = UI:StatTile(frame, spec.label, "-")
		tile:SetHeight(96)
		if prev then
			tile:SetPoint("TOPLEFT", prev, "TOPRIGHT", T.space.md, 0)
		else
			tile:SetPoint("TOPLEFT", bar, "BOTTOMLEFT", 0, -T.space.md)
		end
		tiles[spec.key] = tile
		prev = tile
	end
	frame.tiles = tiles

	-- Equal-width tiles that track the frame.
	frame:SetScript("OnSizeChanged", function(self)
		local available = self:GetWidth() - T.space.lg * 2 - T.space.md * 3
		local width = available / 4
		for _, tile in pairs(tiles) do tile:SetWidth(width) end
	end)

	-- Chart
	local chartLabel = UI:Label(frame, L["Last 7 days"])
	chartLabel:SetPoint("TOPLEFT", tiles.net, "BOTTOMLEFT", 0, -T.space.lg)

	local chart = UI:BarChart(frame, {
		valueFormat = function(copper) return U.MoneyPlain(copper) end,
		labelFormat = function(item)
			return date("%a", time({
				year = tonumber(item.key:sub(1, 4)),
				month = tonumber(item.key:sub(6, 7)),
				day = tonumber(item.key:sub(9, 10)),
				hour = 12,
			}))
		end,
	})
	chart:SetPoint("TOPLEFT", chartLabel, "BOTTOMLEFT", 0, -T.space.sm)
	chart:SetPoint("RIGHT", frame, "RIGHT", -T.space.lg, 0)
	chart:SetHeight(140)
	frame.chart = chart

	-- Breakdown + top customers, side by side
	local destLabel = UI:Label(frame, L["By destination"])
	destLabel:SetPoint("TOPLEFT", chart, "BOTTOMLEFT", 0, -T.space.lg)

	local breakdown = UI:BreakdownList(frame, {
		valueFormat = function(copper) return U.MoneyFull(copper) end,
	})
	breakdown:SetPoint("TOPLEFT", destLabel, "BOTTOMLEFT", 0, -T.space.sm)
	breakdown:SetWidth(320)
	frame.breakdown = breakdown

	local topLabel = UI:Label(frame, L["Top customers"])
	topLabel:SetPoint("TOPLEFT", destLabel, "TOPLEFT", 360, 0)

	local topList = UI:BreakdownList(frame, {
		valueFormat = function(copper) return U.MoneyFull(copper) end,
	})
	topList:SetPoint("TOPLEFT", topLabel, "BOTTOMLEFT", 0, -T.space.sm)
	topList:SetWidth(300)
	frame.topList = topList

	return frame
end

local function refresh(frame)
	local window = frame.window
	local totals, since = PP.Stats:Totals(window)

	-- Tiles
	frame.tiles.net:SetValue(U.MoneyFull(totals.net, true), totals.net >= 0 and "positive" or "negative")
	frame.tiles.net:SetSub(("%s gross · %s refunded"):format(
		U.MoneyFull(totals.gross), U.MoneyFull(totals.refunds)))

	local gph = PP.Stats:GoldPerHour(window)
	frame.tiles.gph:SetValue(gph > 0 and U.MoneyFull(gph) or "-", "gold")
	frame.tiles.gph:SetSub(window == "session"
		and ("%s active"):format(U.Duration(PP.Stats:ActiveSeconds()))
		or "")

	local portals, teleports = PP.CastTracker:CountSince(since)
	frame.tiles.portals:SetValue(tostring(portals + teleports))
	frame.tiles.portals:SetSub(("%d portals · %d teleports"):format(portals, teleports))

	local funnel = PP.Stats:Funnel()
	local rate = PP.Stats:ConversionRate()
	frame.tiles.conv:SetValue(("%d%%"):format(U.Round(rate * 100)))
	frame.tiles.conv:SetSub(("%d leads / %d inv / %d paid"):format(
		funnel.leads, funnel.invites, funnel.paid))

	-- Chart
	frame.chart:SetData(PP.Ledger:DailySeries(7))

	-- Destination breakdown
	local byDest = PP.Ledger:ByDestination(since)
	local destRows = {}
	for _, dest in ipairs(PP.Dest.list) do
		local value = byDest[dest.key]
		if value and value ~= 0 then
			destRows[#destRows + 1] = {
				label = dest.name,
				value = value,
				icon = PP.Dest:Icon(dest),
			}
		end
	end
	U.SortBy(destRows, function(r) return r.value end, true)
	frame.breakdown:SetData(destRows)

	-- Top customers
	local customers = PP.Ledger:TopCustomers(8)
	local customerRows = {}
	for _, c in ipairs(customers) do
		customerRows[#customerRows + 1] = {
			label = c.vip and ("|cff" .. T.hex.gold .. c.name .. "|r") or c.name,
			value = c.total,
		}
	end
	frame.topList:SetData(customerRows)
end

UI:RegisterTab({
	key = "stats",
	label = L["Stats"],
	icon = "Interface\\ICONS\\INV_Misc_Book_09",
	order = 5,
	build = build,
	refresh = refresh,
})
