local p = {}
local lang = mw.language.getContentLanguage()

local currentTitle = mw.title.getCurrentTitle()
local currentFullText = currentTitle.fullText

local isANPage = mw.ustring.match(
	currentFullText,
	"^Wikipedia:Tin nhắn cho bảo quản viên/"
) ~= nil

-- Initialize

local domains = {}
local domainLookup = {}

if not isANPage then
	local title = mw.title.new('MediaWiki:BlockedExternalDomains.json')
	local content = title:getContent() -- expensive call
	local data = mw.text.jsonDecode(content)

	for _, entry in ipairs(data) do
		table.insert(domains, entry.domain)
	end

	for _, domain in ipairs(domains) do
		domainLookup[domain] = true
	end
end

-- Main

local function isAdded(hostname)
	return domainLookup[hostname] == true
end

local function statsText(hostnames, feedbacks)
	local stats = { good = 0, bad = 0, added = 0 }
	
	for _, hostname in ipairs(hostnames) do
		for _, feedback in ipairs(feedbacks) do
			if feedback.hostname == hostname.hostname then
				if feedback.status == 0 then
					stats.good = stats.good + 1
				else
					stats.bad = stats.bad + 1
				end
			end
		end

		if isAdded(hostname.hostname) then
			stats.added = stats.added + 1
		end
	end
	
	local texts = {}
	
	for key, value in pairs(stats) do
		if value ~= 0 then
			table.insert(texts, tostring(
				mw.html.create("span")
					:addClass("citron-spam-" .. key .. "-count")
					:wikitext(value)	
			))
		end
	end
	
	return table.concat(texts, " · ")
end

