local MER, F, E, I, V, P, G, L = unpack(ElvUI_MerathilisUI)
local module = MER:GetModule("MER_Skins")
local S = E:GetModule("Skins")

local _G = _G
local pairs, unpack = pairs, unpack

local hooksecurefunc = hooksecurefunc

local Type_StatusBar = _G.Enum.UIWidgetVisualizationType.StatusBar
local Type_CaptureBar = _G.Enum.UIWidgetVisualizationType.CaptureBar
local Type_SpellDisplay = _G.Enum.UIWidgetVisualizationType.SpellDisplay
local Type_ItemDisplay = _G.Enum.UIWidgetVisualizationType.ItemDisplay
local Type_DoubleStatusBar = _G.Enum.UIWidgetVisualizationType.DoubleStatusBar

local atlasColors = {
	["UI-Frame-Bar-Fill-Blue"] = { 0.2, 0.6, 1 },
	["UI-Frame-Bar-Fill-Red"] = { 0.9, 0.2, 0.2 },
	["UI-Frame-Bar-Fill-Yellow"] = { 1, 0.6, 0 },
	["objectivewidget-bar-fill-left"] = { 0.2, 0.6, 1 },
	["objectivewidget-bar-fill-right"] = { 0.9, 0.2, 0.2 },
	["EmberCourtScenario-Tracker-barfill"] = { 0.9, 0.2, 0.2 },
}

local function ReplaceWidgetBarTexture(self, atlas)
	if self:IsForbidden() then
		return
	end

	if atlasColors[atlas] then
		self:SetStatusBarTexture(E.media.normTex)
		self:SetStatusBarColor(unpack(atlasColors[atlas]))
	end
end

local function ReskinWidgetStatusBar(bar)
	if not bar or bar:IsForbidden() then
		return
	end

	if bar and not bar.styled then
		if bar.BG then
			bar.BG:SetAlpha(0)
		end
		if bar.BGLeft then
			bar.BGLeft:SetAlpha(0)
		end
		if bar.BGRight then
			bar.BGRight:SetAlpha(0)
		end
		if bar.BGCenter then
			bar.BGCenter:SetAlpha(0)
		end
		if bar.BorderLeft then
			bar.BorderLeft:SetAlpha(0)
		end
		if bar.BorderRight then
			bar.BorderRight:SetAlpha(0)
		end
		if bar.BorderCenter then
			bar.BorderCenter:SetAlpha(0)
		end
		if bar.Spark then
			bar.Spark:SetAlpha(0)
		end
		if bar.SparkGlow then
			bar.SparkGlow:SetAlpha(0)
		end
		if bar.BorderGlow then
			bar.BorderGlow:SetAlpha(0)
		end

		bar:CreateBackdrop("Transparent")
		if bar.GetStatusBarTexture then
			ReplaceWidgetBarTexture(bar, bar:GetStatusBarTexture())
			hooksecurefunc(bar, "SetStatusBarTexture", ReplaceWidgetBarTexture)
		end

		bar.styled = true
	end
end

local function ReskinDoubleStatusBarWidget(self)
	if self:IsForbidden() then
		return
	end

	if not self.styled then
		ReskinWidgetStatusBar(self.LeftBar)
		ReskinWidgetStatusBar(self.RightBar)

		self.styled = true
	end
end

local function ReskinPVPCaptureBar(self)
	if self:IsForbidden() then
		return
	end

	self.LeftBar:SetTexture(E.media.normTex)
	self.NeutralBar:SetTexture(E.media.normTex)
	self.RightBar:SetTexture(E.media.normTex)

	self.LeftBar:SetVertexColor(0.2, 0.6, 1, 1)
	self.NeutralBar:SetVertexColor(0.8, 0.8, 0.8, 1)
	self.RightBar:SetVertexColor(0.9, 0.2, 0.2, 1)

	self.LeftLine:SetAlpha(0)
	self.RightLine:SetAlpha(0)
	self.BarBackground:SetAlpha(0)
	self.Glow1:SetAlpha(0)
	self.Glow2:SetAlpha(0)
	self.Glow3:SetAlpha(0)

	if not self.backdrop then
		self:CreateBackdrop("Transparent")
		self.backdrop:SetPoint("TOPLEFT", self.LeftBar, -2, 2)
		self.backdrop:SetPoint("BOTTOMRIGHT", self.RightBar, 2, -2)
	end
end

local function ReskinSpellDisplayWidget(spell)
	if not spell or spell:IsForbidden() then
		return
	end

	if not spell.backdrop then
		spell.Border:SetAlpha(0)
		spell.DebuffBorder:SetAlpha(0)
		spell.backdrop = S:HandleIcon(spell.Icon)
	end
	spell.IconMask:Hide()
end

local function ReskinPowerBarWidget(self)
	if not self.widgetFrames then
		return
	end

	for _, widgetFrame in pairs(self.widgetFrames) do
		if widgetFrame.widgetType == Type_StatusBar then
			if not widgetFrame:IsForbidden() then
				ReskinWidgetStatusBar(widgetFrame.Bar)
			end
		end
	end
end

local function ReskinWidgetItemDisplay(item)
	if not item.Icon.backdrop then
		S:HandleIcon(item.Icon, true)
		S:HandleIconBorder(item.IconBorder, item.Icon.backdrop)
	end
	item.IconMask:Hide()
end

local function ReskinWidgetGroups(self)
	if not self.widgetFrames then
		return
	end

	for _, widgetFrame in pairs(self.widgetFrames) do
		if not widgetFrame:IsForbidden() then
			local widgetType = widgetFrame.widgetType
			if widgetType == Type_DoubleStatusBar then
				ReskinDoubleStatusBarWidget(widgetFrame)
			elseif widgetType == Type_SpellDisplay then
				ReskinSpellDisplayWidget(widgetFrame.Spell)
			elseif widgetType == Type_StatusBar then
				ReskinWidgetStatusBar(widgetFrame.Bar)
			elseif widgetType == Type_ItemDisplay then
				ReskinWidgetItemDisplay(widgetFrame.Item)
			end
		end
	end
end

function module:UIWidgets()
	if not module:CheckDB("misc", "misc") then
		return
	end

	hooksecurefunc(_G.UIWidgetTopCenterContainerFrame, "UpdateWidgetLayout", ReskinWidgetGroups)
	ReskinWidgetGroups(_G.UIWidgetTopCenterContainerFrame)

	hooksecurefunc(_G.UIWidgetBelowMinimapContainerFrame, "UpdateWidgetLayout", function(self)
		if not self.widgetFrames then
			return
		end

		for _, widgetFrame in pairs(self.widgetFrames) do
			if widgetFrame.widgetType == Type_CaptureBar then
				if not widgetFrame:IsForbidden() then
					ReskinPVPCaptureBar(widgetFrame)
				end
			end
		end
	end)

	hooksecurefunc(_G.UIWidgetPowerBarContainerFrame, "UpdateWidgetLayout", ReskinPowerBarWidget)
	ReskinPowerBarWidget(_G.UIWidgetPowerBarContainerFrame)

	hooksecurefunc(_G.ObjectiveTrackerUIWidgetContainer, "UpdateWidgetLayout", ReskinPowerBarWidget)
	ReskinPowerBarWidget(_G.ObjectiveTrackerUIWidgetContainer)

	hooksecurefunc(_G.UIWidgetTemplateStatusBarMixin, "Setup", function(self)
		ReskinWidgetStatusBar(self.Bar)
	end)

	module:SecureHook(S, "SkinStatusBarWidget", function(_, widgetFrame)
		if widgetFrame.Label then
			F.SetFontOutline(widgetFrame.Label)
		end
		if widgetFrame.Bar then
			module:CreateBackdropShadow(widgetFrame.Bar)
			if widgetFrame.Bar.Label then
				F.SetFontOutline(widgetFrame.Bar.Label)
			end
		end
	end)

	module:SecureHook(_G.UIWidgetTemplateStatusBarMixin, "Setup", function(widget)
		local forbidden = widget:IsForbidden()
		local bar = widget.Bar
		local id = widget.widgetSetID

		if forbidden or id == 283 or not bar or not bar.backdrop then
			return
		end

		module:CreateBackdropShadow(bar)

		if widget.isJailersTowerBar and module:CheckDB(nil, "scenario") then
			bar:SetWidth(234)
		end
	end)

	module:SecureHook(_G.UIWidgetTemplateCaptureBarMixin, "Setup", function(widget)
		local bar = widget.Bar
		if bar then
			module:CreateBackdropShadow(bar)
		end
	end)

	module:RawHook(S, "SkinTextWithStateWidget", function(_, widgetFrame)
		local text = widgetFrame.Text
		if not text then
			return
		end
		F.SetFontOutline(text)
		text:SetTextColor(1, 1, 1)
	end, true)
end

module:AddCallback("UIWidgets")