local function createHostnameListNode(title, node, hostnames, revisions, reportDate, id, feedbacks)
	if #hostnames == 0 then
		return nil
	end
	
	node
		:node(
			mw.html.create("div")
				:addClass("citron-spam-content-title-placeholder mw-collapsible"
					.. (id:find("uncertain") and " mw-collapsed" or ""))
				:css("position", "absolute")
				:attr("id", "mw-customcollapsible-" .. id)
		)
		:node(
			mw.html.create("div")
				:addClass("citron-spam-content-title-wrapper mw-customtoggle-" .. id)
				:node(
					mw.html.create("div")
						:addClass("citron-spam-content-title")
						:wikitext(title .. " (" .. #hostnames .. ")")
				)
				:node(
					mw.html.create("div")
						:addClass("citron-spam-content-feedback-stats")
						:wikitext(statsText(hostnames, feedbacks))
				)
		)

	for _, hostname in ipairs(hostnames) do
		-- .citron-spam-hostname-inner-bottom
		local hostnameInnerBottomNode = mw.html.create("div")
			:addClass("citron-spam-hostname-inner-bottom mw-collapsible mw-collapsed")
			:attr("id", "mw-customcollapsible-citron-" .. reportDate)

		for _, revisionId in ipairs(hostname.revisionIds) do
			local revision = revisions[revisionId]
		    hostnameInnerBottomNode
		    	:node(
		    		mw.html.create("div")
		    			:addClass("citron-spam-revision")
		    			:wikitext(
		    				"[[Special:Contributions/"
			    				.. revision.user
			    				.. "|"
			    				.. revision.user
			    				.. "]] ([[Special:Diff/"
			    				.. revisionId
			    				.. "|"
			    				.. revision.page
			    				.. "]])"
		    			)
		    	)
		end
		
		-- .citron-spam-feedbacks
		local feedbacksNode = mw.html.create("div")
			:addClass("citron-spam-feedbacks")
		local feedbacksCount = 0

		for _, feedback in ipairs(feedbacks) do
			if feedback.hostname == hostname.hostname then
				feedbacksCount = feedbacksCount + 1
				feedbacksNode:node(
					mw.html.create("div")
						:addClass("citron-spam-feedback "
							.. (feedback.status == 0
								and "citron-spam-feedback-good" 
								or "citron-spam-feedback-bad"))
						:attr("title", feedback.createdAt)
						:node(mw.html.create("span")
							:addClass("citron-spam-feedback-icon"))
						:node(mw.html.create("span")
							:addClass("citron-spam-feedback-user")
							:wikitext(feedback.user))
				)
			end
		end

		local statusClass, bgHostnameInnerTopLeftStart, bgHostnameInnerTopLeftEnd
		if hostname.score >= 0.8 then
		    statusClass = "citron-spam-very-bad"
		    bgHostnameInnerTopLeftStart = "var(--background-color-destructive-subtle--hover, #ffdad3)"
		    bgHostnameInnerTopLeftEnd = "var(--background-color-destructive-subtle, #ffe9e5)"
		elseif hostname.score >= 0.5 then
		    statusClass = "citron-spam-bad"
		    bgHostnameInnerTopLeftStart = "light-dark(#ffdcb8, #572c19)"
		    bgHostnameInnerTopLeftEnd = "light-dark(#ffead4, #361d13)"
		else
		    statusClass = "citron-spam-uncertain"
		    bgHostnameInnerTopLeftStart = "var(--background-color-progressive-subtle--hover, #dce3f9)"
		    bgHostnameInnerTopLeftEnd = "var(--background-color-progressive-subtle, #f1f4fd)"
		end

		local added = isAdded(hostname.hostname)
		local addedClass = added and "citron-spam-added" or "citron-spam-not-added"
		local addedText = added and "Đã thêm" or "Chưa thêm"

		local score = string.format("%.0f%%", hostname.score * 100)

    	node
    		:node(
    			mw.html.create("div")
    				:addClass("citron-spam-hostname mw-collapsible"
    					.. (id:find("uncertain") and " mw-collapsed" or ""))
    				:attr("id", "mw-customcollapsible-" .. id)
    				:node(
    					mw.html.create("div")
    						:addClass("citron-spam-hostname-time")
    						:wikitext(hostname.time)
    				)
    				:node(
    					mw.html.create("div")
    						:addClass("citron-spam-hostname-inner")
    						:attr("data-added", tostring(added))
    						:node(
    							mw.html.create("div")
    								:addClass("citron-spam-hostname-inner-top")
									:css("--percentage", score)
									:css("--background-hostname-inner-top-left-start", bgHostnameInnerTopLeftStart)
									:css("--background-hostname-inner-top-left-end", bgHostnameInnerTopLeftEnd)
									:css("--background-hostname-inner-top-left",
										"linear-gradient(to right, var(--background-hostname-inner-top-left-start) var(--percentage), var(--background-hostname-inner-top-left-end) var(--percentage))")
    								:node(
    									mw.html.create("div")
    										:addClass("citron-spam-hostname-inner-top-left "
    											.. statusClass)
    										:node(
    											mw.html.create("div")
    												:addClass("citron-spam-hostname-hostname")
    												:wikitext(hostname.hostname)
    										)
    										:node(
    											mw.html.create("div")
    												:addClass("citron-spam-hostname-score")
		    										:wikitext(score)
    										)
    								)
    								:node(
    									mw.html.create("div")
    										:addClass("citron-spam-hostname-inner-top-right")
    										:node(feedbacksCount ~= 0 
    											and feedbacksNode
    											or nil)
    										:node(
    											mw.html.create("div")
    												:addClass("citron-spam-hostname-status "
    													.. addedClass)
		    										:wikitext(addedText)
    										)
    								)
    						)
    						:node(hostnameInnerBottomNode)
    				)
    		)
	end
	
	return node
end

local function createReport(date)
	local today = os.date("%Y-%m-%d") == date;
    local title = mw.title.new("Project:Citron/Spam/" .. date .. ".json")
    local content = title:getContent()

    local wrapperNode = mw.html.create("div")
        :addClass("citron-spam-wrapper")
        :node(
        	mw.html.create("div")
        		:addClass("citron-spam-header")
        		:node(
        			mw.html.create("div")
        				:addClass("citron-spam-title")
        				:wikitext("[[Project:Citron/Spam|Citron · Spam]]")
        		)
        		:node(
					mw.html.create("div")
						:addClass("citron-spam-actions")
						:node(
							mw.html.create("span")
								:addClass("mw-customtoggle-citron-" .. date)
								:wikitext("Xem phiên bản")
						)
						:node(
							today
							and mw.html.create("span")
									:addClass("citron-spam-support")
									:attr("data-date", date)
									:wikitext("Hỗ trợ đánh giá")
							or nil
						)
						:node(
		        			mw.html.create("span")
		        				:addClass("citron-spam-date")
		        				:wikitext(
		        					"[[Project:Citron/Spam/"
			        					.. date
			        					.. ".json|"
			        					.. date
			        					.. "]]"
		        				)
		        		)
				)
        )

    if content == nil then
    	wrapperNode:node(
    		mw.html.create("div")
    			:addClass("citron-spam-empty")
    			:wikitext("Không có báo cáo tại thời điểm được cung cấp")
    	)

		return tostring(wrapperNode)
    end

    local data = mw.text.jsonDecode(content)
    local very_bad_hostnames = {}
	local bad_hostnames = {}
	local uncertain_hostnames = {}

	for _, hostname in ipairs(data.hostnames) do
	    if hostname.score >= 0.8 then
	        table.insert(very_bad_hostnames, hostname)
	    elseif hostname.score >= 0.5 then
	        table.insert(bad_hostnames, hostname)
	    else
	        table.insert(uncertain_hostnames, hostname)
	    end
	end

	local contentVeryBadNode = createHostnameListNode(
		"Có khả năng rất cao là xấu",
		mw.html.create("div"):addClass("citron-spam-content"),
		very_bad_hostnames,
		data.revisions,
		date,
		"citron-" .. date .. "-very-bad",
		data.feedbacks
	)
	local contentBadNode = createHostnameListNode(
		"Có khả năng cao là xấu",
		mw.html.create("div"):addClass("citron-spam-content"),
		bad_hostnames,
		data.revisions,
		date,
		"citron-" .. date .. "-bad",
		data.feedbacks
	)
	local contentUncertainNode = createHostnameListNode(
		"Chưa chắc chắn",
		mw.html.create("div"):addClass("citron-spam-content"),
		uncertain_hostnames,
		data.revisions,
		date,
		"citron-" .. date .. "-uncertain",
		data.feedbacks
	)

	if #data.hostnames > 0 then
		wrapperNode:node(contentVeryBadNode)
		wrapperNode:node(contentBadNode)
		wrapperNode:node(contentUncertainNode)
	else
    	wrapperNode:node(
    		mw.html.create("div")
    			:addClass("citron-spam-empty")
    			:wikitext("Chưa có dữ liệu")
    	)
	end

	wrapperNode
		:node(
			mw.html.create("div")
				:addClass("citron-spam-footer")
				:node(
					mw.html.create("div")
						:addClass("citron-spam-last-update")
						:wikitext(
							"Cập nhật lúc "
							.. lang:formatDate("H:i, j F, Y", data.updatedAt)
							.. " (UTC). Truy cập [[Special:BlockedExternalDomains|Tên miền bị chặn]]. "
							.. tostring(
								mw.html.create("span")
									:addClass("citron-spam-info")
									:wikitext("[[:vi:User:Plantaest/Citron|ⓘ]]")
							)
						)
				)
				:node(
					mw.html.create("div")
						:addClass("citron-spam-status")
						:attr("data-today", tostring(today))
						:wikitext(today and "Đang cập nhật" or "Kết thúc cập nhật")
				)
		)

    return tostring(wrapperNode)
end

local function createTemplatestylesNode()
    return mw.getCurrentFrame():extensionTag{
		name = "templatestyles", args = { src = "Module:Citron/Spam/styles.css" }
	}
end

function p.report(frame)
	if isANPage then
		local date = frame.args["date"]
			or lang:formatDate("Y-m-d")

		return string.format(
			"Xem báo cáo tại: [[Wikipedia:Citron/Spam/%s.json]].",
			date
		)
	end

	local date = frame.args["date"]
	return createTemplatestylesNode() .. createReport(date)
end

function p.main(frame)
	local dates = {}
	local reports = {}

	for i = 0, 6 do
		table.insert(
			dates,
			lang:formatDate("Y-m-d", "-" .. i .. " days")
		)
	end
	
	for _, date in ipairs(dates) do
		table.insert(reports, createReport(date))
	end

	return createTemplatestylesNode() .. table.concat(reports, "\n")
end

return p