--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local assets = require(root.Plugin.assets)
local log = require(root.Plugin.log)
local colorPicker = require(root.Plugin.Components.base.colorPicker)

local specialKeycodeLookup = {
	["+"] = Enum.KeyCode.Plus,
	["-"] = Enum.KeyCode.Minus,
	["*"] = Enum.KeyCode.Asterisk,
	["/"] = Enum.KeyCode.Slash,
	["."] = Enum.KeyCode.Period,
	[";"] = Enum.KeyCode.Semicolon,
	[","] = Enum.KeyCode.Comma,
	["="] = Enum.KeyCode.Equals,
	["["] = Enum.KeyCode.LeftBracket,
	["]"] = Enum.KeyCode.RightBracket,
	["\\"] = Enum.KeyCode.BackSlash,
	["'"] = Enum.KeyCode.Quote,
	["`"] = Enum.KeyCode.Backquote,
	["~"] = Enum.KeyCode.Tilde,
	["|"] = Enum.KeyCode.Pipe,
	["@"] = Enum.KeyCode.At,
	["#"] = Enum.KeyCode.Hash,
	["$"] = Enum.KeyCode.Dollar,
	["%"] = Enum.KeyCode.Percent,
	["^"] = Enum.KeyCode.Caret,
	["&"] = Enum.KeyCode.Ampersand,
	["("] = Enum.KeyCode.LeftParenthesis,
	[")"] = Enum.KeyCode.RightParenthesis,
	["_"] = Enum.KeyCode.Underscore,
	["{"] = Enum.KeyCode.LeftCurly,
	["}"] = Enum.KeyCode.RightCurly,
	[":"] = Enum.KeyCode.Colon,
	['"'] = Enum.KeyCode.QuotedDouble,
	["<"] = Enum.KeyCode.LessThan,
	[">"] = Enum.KeyCode.GreaterThan,
	["?"] = Enum.KeyCode.Question,
}

export type option = {
	type: "select",
	layoutOrder: number,
	options: Fusion.UsedAs<{ [any]: unknown }>,
	value: Fusion.Value<any>,
	selectionChanged: (() -> ())?,
	OverrideXSize: number?,
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
} | {
	type: "string",
	layoutOrder: number,
	value: Fusion.Value<string>,
	focusLost: (() -> ())?,
	OverrideXSize: number?,
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
} | {
	type: "keycode",
	layoutOrder: number,
	value: Fusion.Value<Enum.KeyCode>,
	focusLost: (() -> ())?,
	OverrideXSize: number?,
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
} | {
	type: "number",
	layoutOrder: number,
	value: Fusion.Value<number>,
	focusLost: (() -> ())?,
	OverrideXSize: number?,
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
} | {
	type: "button",
	layoutOrder: number,
	text: Fusion.UsedAs<string>,
	OverrideXSize: number?,
	callback: () -> (),
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
} | {
	type: "color",
	layoutOrder: number,
	value: Fusion.Value<Color3>,
	colorChanged: (() -> ())?,
	label: string,
	disabled: Fusion.UsedAs<boolean?>,
	visible: Fusion.UsedAs<boolean?>,
}

export type childOption = {
	options: { option },
	-- onOptionChange: ((key: number, newValue: any?) -> ())?,
	onOptionChange: nil,
	onEdit: (() -> ())?,
	onDownload: (() -> ())?,
	onDelete: (() -> ())?,
}

local function getSize(data: { [any]: any }): number
	return if data.OverrideXSize ~= nil
		then data.OverrideXSize
		elseif data.type == "number" then 50
		elseif data.type == "button" then 200
		else 250
end

--[[
	createChildren
	A function that will create the required children for a list in the main app
]]
local function createChildren(
	scope: types.Scope,
	props: {
		options: Fusion.UsedAs<{ option }>,

		-- onOptionChange: ((key: number, newValue: any?) -> ())?,
		onOptionChange: nil,
		onEdit: (() -> ())?,
		onDownload: (() -> ())?,
		onDelete: (() -> ())?,

		baseSize: number,
		rowSize: Fusion.Value<number>,
	}
)
	local currentTheme = RedonUI.theme.theme:now()
	local isTrashHovered = scope:Value(false)
	local isDownloadHovered = scope:Value(false)
	local maxOptionsSize = 1820 - 15
	if props.onEdit ~= nil then
		maxOptionsSize = maxOptionsSize - 200 - 15
	end
	if props.onDelete ~= nil then
		maxOptionsSize = maxOptionsSize - 40 - 15
	end
	if props.onDownload ~= nil then
		maxOptionsSize = maxOptionsSize - 36 - 15
	end
	if props.baseSize < 70 then
		maxOptionsSize = maxOptionsSize - 35
	end
	local maxButtonSize = 1820 - maxOptionsSize

	local rowMeta = scope:Value({ { total = 0 } })
	local rows = scope:Computed(function(use)
		local rows = { {} }
		local newRowMeta = { { total = 0 } }
		local currentRow = 1
		local currentRowSize = maxOptionsSize

		for key, data in use(props.options) do
			if use(data.visible) == false then
				continue
			end
			local size = getSize(data)
			if currentRowSize < size then
				currentRow = currentRow + 1
				currentRowSize = maxOptionsSize
				props.rowSize:set(scope.peek(props.rowSize) + 75)
				rows[currentRow] = {}
				newRowMeta[currentRow] = { total = 0 }
			end
			currentRowSize -= size + 15
			rows[currentRow][key] = data
			newRowMeta[currentRow].total += size + 15
			newRowMeta[currentRow][key] = newRowMeta[currentRow].total
		end
		rowMeta:set(newRowMeta)
		return rows
	end)

	local dropdownFrames = scope:Value({})
	local function createDropdown(scope: typeof(scope), props: any)
		local dropdown = scope:dropdown(props)
		local currentDropdowns = scope.peek(dropdownFrames)
		if currentDropdowns[props.LayoutOrder] ~= nil then
			currentDropdowns[props.LayoutOrder].Parent = nil
		end
		-- table.insert(currentDropdowns, props.LayoutOrder, dropdown[2])
		currentDropdowns[props.LayoutOrder] = dropdown[2]
		dropdownFrames:set(currentDropdowns)
		return dropdown[1]
	end

	return {
		scope:base {
			Size = UDim2.fromScale(maxOptionsSize / 1820, 1), -- 1345
			Position = UDim2.fromScale(if props.baseSize < 70 then 0.0274725274725 else 0.0082417582, 0),
			BackgroundTransparency = 1,
			Name = "Options",

			[Fusion.Children] = Fusion.Child {
				scope:New("UIListLayout") {
					Padding = scope:Computed(function(use)
						return UDim.new(15 / use(props.rowSize), 0)
					end),
					FillDirection = Enum.FillDirection.Vertical,
					HorizontalAlignment = Enum.HorizontalAlignment.Left,
					VerticalAlignment = Enum.VerticalAlignment.Top,
					SortOrder = Enum.SortOrder.LayoutOrder,
				},

				scope:ForPairs(rows, function(_, scope: typeof(scope), rowKey: number, value: { option })
					return rowKey,
						scope:base {
							Size = scope:Computed(function(use)
								return UDim2.fromScale(1, props.baseSize / use(props.rowSize))
							end),
							BackgroundTransparency = 1,
							LayoutOrder = rowKey,
							[Fusion.Children] = Fusion.Child {
								scope:New("UIListLayout") {
									Padding = UDim.new(15 / maxOptionsSize, 0),
									FillDirection = Enum.FillDirection.Horizontal,
									HorizontalAlignment = Enum.HorizontalAlignment.Left,
									VerticalAlignment = Enum.VerticalAlignment.Center,
									SortOrder = Enum.SortOrder.LayoutOrder,
								},

								scope:ForPairs(value, function(_, scope: typeof(scope), key: number, data: option)
									local size = getSize(data)

									local baseProps = {
										Size = scope:Computed(function(use)
											return UDim2.fromScale(
												size / maxOptionsSize,
												(if props.baseSize < 70 then 45 else 50) / use(props.rowSize)
											)
										end),
										BackgroundColor3 = scope:Computed(function(use)
											return if use(data.disabled) == true
												then currentTheme.colors.base
												else currentTheme.colors.crust
										end),
										BorderColor3 = scope:Computed(function(use)
											return if use(data.disabled) == true
												then currentTheme.colors.overlay0
												else currentTheme.colors.white
										end),
										Interactable = scope:Computed(function(use)
											return if use(data.disabled) == true then false else true
										end),
										Visible = data.visible,
										CornerRadius = UDim.new(0, 5),
										Border = 1,
										TextScaled = true,
										MaxTextSize = 20,
										FontWeight = Enum.FontWeight.Regular,
										LayoutOrder = data.layoutOrder,
									}
									-- if data.disabled == true then
									-- 	baseProps.Interactable = false
									-- 	baseProps.BackgroundColor3 = currentTheme.colors.base
									-- 	baseProps.BorderColor3 = currentTheme.colors.overlay0
									-- end
									local textBaseProps = {
										MaxSize = Vector2.new(300, 50),
										PaddingBottom = UDim.new(0.2, 0),
										PaddingTop = UDim.new(0.2, 0),
										PaddingLeft = UDim.new(10 / size, 0),
										PaddingRight = UDim.new(10 / size, 0),
									}
									if data.type == "string" then
										return key,
											scope:textBox(scope.CombineProperties(baseProps, textBaseProps, {
												Text = data.value,
												[Fusion.Out "Text"] = data.value,
												TextXAlignment = Enum.TextXAlignment.Left,
												[Fusion.OnEvent "FocusLost"] = function()
													if data.focusLost then
														data.focusLost()
													end
												end,
											}))
									elseif data.type == "keycode" then
										local value = scope:Value(scope.peek(data.value).Name)
										return key,
											scope:textBox(scope.CombineProperties(baseProps, textBaseProps, {
												Text = scope:Computed(function(use)
													return use(data.value).Name
												end),
												[Fusion.Out "Text"] = value,
												TextXAlignment = Enum.TextXAlignment.Left,
												[Fusion.OnEvent "FocusLost"] = function()
													local success, actualValue = pcall(function()
														local possibleKeycode = scope.peek(value)
														if specialKeycodeLookup[possibleKeycode] then
															return specialKeycodeLookup[possibleKeycode]
														end
														return (Enum.KeyCode :: any)[possibleKeycode]
													end)
													if not success then
														log.warn("Unable to serialize keycode", actualValue)
														return
													end
													data.value:set(actualValue)

													if data.focusLost then
														data.focusLost()
													end
												end,
											}))
									elseif data.type == "number" then
										local value = scope:Value(tostring(scope.peek(data.value)))
										return key,
											scope:textBox(scope.CombineProperties(baseProps, textBaseProps, {
												Text = data.value,
												[Fusion.Out "Text"] = value,
												TextXAlignment = Enum.TextXAlignment.Center,
												[Fusion.OnEvent "FocusLost"] = function()
													local success, actualValue = pcall(function()
														return tonumber(scope.peek(value))
													end)
													if not success or actualValue == nil then
														log.warn("Unable to serialize number", actualValue)
														return
													end
													data.value:set(actualValue)

													if data.focusLost then
														data.focusLost()
													end
												end,
											}))
									elseif data.type == "color" then
										-- local value = scope:Value(data.initialValue)
										local isHovered = scope:Value(false)
										return key,
											scope:textButton(scope.CombineProperties(baseProps, {
												MaxSize = Vector2.new(300, 50),
												TextLabelSize = UDim2.fromScale(1, 1),
												Text = scope:Computed(function(use)
													local currentValue = use(data.value)
													return ("%d, %d, %d"):format(
														currentValue.R * 255,
														currentValue.G * 255,
														currentValue.B * 255
													)
												end),
												TextXAlignment = Enum.TextXAlignment.Left,
												[Fusion.OnEvent "Activated"] = function()
													local newColor = colorPicker(scope, {
														id = "evcColorPicker",
														initialColor = scope.peek(data.value),
													})
													if newColor then
														data.value:set(newColor)
														if data.colorChanged then
															data.colorChanged()
														end
													end
												end,
												Reactive = true,

												MouseEnter = function()
													isHovered:set(true)
												end,
												MouseLeave = function()
													isHovered:set(false)
												end,

												[Fusion.Children] = {
													scope:New("UIPadding") {
														PaddingTop = UDim.new(0.2, 0),
														PaddingBottom = UDim.new(0.2, 0),
														PaddingLeft = UDim.new(10 / size, 0),
														PaddingRight = UDim.new(10 / size, 0),
													},

													scope:base {
														Size = UDim2.fromScale(0.1304347826, 1),
														Position = UDim2.fromScale(1, 0.5),
														AnchorPoint = Vector2.new(1, 0.5),
														CornerRadius = UDim.new(1, 0),
														BackgroundColor3 = data.value,

														[Fusion.Children] = {
															scope:New("UIAspectRatioConstraint") {
																AspectRatio = 1,
															},
														},
													},
												},
											}))
									elseif data.type == "button" then
										return key,
											scope:textButton(scope.CombineProperties(baseProps, {
												MaxSize = Vector2.new(300, 50),
												Text = data.text,
												TextXAlignment = Enum.TextXAlignment.Center,
												[Fusion.OnEvent "Activated"] = function()
													data.callback()
												end,
												Reactive = true,
											}))
									elseif data.type == "select" then
										-- local value = scope:Value(data.initialValue)
										local absoluteSize = scope:Value(Vector2.one)
										return key,
											createDropdown(
												scope,
												scope.CombineProperties(baseProps, {
													DropdownHeight = 100,
													Options = data.options,
													Text = scope:Computed(function(use)
														local currentValue = use(data.value)
														return if currentValue == nil then "None" else currentValue
													end),
													TextXAlignment = Enum.TextXAlignment.Left,
													Position = scope:Computed(function(use)
														local currentRowMeta = use(rowMeta)
														if
															currentRowMeta[rowKey] == nil
															or currentRowMeta[rowKey][key] == nil
														then
															return UDim2.fromScale(0, 0)
														end
														return UDim2.fromScale(
															(
																currentRowMeta[rowKey][key]
																- size
																- (if props.baseSize < 70 then -25 else 15)
															) / maxOptionsSize,
															0
														)
													end),
													[Fusion.Out "AbsoluteSize"] = absoluteSize,
													DropdownYOffset = scope:Computed(function(use)
														return UDim.new(0, use(absoluteSize).Y + 25)
													end),
													RemoveForPadding = UDim2.fromOffset(0, 10),

													OnOptionSelected = function(_, v)
														data.value:set(v)
														if data.selectionChanged then
															data.selectionChanged()
														end
													end,
												})
											)
									end
									return key, {} :: any
								end),
							},
						}
				end),
			},
		},
		scope:base {
			Size = UDim2.fromScale(maxOptionsSize / 1820, 1), -- 1345
			Position = UDim2.fromScale(0.0082417582, 0),
			BackgroundTransparency = 1,
			Name = "Dropdowns",

			[Fusion.Children] = dropdownFrames,
		},
		scope:base {
			Size = UDim2.fromScale(maxButtonSize / 1820, 1),
			AnchorPoint = Vector2.new(1, 0.5),
			Position = UDim2.fromScale(0.9917582418, 0.5),
			BackgroundTransparency = 1,
			Name = "Buttons",

			[Fusion.Children] = Fusion.Child {
				scope:New("UIListLayout") {
					Padding = UDim.new(15 / maxButtonSize, 0),
					FillDirection = Enum.FillDirection.Horizontal,
					HorizontalAlignment = Enum.HorizontalAlignment.Right,
					VerticalAlignment = Enum.VerticalAlignment.Center,
					SortOrder = Enum.SortOrder.LayoutOrder,
				},

				if props.onEdit ~= nil
					then scope:textButton {
						Size = UDim2.fromScale(200 / maxButtonSize, 0.6666666667),
						MaxSize = Vector2.new(200, 50),
						BackgroundColor3 = currentTheme.colors.crust,
						Shadow = true,
						ShadowColor3 = currentTheme.colors.mantle,
						ButtonGlow = true,
						ButtonGlowColor3 = currentTheme.colors.mantle,
						CornerRadius = UDim.new(0, 5),
						Border = 1,
						Text = "Edit",
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Medium,
						TextXAlignment = Enum.TextXAlignment.Center,
						Reactive = true,
						LayoutOrder = 1,

						[Fusion.OnEvent "Activated"] = function()
							if props.onEdit then
								props.onEdit()
							end
						end,
					}
					else {},
				if props.onDelete ~= nil
					then scope:iconButton {
						Size = UDim2.fromScale(40 / maxButtonSize, 0.7666666667),
						BackgroundTransparency = 1,
						Image = scope:Computed(function(use)
							return if use(isTrashHovered)
								then assets.images.redonUI.trashFilled
								else assets.images.redonUI.trash
						end),
						Reactive = true,
						ScaleType = Enum.ScaleType.Fit,
						LayoutOrder = 3,

						MouseEnter = function()
							isTrashHovered:set(true)
						end,

						MouseLeave = function()
							isTrashHovered:set(false)
						end,

						[Fusion.OnEvent "Activated"] = function()
							if props.onDelete then
								props.onDelete()
							end
						end,
					}
					else {},
				if props.onDownload ~= nil
					then scope:iconButton {
						Size = UDim2.fromScale(36 / maxButtonSize, 0.7666666667),
						BackgroundTransparency = 1,
						Image = scope:Computed(function(use)
							return if use(isDownloadHovered)
								then assets.images.redonUI.downloadFilled
								else assets.images.redonUI.download
						end),
						Reactive = true,
						ScaleType = Enum.ScaleType.Fit,
						LayoutOrder = 2,

						MouseEnter = function()
							isDownloadHovered:set(true)
						end,

						MouseLeave = function()
							isDownloadHovered:set(false)
						end,

						[Fusion.OnEvent "Activated"] = function()
							if props.onDownload then
								props.onDownload()
							end
						end,
					}
					else {},
			},
		},
	}
end

return function(
	scope: types.Scope,
	props: {
		options: Fusion.UsedAs<{ option }>,
		childOptions: Fusion.UsedAs<{ childOption }?>?,

		-- onOptionChange: ((key: number, newValue: any?) -> ())?,
		onOptionChange: nil,
		onEdit: (() -> ())?,
		onDownload: (() -> ())?,
		onDelete: (() -> ())?,

		baseSize: number?,
		actualTableSize: Fusion.Value<Vector2>?,
		rowSize: Fusion.Value<number>,
	}
): Fusion.Child
	log.debug(props)
	if props.childOptions == nil or props.actualTableSize == nil then
		local baseSize = props.baseSize or 75
		return createChildren(scope, {
			options = props.options,
			-- onOptionChange = props.onOptionChange,
			onEdit = props.onEdit,
			onDownload = props.onDownload,
			onDelete = props.onDelete,
			baseSize = baseSize,
			rowSize = props.rowSize,
		})
	end

	local combinedOptions = scope:Computed(function(use)
		local currentOptions = use(props.childOptions)
		if currentOptions == nil then
			currentOptions = {}
		end
		log.debug(currentOptions)
		local firstOption: childOption = {
			options = props.options,
			-- onOptionChange = props.onOptionChange,
			onEdit = props.onEdit,
			onDownload = props.onDownload,
			onDelete = props.onDelete,
		}
		table.insert(currentOptions, 1, firstOption)
		return currentOptions
	end)
	local allRowSize = {}

	return Fusion.Child {
		scope:New("UIListLayout") {
			SortOrder = Enum.SortOrder.LayoutOrder,
		},

		scope:ForPairs(combinedOptions, function(_, scope: typeof(scope), key: number, value: childOption)
			local thisRowSize = scope:Value(if key == 1 then 75 else 62)
			scope:Observer(thisRowSize):onChange(function()
				local this = scope.peek(thisRowSize)
				allRowSize[key] = this
				local total = 0
				for _, v in ipairs(allRowSize) do
					total += v
				end
				props.rowSize:set(total)
			end)
			return key,
				scope:base {
					Size = UDim2.fromScale(1, 0),
					BackgroundTransparency = 1,
					LayoutOrder = key,
					AutomaticSize = Enum.AutomaticSize.Y,
					ZIndex = key,

					[Fusion.Children] = {
						scope:base {
							Size = scope:Computed(function(use)
								return UDim2.new(1, 0, 0, (use(thisRowSize) / 820) * use(props.actualTableSize).Y)
							end),
							BackgroundTransparency = 1,

							[Fusion.Children] = createChildren(scope, {
								options = value.options,

								-- onOptionChange = value.onOptionChange,
								onEdit = value.onEdit,
								onDownload = value.onDownload,
								onDelete = value.onDelete,

								baseSize = scope.peek(thisRowSize),
								rowSize = thisRowSize,
							}),
						},
					},
				}
		end),
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local chassisHandler = require(root.Plugin.chassisHandler)
local log = require(root.Plugin.log)
local popup = require(root.Plugin.Components.popup)
local createChildren = require(script.Parent.Parent.createChildren)
local vehicle = require(root.Plugin.vehicle)

local function addButton(
	scope: types.Scope,
	currentTheme: typeof(RedonUI.theme.mocha),
	buttonText: Fusion.UsedAs<string>,
	onPress: () -> ()
): Fusion.Child
	return scope:base {
		Size = UDim2.fromScale(1, 0.0914634146),
		BackgroundTransparency = 1,
		LayoutOrder = 1000,

		[Fusion.Children] = {
			scope:textButton {
				Size = UDim2.fromScale(1, 0.6666666667),
				MaxSize = Vector2.new(175, 50),
				AnchorPoint = Vector2.new(0.5, 0.5),
				Position = UDim2.fromScale(0.5, 0.5),
				BackgroundColor3 = currentTheme.colors.crust,
				CornerRadius = UDim.new(0, 5),
				Border = 1,
				Text = buttonText,
				TextScaled = true,
				MaxTextSize = 30,
				FontWeight = Enum.FontWeight.Medium,
				TextXAlignment = Enum.TextXAlignment.Center,
				Reactive = true,

				[Fusion.OnEvent "Activated"] = function()
					onPress()
				end,
			},
		},
	}
end

type props = {
	UnsavedChanges: Fusion.Value<boolean>,
	CurrentPanel: Fusion.Value<types.mainPanels>,
	CurrentPage: Fusion.Value<types.pages?>,
	CurrentVehicle: Fusion.Value<Model | string?>,
	CurrentPattern: Fusion.Value<types.selectedPattern?>,
	ReturnTo: Fusion.Value<types.returnTo>,
	firstScope: types.Scope,
	currentContent: Fusion.Value<"functions" | "activation" | "patterns">,
	functions: Fusion.Value<{ { name: string, weight: number } }>,
	activations: Fusion.Value<{ types.activationState }>,
	actualTableSize: Fusion.Value<Vector2>,
	patterns: Fusion.Value<{ types.pattern }>,
	selectedFunction: Fusion.Value<number?>,
}

local SPRING_SPEED = 20
local SPRING_DAMPING = 0.75
--[[
	Activations Page
	Creates the activations page for the functions page
]]
return function(scope: types.Scope, props: props)
	local currentTheme = RedonUI.theme.theme:now()

	local currentConfiguration = nil
	scope:Observer(props.CurrentVehicle):onChange(function()
		local currentVehicle = scope.peek(props.CurrentVehicle)
		if typeof(currentVehicle) == "Instance" then
			currentConfiguration = chassisHandler:getConfiguration(currentVehicle)
		end
	end)

	local function updateActivationsConfiguration()
		local currentFunction = scope.peek(props.selectedFunction)
		if currentConfiguration ~= nil and currentFunction ~= nil then
			local assembledActivations: { types.activation } = {}
			for _, activation in scope.peek(props.activations) do
				local newActivation = {} :: types.activation
				for key, stateValue in pairs(activation) do
					local value = scope.peek(stateValue)
					if typeof(value) == "table" then
						local newTable = {}
						for i, v in pairs(value) do
							newTable[i] = scope.peek(v)
						end
						newActivation[key] = newTable
					else
						newActivation[key] = value
					end
				end
				table.insert(assembledActivations, newActivation)
			end
			log.debug(assembledActivations)
			if currentConfiguration.functions[currentFunction].activations ~= assembledActivations then
				props.UnsavedChanges:set(true)
			end
			currentConfiguration.functions[currentFunction].activations = assembledActivations
		end
	end

	local contentChooserXSize = 0.1098901099
	return scope:base {
		Size = UDim2.fromScale(1, 1),
		AnchorPoint = Vector2.new(0.5, 0.5),
		Position = scope:Spring(
			scope:Computed(function(use)
				local activeContent = use(props.currentContent)
				if activeContent ~= "functions" then
					return UDim2.fromScale(0.5, 0.5)
				else
					return UDim2.fromScale(1.5, 0.5)
				end
			end),
			SPRING_SPEED,
			SPRING_DAMPING
		),
		BackgroundTransparency = 1,
		ClipsDescendants = true,

		[Fusion.Children] = {
			scope:base {
				Size = UDim2.fromScale(1, 0.0558659218),
				AnchorPoint = Vector2.new(0.5, 0),
				Position = UDim2.fromScale(0.5, 0.0145251397),
				BackgroundTransparency = 1,
				ClipsDescendants = true,

				[Fusion.Children] = {
					scope:textButton {
						TextLabelSize = UDim2.fromScale(1, 1),
						Size = UDim2.fromScale(0.2, 1),
						Position = UDim2.fromScale(0.0054945055, -0.12),
						TextScaled = true,
						Text = "<- Return To Functions",
						BackgroundTransparency = 1,
						TextXAlignment = Enum.TextXAlignment.Left,
						TextColor3 = currentTheme.colors.text,
						FontWeight = Enum.FontWeight.Medium,
						MaxTextSize = 20,
						Reactive = true,
						AnimateSize = false,

						[Fusion.OnEvent "Activated"] = function()
							props.currentContent:set("functions")
							props.selectedFunction:set(nil)
						end :: unknown,
					},

					scope:base {
						CornerRadius = UDim.new(0.5, 0),
						BackgroundColor3 = currentTheme.colors.blue,
						Size = UDim2.fromScale(contentChooserXSize, 0.2),
						AnchorPoint = Vector2.new(0.5, 0),
						Position = scope:Spring(
							scope:Computed(function(use)
								local currentContent = use(props.currentContent)
								if currentContent == "functions" then
									return UDim2.fromScale(1, 0)
								end
								if currentContent == "activation" then
									return UDim2.fromScale(0.5 + (contentChooserXSize / 2 + 0.0082417583), 0.9)
								else
									return UDim2.fromScale(0.5 - (contentChooserXSize / 2 + 0.0082417583), 0.9)
								end
							end),
							SPRING_SPEED,
							SPRING_DAMPING
						),
					},

					scope:base {
						Size = UDim2.fromScale(1, 1),
						Position = UDim2.fromScale(0, -0.12),
						BackgroundTransparency = 1,

						[Fusion.Children] = Fusion.Child {
							scope:New("UIListLayout") {
								Padding = UDim.new(0.0164835165, 0),
								FillDirection = Enum.FillDirection.Horizontal,
								HorizontalAlignment = Enum.HorizontalAlignment.Center,
								VerticalAlignment = Enum.VerticalAlignment.Center,
								SortOrder = Enum.SortOrder.LayoutOrder,
							},

							scope:ForPairs(
								{ "Patterns", "Activation" },
								function(_, scope: typeof(scope), key: number, value: string)
									local loweredValue = value:lower()
									return key,
										scope:textButton {
											Size = UDim2.fromScale(contentChooserXSize, 1),
											BackgroundTransparency = 1,
											TextColor3 = scope:Computed(function(use)
												return use(props.currentContent) == loweredValue
														and currentTheme.colors.blue
													or currentTheme.colors.text
											end),
											Text = value,
											TextScaled = true,
											MaxTextSize = 30,
											FontWeight = scope:Computed(function(use)
												return use(props.currentContent) == loweredValue
														and Enum.FontWeight.Bold
													or Enum.FontWeight.Regular
											end),
											LayoutOrder = key,
											Reactive = true,
											AnimateSize = false,

											[Fusion.OnEvent "Activated"] = function()
												props.currentContent:set(loweredValue :: "activation" | "patterns")
											end,
										}
								end
							),
						},
					},
				},
			},

			--TODO: This can be seperated into its own section
			scope:list {
				Size = UDim2.fromScale(1, 0.9162011173), -- 895 -75 total 820
				AnchorPoint = Vector2.new(0.5, 1),
				Position = scope:Spring(
					scope:Computed(function(use)
						local activeContent = use(props.currentContent)
						if activeContent == "patterns" then
							return UDim2.fromScale(0.5, 1)
						elseif activeContent == "activation" then
							return UDim2.fromScale(-1, 1)
						else
							return UDim2.fromScale(1.5, 1)
						end
					end),
					SPRING_SPEED,
					SPRING_DAMPING
				),
				BackgroundColor3 = currentTheme.colors.mantle,
				AlternateColor3 = currentTheme.colors.crust,
				RowSize = UDim2.fromScale(1, 0), -- 1820, 75
				PrimaryColor = "Alternate" :: "Alternate",
				CornerRadius = UDim.new(0.0182926829, 0),
				AutomaticSize = Enum.AutomaticSize.Y,
				Rows = scope:ForPairs(props.patterns, function(_, scope: typeof(scope), key: number, _: types.pattern)
					local rowSize = scope:Value(75)
					local bg = scope:Spring(scope:Value(1), 10, 1)
					bg:setPosition(0)

					local index = scope:Value(key)
					return key,
						scope:base {
							Size = scope:Computed(function(use)
								return UDim2.new(1, 0, 0, (use(rowSize) / 820) * use(props.actualTableSize).Y)
							end),
							BackgroundColor3 = currentTheme.colors.surface0,
							BackgroundTransparency = bg,

							[Fusion.Children] = createChildren(scope, {
								rowSize = rowSize,
								options = {
									{
										type = "number",
										value = index,
										focusLost = function()
											local selectedFunction = scope.peek(props.selectedFunction)
											if currentConfiguration == nil or selectedFunction == nil then
												return
											end
											local newValue = scope.peek(index)
											local currentPatterns = scope.peek(props.patterns)
											if currentPatterns[newValue] ~= nil then
												local currentPattern = currentPatterns[key]
												local otherPattern = currentPatterns[newValue]
												if currentPattern == otherPattern then
													log.warn("Attempted to swap pattern with itself")
													return
												end
												scope.arraySwap(currentPatterns, key, newValue)
												currentConfiguration.functions[selectedFunction].patterns =
													currentPatterns
												props.patterns:set(currentPatterns)
												props.UnsavedChanges:set(true)
												return
											end

											local currentPattern = currentPatterns[key]
											table.remove(currentPatterns, key)
											scope.insertAtNumberOrEnd(currentPatterns, newValue, currentPattern)
											currentConfiguration.functions[selectedFunction].patterns = currentPatterns
											props.patterns:set(currentPatterns)
											props.UnsavedChanges:set(true)
										end,
										layoutOrder = 1,
									},
								} :: { createChildren.option },

								onEdit = function()
									local selectedFunction = scope.peek(props.selectedFunction)
									if currentConfiguration == nil or selectedFunction == nil then
										return
									end
									props.CurrentPattern:set({
										functionId = selectedFunction,
										patternId = key,
										pattern = currentConfiguration.functions[selectedFunction].patterns[key],
									})
									props.CurrentPage:set("Flashers")
									props.CurrentPanel:set("ELS Setup")
									props.ReturnTo:set("vehicleSetup")
								end,
								onDelete = function()
									local selectedFunction = scope.peek(props.selectedFunction)
									if currentConfiguration == nil or selectedFunction == nil then
										return
									end

									popup:addPopup(scope, {
										title = "Delete Pattern",
										description = "Are you sure you want to delete this pattern?\n<b>All data will be lost.</b>",
										actions = {
											{
												text = "Cancel",
												type = "primary",
												key = 1,
												callback = function(newPopup)
													popup:removePopup(newPopup)
												end,
												keybind = Enum.KeyCode.Escape,
											},
											{
												text = "Delete",
												type = "danger",
												key = 2,
												callback = function(newPopup)
													popup:removePopup(newPopup)
													local currentPatterns = scope.peek(props.patterns)
													table.remove(currentPatterns, key)
													props.patterns:set(currentPatterns)
													currentConfiguration.functions[selectedFunction].patterns =
														currentPatterns
													props.UnsavedChanges:set(true)
												end,
											},
										},
									})
								end,
								onDownload = function() end,
							}),
						}
				end),
				[Fusion.Children] = addButton(scope, currentTheme, "Add Pattern", function()
					if currentConfiguration == nil then
						return
					end
					local currentPatterns = scope.peek(props.patterns)
					table.insert(currentPatterns, scope.deepCopy(chassisHandler.defaults.functions.patterns[1]))
					props.patterns:set(currentPatterns)
					props.UnsavedChanges:set(true)
				end),
			},

			--TODO: This can be seperated into its own section
			scope:list {
				Size = UDim2.fromScale(1, 0.9162011173), -- 895 -75 total 820
				AnchorPoint = Vector2.new(0.5, 1),
				Position = scope:Spring(
					scope:Computed(function(use)
						local activeContent = use(props.currentContent)
						if activeContent == "activation" then
							return UDim2.fromScale(0.5, 1)
						else
							return UDim2.fromScale(1.5, 1)
						end
					end),
					SPRING_SPEED,
					SPRING_DAMPING
				),
				BackgroundColor3 = currentTheme.colors.mantle,
				AlternateColor3 = currentTheme.colors.crust,
				RowSize = UDim2.fromScale(1, 0), -- 1820, 75
				PrimaryColor = "Alternate" :: "Alternate",
				CornerRadius = UDim.new(0.0182926829, 0),
				AutomaticSize = Enum.AutomaticSize.Y,
				Rows = scope:ForPairs(
					props.activations,
					function(_, scope: typeof(scope), key: number, value: types.activationState)
						local sirenVisible = scope:Computed(function(use)
							return use(value.mode) == "Siren Override"
						end)
						local rowSize = scope:Value(75)
						local activationType = scope:Value(scope.peek(value.type))
						return key,
							scope:base {
								Size = scope:Computed(function(use)
									return UDim2.new(1, 0, 0, (use(rowSize) / 820) * use(props.actualTableSize).Y)
								end),
								BackgroundTransparency = 1,

								[Fusion.Children] = createChildren(scope, {
									rowSize = rowSize,
									options = scope:Computed(function(use)
										local controls: { createChildren.option } = {
											{
												type = "select",
												value = activationType,
												layoutOrder = 1,
												options = scope:Computed(function(use)
													local defaultOptions = { "Standard", "Default", "Override" }
													local currentVehicle = use(props.CurrentVehicle)
													if
														currentVehicle ~= nil
														and typeof(currentVehicle) == "Instance"
													then
														local vehicleType = vehicle:isValidVehicle(currentVehicle)
														if vehicleType == "ag" or vehicleType == "mg" then
															table.insert(defaultOptions, "AG-Event")
														end
													end
													return defaultOptions
												end),
												selectionChanged = function()
													if currentConfiguration == nil then
														return
													end
													local newType = scope.peek(activationType)
													if newType == "Standard" then
														value.mode = value.mode
															or props.firstScope:Value("Cycle") :: any
														if
															value.mode ~= nil
															and (
																scope.peek(value.mode) ~= "Cycle"
																or scope.peek(value.mode) ~= "Set Pattern"
															)
														then
															value.mode:set("Cycle")
														end
														value.pattern = value.pattern or props.firstScope:Value(0)
														value.keybinds = value.keybinds
															or props.firstScope:Value({
																props.firstScope:Value(Enum.KeyCode.J),
																props.firstScope:Value(Enum.KeyCode.DPadLeft),
															})
														value.siren = nil
														value.dependentFunction = nil
														value.dependentPattern = nil
														value.conditions = nil
													elseif newType == "Override" then
														value.pattern = nil
														value.keybinds = nil
														value.mode = value.mode or props.firstScope:Value("Park") :: any
														if
															value.mode ~= nil
															and (
																scope.peek(value.mode) == "Cycle"
																or scope.peek(value.mode) == "Set Pattern"
															)
														then
															value.mode:set("Park")
														end
														value.siren = value.siren or props.firstScope:Value(nil)
														value.dependentFunction = value.dependentFunction
															or props.firstScope:Value("No Dependent Function")
														value.dependentPattern = value.dependentPattern
															or props.firstScope:Value(0)
													elseif newType == "Default" then
														value.pattern = value.pattern or props.firstScope:Value(0)
														value.mode = nil
														value.siren = nil
														value.dependentFunction = nil
														value.dependentPattern = nil
														value.conditions = nil
														value.keybinds = nil
													elseif newType == "AG-Event" then
														value.pattern = nil
														value.mode = value.mode
															or props.firstScope:Value("Stages") :: any
														if
															value.mode ~= nil
															and (
																scope.peek(value.mode) ~= "Stages"
																or scope.peek(value.mode) ~= "Traffic Advisor"
																or scope.peek(value.mode) ~= "Scene"
																or scope.peek(value.mode) ~= "Ally Left"
																or scope.peek(value.mode) ~= "Ally Right"
																or scope.peek(value.mode) ~= "Rear Scene"
															)
														then
															value.mode:set("Stages")
														end
														value.siren = nil
														value.dependentFunction = nil
														value.dependentPattern = nil
														value.conditions = nil
														value.keybinds = nil
													end
													value.type:set(newType :: any)
													updateActivationsConfiguration()
												end,
											},
										}

										local currentType = use(value.type)
										if
											currentType == "Standard"
											and value.mode ~= nil
											and value.pattern ~= nil
											and value.keybinds ~= nil
										then
											table.insert(controls, {
												type = "select",
												value = value.mode,
												layoutOrder = 2,
												options = { "Cycle", "Set Pattern" },
												selectionChanged = updateActivationsConfiguration,
											})
											table.insert(controls, {
												type = "number",
												value = value.pattern,
												layoutOrder = 3,
												disabled = scope:Computed(function(use)
													return if use(value.mode) == "Cycle" then true else false
												end),
												focusLost = updateActivationsConfiguration,
											})
											for i, keybind in use(value.keybinds) do
												table.insert(controls, {
													type = "keycode",
													value = keybind,
													layoutOrder = i + 3,
													focusLost = updateActivationsConfiguration,
												})
											end
										elseif
											currentType == "Override"
											and value.mode ~= nil
											and value.siren ~= nil
											and value.dependentFunction ~= nil
											and value.dependentPattern ~= nil
										then
											table.insert(controls, {
												type = "select",
												value = value.mode,
												layoutOrder = 2,
												options = { "Siren Override", "Park", "Brake", "Reverse" },
												selectionChanged = function()
													if scope.peek(value.mode) == "Siren Override" then
														if scope.peek(value.siren) == nil then
															value.siren:set("Unknown Siren")
														end
													else
														value.siren:set(nil)
													end
													updateActivationsConfiguration()
												end,
											})
											-- if use(value.siren) ~= nil then
											table.insert(controls, {
												type = "select",
												value = value.siren,
												layoutOrder = 3,
												options = scope:Computed(function()
													if currentConfiguration == nil then
														return {}
													end

													local sirensByName = {}
													for _, siren in pairs(currentConfiguration.sirens) do
														table.insert(sirensByName, siren.name)
													end
													return sirensByName
												end),
												selectionChanged = updateActivationsConfiguration,
												visible = sirenVisible,
											})
											-- end

											table.insert(controls, {
												type = "select",
												value = value.dependentFunction,
												layoutOrder = 4,
												options = scope:Computed(function(use)
													local choices = { "No Dependent Function" }
													for _, func in use(props.functions) do
														table.insert(choices, func.weight, func.name)
													end
													return choices
												end),
												selectionChanged = updateActivationsConfiguration,
											})
											table.insert(controls, {
												type = "number",
												value = value.dependentPattern,
												layoutOrder = 5,
												focusLost = updateActivationsConfiguration,
											})
										elseif currentType == "Default" and value.pattern ~= nil then
											table.insert(controls, {
												type = "number",
												value = value.pattern,
												layoutOrder = 2,
												focusLost = updateActivationsConfiguration,
											})
										elseif currentType == "AG-Event" and value.mode ~= nil then
											table.insert(controls, {
												type = "select",
												value = value.mode,
												layoutOrder = 2,
												options = {
													"Stages",
													"Traffic Advisor",
													"Scene",
													"Ally Left",
													"Ally Right",
													"Rear Scene",
												},
												selectionChanged = updateActivationsConfiguration,
											})
										end

										return controls
									end),

									onDelete = function()
										local selectedFunction = scope.peek(props.selectedFunction)
										if currentConfiguration == nil or selectedFunction == nil then
											return
										end

										popup:addPopup(scope, {
											title = "Delete Activation",
											description = "Are you sure you want to delete this activation?\n<b>All data will be lost.</b>",
											actions = {
												{
													text = "Cancel",
													type = "primary",
													key = 1,
													callback = function(newPopup)
														popup:removePopup(newPopup)
													end,
													keybind = Enum.KeyCode.Escape,
												},
												{
													text = "Delete",
													type = "danger",
													key = 2,
													callback = function(newPopup)
														popup:removePopup(newPopup)
														local currentActivations = scope.peek(props.activations)
														table.remove(currentActivations, key)
														props.activations:set(currentActivations)
														updateActivationsConfiguration()
													end,
													keybind = Enum.KeyCode.Return,
												},
											},
										})
									end,
									onDownload = function() end,
								}),
							}
					end
				),
				[Fusion.Children] = addButton(scope, currentTheme, "Add Activation", function()
					if currentConfiguration == nil then
						return
					end
					local currentActivations = scope.peek(props.activations)
					local newActivation: types.activationState = {
						type = props.firstScope:Value("Standard") :: any,
						mode = props.firstScope:Value("Cycle") :: any,
						pattern = props.firstScope:Value(0),
						keybinds = props.firstScope:Value({
							props.firstScope:Value(Enum.KeyCode.J),
							props.firstScope:Value(Enum.KeyCode.DPadLeft),
						}),
					}
					table.insert(currentActivations, newActivation)
					props.activations:set(currentActivations)
					props.UnsavedChanges:set(true)
				end),
			},
		},
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local chassisHandler = require(root.Plugin.chassisHandler)
local log = require(root.Plugin.log)
local popup = require(root.Plugin.Components.popup)
local createChildren = require(script.Parent.Parent.createChildren)

local function testFunctionName(name: string, functions: { string }, currentDepth: number): string
	local actualName = if currentDepth == 0 then name else `{name} ({currentDepth})`
	local index = table.find(functions, actualName)
	if index ~= nil then
		return testFunctionName(name, functions, currentDepth + 1)
	end
	return actualName
end

type props = {
	UnsavedChanges: Fusion.Value<boolean>,
	currentContent: Fusion.Value<"functions" | "activation" | "patterns">,
	CurrentVehicle: Fusion.Value<Model | string?>,
	functions: Fusion.Value<{ { name: string, weight: number } }>,
	actualTableSize: Fusion.Value<Vector2>,
	patterns: Fusion.Value<{ types.pattern }>,
	selectedFunction: Fusion.Value<number?>,
}

local SPRING_SPEED = 20
local SPRING_DAMPING = 0.75
--[[
	Functions Page
	Creates the functions page for the functions page
]]
return function(scope: types.Scope, props: props)
	local currentTheme = RedonUI.theme.theme:now()

	local currentConfiguration = nil
	scope:Observer(props.CurrentVehicle):onChange(function()
		local currentVehicle = scope.peek(props.CurrentVehicle)
		if typeof(currentVehicle) == "Instance" then
			currentConfiguration = chassisHandler:getConfiguration(currentVehicle)
		end
	end)

	local newFunctionName = scope:Value("")
	return scope:base {
		Size = UDim2.fromScale(1, 1),
		AnchorPoint = Vector2.new(0.5, 0.5),
		Position = scope:Spring(
			scope:Computed(function(use)
				local activeContent = use(props.currentContent)
				if activeContent == "functions" then
					return UDim2.fromScale(0.5, 0.5)
				else
					return UDim2.fromScale(-1, 0.5)
				end
			end),
			SPRING_SPEED,
			SPRING_DAMPING
		),
		BackgroundTransparency = 1,

		[Fusion.Children] = {
			scope:base {
				Size = UDim2.fromScale(1, 0.0558659218),
				AnchorPoint = Vector2.new(0.5, 0),
				Position = UDim2.fromScale(0.5, 0.0145251397),
				BackgroundTransparency = 1,

				[Fusion.Children] = {
					scope:New("UIListLayout") {
						Padding = UDim.new(0.0164835165, 0),
						FillDirection = Enum.FillDirection.Horizontal,
						HorizontalAlignment = Enum.HorizontalAlignment.Center,
						SortOrder = Enum.SortOrder.LayoutOrder,
					},

					scope:textBox {
						Size = UDim2.fromScale(0.1648351648, 1),
						MaxSize = Vector2.new(300, 50),
						BackgroundColor3 = currentTheme.colors.crust,
						CornerRadius = UDim.new(0.2, 0),
						Border = 1,
						PlaceholderText = "New Function Name",
						[Fusion.Out "Text"] = newFunctionName,
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Regular,
						TextXAlignment = Enum.TextXAlignment.Left,
						LayoutOrder = 1,
						PaddingBottom = UDim.new(0.2, 0),
						PaddingTop = UDim.new(0.2, 0),
						PaddingLeft = UDim.new(0.0333333333, 0),
						PaddingRight = UDim.new(0.0333333333, 0),
					},

					scope:textButton {
						Size = UDim2.fromScale(0.0961538462, 1),
						MaxSize = Vector2.new(175, 50),
						BackgroundColor3 = currentTheme.colors.crust,
						CornerRadius = UDim.new(0.2, 0),
						Border = 2,
						Text = "Add",
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Bold,
						LayoutOrder = 2,
						Reactive = true,

						[Fusion.OnEvent "Activated"] = function()
							log.debug(currentConfiguration)
							if currentConfiguration == nil then
								return
							end
							local newFunctionName = scope.peek(newFunctionName)
							if newFunctionName == "" then
								newFunctionName = "New Function"
							end
							local currentFunctions = scope.peek(props.functions)
							local functionsByName = {}
							for i, func in currentFunctions do
								functionsByName[i] = func.name
							end
							newFunctionName = testFunctionName(newFunctionName, functionsByName, 0)

							local newFunctionData = scope.deepCopy(chassisHandler.defaults.functions)
							newFunctionData.name = newFunctionName
							newFunctionData.weight = #currentConfiguration.functions + 1
							table.insert(currentConfiguration.functions, newFunctionData)

							table.insert(
								currentFunctions,
								{ name = newFunctionData.name, weight = newFunctionData.weight }
							)
							log.debug(currentConfiguration.functions, currentFunctions)
							props.functions:set(currentFunctions)
							props.UnsavedChanges:set(true)
						end,
					},

					scope:textButton {
						Size = UDim2.fromScale(0.0961538462, 1),
						MaxSize = Vector2.new(175, 50),
						BackgroundColor3 = currentTheme.colors.crust,
						CornerRadius = UDim.new(0.2, 0),
						Border = 2,
						Text = "Import",
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Bold,
						LayoutOrder = 3,
						Reactive = true,
					},
				},
			},

			scope:list {
				Size = UDim2.fromScale(1, 0.9162011173), -- 895 -75 total 820
				AnchorPoint = Vector2.new(0.5, 1),
				Position = UDim2.fromScale(0.5, 1),
				BackgroundColor3 = currentTheme.colors.mantle,
				AlternateColor3 = currentTheme.colors.crust,
				RowSize = UDim2.fromScale(1, 0), -- 1820, 75
				PrimaryColor = "Alternate" :: "Alternate",
				CornerRadius = UDim.new(0.0182926829, 0),
				AutomaticSize = Enum.AutomaticSize.Y,
				[Fusion.Out "AbsoluteSize"] = props.actualTableSize,
				Rows = scope:ForPairs(
					props.functions,
					function(_, scope: typeof(scope), key: number, value: { name: string, weight: number })
						local rowSize = scope:Value(75)
						local bg = scope:Spring(scope:Value(1), 10, 1)
						bg:setPosition(0)

						local weight = scope:Value(value.weight)
						local name = scope:Value(value.name)
						return key,
							scope:base {
								Size = scope:Computed(function(use)
									return UDim2.new(1, 0, 0, (use(rowSize) / 820) * use(props.actualTableSize).Y)
								end),
								BackgroundColor3 = currentTheme.colors.surface0,
								BackgroundTransparency = bg,

								[Fusion.Children] = createChildren(scope, {
									rowSize = rowSize,
									options = {
										{
											type = "number",
											value = weight,
											focusLost = function()
												if currentConfiguration == nil then
													return
												end
												local newValue = scope.peek(weight)
												local currentFunctions = scope.peek(props.functions)
												if currentFunctions[newValue] ~= nil then
													local currentFunction = currentFunctions[key]
													local otherFunction = currentFunctions[newValue]
													if currentFunction == otherFunction then
														log.warn("Attempted to swap function with itself")
														return
													end
													-- update the weights first
													currentFunctions[key].weight = newValue
													currentConfiguration.functions[key].weight = newValue
													currentFunctions[newValue].weight = key
													currentConfiguration.functions[newValue].weight = key

													-- now swap the functions
													scope.arraySwap(currentFunctions, key, newValue)
													scope.arraySwap(currentConfiguration.functions, key, newValue)
													props.functions:set(currentFunctions)
													props.UnsavedChanges:set(true)
													return
												end

												local currentFunction = currentFunctions[key]
												local currentData = currentConfiguration.functions[key]
												-- Clear old
												table.remove(currentFunctions, key)
												table.remove(currentConfiguration.functions, key)

												-- Insert new
												local actualPos = scope.insertAtNumberOrEnd(
													currentFunctions,
													newValue,
													currentFunction
												)
												scope.insertAtNumberOrEnd(
													currentConfiguration.functions,
													newValue,
													currentData
												)

												-- Update weights
												for i, func in currentFunctions do
													func.weight = i
													currentConfiguration.functions[i].weight = i
												end

												weight:set(actualPos)

												props.functions:set(currentFunctions)
												props.UnsavedChanges:set(true)
											end,
											layoutOrder = 1,
										},
										{
											type = "string",
											value = name,
											focusLost = function()
												if currentConfiguration == nil then
													return
												end
												local newValue = scope.peek(name)
												local currentFunctions = scope.peek(props.functions)
												currentFunctions[key].name = newValue
												currentConfiguration.functions[key].name = newValue
												props.functions:set(currentFunctions)
												props.UnsavedChanges:set(true)
											end,
											layoutOrder = 2,
										},
									} :: { createChildren.option },

									onEdit = function()
										if currentConfiguration == nil then
											return
										end
										props.currentContent:set("patterns")
										props.selectedFunction:set(key)
										props.patterns:set(currentConfiguration.functions[key].patterns)
									end,
									onDelete = function()
										if currentConfiguration == nil then
											return
										end

										popup:addPopup(scope, {
											title = "Delete Function",
											description = "Are you sure you want to delete this function?\n<b>All data will be lost.</b>",
											actions = {
												{
													text = "Cancel",
													type = "primary",
													key = 1,
													callback = function(newPopup)
														popup:removePopup(newPopup)
													end,
													keybind = Enum.KeyCode.Escape,
												},
												{
													text = "Delete",
													type = "danger",
													key = 2,
													callback = function(newPopup)
														popup:removePopup(newPopup)
														local currentFunctions = scope.peek(props.functions)
														table.remove(currentFunctions, key)
														table.remove(currentConfiguration.functions, key)
														props.functions:set(currentFunctions)
														props.UnsavedChanges:set(true)
													end,
												},
											},
										})
									end,
									onDownload = function() end,
								}),
							}
					end
				),
			},
		},
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local chassisHandler = require(root.Plugin.chassisHandler)

local functionsPage = require(script.functionsPage)
local activationsPage = require(script.activationsPage)
local components = {
	functionsPage = functionsPage,
	activationsPage = activationsPage,
}

type props = {
	UnsavedChanges: Fusion.Value<boolean>,
	Mode: Fusion.Value<types.mode>,
	CurrentPanel: Fusion.Value<types.mainPanels>,
	CurrentPage: Fusion.Value<types.pages?>,
	CurrentVehicle: Fusion.Value<Model | string?>,
	CurrentPattern: Fusion.Value<types.selectedPattern?>,
	ReturnTo: Fusion.Value<types.returnTo>,
}

--[[
	Functions
	Creates the functions page for the main app
]]
return function(baseScope: types.Scope, props: props): Fusion.Child
	local scope = baseScope:innerScope(components)
	local currentTheme = RedonUI.theme.theme:now()
	local firstScope = scope:innerScope()

	local currentContent: Fusion.Value<"functions" | "activation" | "patterns"> = scope:Value("functions" :: any)
	local currentConfiguration = nil
	local functions: Fusion.Value<{ { name: string, weight: number } }> = scope:Value({})
	local patterns: Fusion.Value<{ types.pattern }> = scope:Value({})
	local activations: Fusion.Value<{ types.activationState }> = scope:Value({})
	local selectedFunction: Fusion.Value<number?> = scope:Value(nil)

	scope:Observer(props.CurrentVehicle):onChange(function()
		local currentVehicle = scope.peek(props.CurrentVehicle)
		if typeof(currentVehicle) == "Instance" then
			currentConfiguration = chassisHandler:getConfiguration(currentVehicle)
			if currentConfiguration ~= nil then
				local newFunctions = {}
				for i, func in currentConfiguration.functions do
					newFunctions[i] = { name = func.name, weight = func.weight }
				end
				functions:set(newFunctions)
				currentContent:set("functions")
			end
		end
	end)

	scope:Observer(selectedFunction):onChange(function()
		local currentFunction = scope.peek(selectedFunction)
		if currentConfiguration ~= nil and currentFunction ~= nil then
			local newActivations: { types.activationState } = {}
			for activationKey, activationData in pairs(currentConfiguration.functions[currentFunction].activations) do
				local newActivation = {} :: types.activationState
				for key, value in pairs(activationData) do
					if typeof(value) == "table" then
						local newTable = {}
						for i, v in pairs(value) do
							newTable[i] = firstScope:Value(v)
						end
						newActivation[key] = newTable
					else
						newActivation[key] = firstScope:Value(value)
					end
				end
				if activationData.type == "Override" and activationData.siren == nil then
					newActivation.siren = firstScope:Value(nil)
				end

				table.insert(newActivations, activationKey, newActivation)
			end
			activations:set(newActivations)
		else
			activations:set({})
		end
	end)

	local actualTableSize = scope:Value(Vector2.one)

	-- 1820, 895
	return scope:base {
		Name = "Functions",
		AnchorPoint = Vector2.new(0.5, 0),
		Position = scope:Spring(
			scope:Computed(function(use)
				local currentPage = use(props.CurrentPage)
				if currentPage == "Functions" then
					return UDim2.fromScale(0.5, 0.0462962963)
				end
				return UDim2.fromScale(-1, 0.0462962963)
			end),
			20,
			0.75
		),
		Size = UDim2.fromScale(1, 0.9537037037),
		BackgroundColor3 = currentTheme.colors.base,

		[Fusion.Children] = {
			scope:New("UIAspectRatioConstraint") {
				AspectRatio = 1.8640776699,
			},

			scope:New("UIPadding") {
				PaddingTop = UDim.new(0.0231481481, 0),
				PaddingBottom = UDim.new(0.0231481481, 0),
				PaddingLeft = UDim.new(0.0260416667, 0),
				PaddingRight = UDim.new(0.0260416667, 0),
			},

			scope:textLabel {
				Size = UDim2.fromScale(1, 0.0555555556),
				AnchorPoint = Vector2.new(0.5, 0),
				Position = UDim2.fromScale(0.5, 0),
				Text = scope:Computed(function(use)
					local selected = use(selectedFunction)
					return if selected ~= nil
						then `Editing Function {scope.peek(functions)[selected].name}`
						else "Select A Function"
				end),
				FontWeight = scope:Computed(function(use)
					return if use(selectedFunction) ~= nil then Enum.FontWeight.Bold else Enum.FontWeight.Medium
				end),
				TextScaled = true,
			},

			scope:base {
				Size = UDim2.fromScale(1, 0.9212962963),
				AnchorPoint = Vector2.new(0.5, 1),
				Position = UDim2.fromScale(0.5, 1),
				BackgroundColor3 = currentTheme.colors.mantle,
				CornerRadius = UDim.new(0.0179640719, 0),
				ClipsDescendants = true,

				[Fusion.Children] = {
					scope:functionsPage {
						UnsavedChanges = props.UnsavedChanges,
						CurrentVehicle = props.CurrentVehicle,
						currentContent = currentContent,
						functions = functions,
						actualTableSize = actualTableSize,
						patterns = patterns,
						selectedFunction = selectedFunction,
					},

					scope:activationsPage {
						UnsavedChanges = props.UnsavedChanges,
						CurrentPanel = props.CurrentPanel,
						CurrentPage = props.CurrentPage,
						CurrentVehicle = props.CurrentVehicle,
						CurrentPattern = props.CurrentPattern,
						ReturnTo = props.ReturnTo,
						firstScope = firstScope,
						currentContent = currentContent,
						functions = functions,
						activations = activations,
						actualTableSize = actualTableSize,
						patterns = patterns,
						selectedFunction = selectedFunction,
					},
				},
			},
		},
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local chassisHandler = require(root.Plugin.chassisHandler)
local popup = require(root.Plugin.Components.popup)
local createChildren = require(script.Parent.Parent.createChildren)

local colorKeyToIndex = {
	"name",
	"partColor",
	"lightColor",
	"lightoColor",
}

type props = {
	actualTableSize: Fusion.Value<Vector2>,
	currentContent: Fusion.Value<"settings" | "colors" | "light groups">,
	lightSettings: Fusion.Value<chassisHandler.lightSettingsState?>,
	updateCurrentConfiguration: () -> (),
}

local SPRING_SPEED = 20
local SPRING_DAMPING = 0.75
--[[
	Colors
	Creates the main colors panel for the light settings page
]]
return function(scope: types.Scope, props: props)
	local currentTheme = RedonUI.theme.theme:now()

	return scope:base {
		ClassName = "ScrollingFrame",
		Size = UDim2.fromScale(1, 0.9162011173), -- 1820, 820
		AnchorPoint = Vector2.new(0.5, 1),
		Position = scope:Spring(
			scope:Computed(function(use)
				local activeContent = use(props.currentContent)
				if activeContent == "colors" then
					return UDim2.fromScale(0.5, 1)
				elseif activeContent == "settings" then
					return UDim2.fromScale(1.5, 1)
				else
					return UDim2.fromScale(-1, 1)
				end
			end),
			SPRING_SPEED,
			SPRING_DAMPING
		),
		BackgroundTransparency = 1,
		ScrollBarThickness = 3,
		ScrollBarImageColor3 = currentTheme.colors.text,
		TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
		BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
		AutomaticCanvasSize = Enum.AutomaticSize.Y,
		CanvasSize = UDim2.new(),

		[Fusion.Children] = Fusion.Child {
			scope:New("UIListLayout") {
				SortOrder = Enum.SortOrder.LayoutOrder,
			},

			scope:base {
				Size = UDim2.fromScale(1, 0.0609756098),
				BackgroundTransparency = 1,
				LayoutOrder = 0,

				[Fusion.Children] = Fusion.Child {
					scope:New("UIListLayout") {
						Padding = UDim.new(0.0082417582, 0),
						FillDirection = Enum.FillDirection.Horizontal,
						SortOrder = Enum.SortOrder.LayoutOrder,
					},

					scope:New("UIPadding") {
						PaddingLeft = UDim.new(0.0082417582, 0),
					},

					scope:ForPairs(
						{ "Name", "Part Color", "Light Color", "Lighto Color" },
						function(_, scope: typeof(scope), key: number, value: string)
							return key,
								scope:textLabel {
									Size = UDim2.fromScale(0.1373626374, 1),
									Text = value,
									FontWeight = Enum.FontWeight.Medium,
									TextXAlignment = Enum.TextXAlignment.Center,
									TextScaled = true,
									MaxTextSize = 25,
									BackgroundTransparency = 1,
									LayoutOrder = key,
								}
						end
					),
				},
			},

			scope:Computed(function(use, scope: typeof(scope))
				local currentLightSettings = use(props.lightSettings)
				if currentLightSettings ~= nil then
					return scope:ForPairs(
						currentLightSettings.colors,
						function(_, scope: typeof(scope), key: number, colorData)
							local rowSize = scope:Value(75)
							local function onOptionChange(option, value)
								local changedIndex = colorKeyToIndex[option]
								local currentColors = scope.peek(currentLightSettings.colors)
								currentColors[key][changedIndex] = value
								currentLightSettings.colors:set(currentColors)
								props.updateCurrentConfiguration()
							end
							local name = scope:Value(colorData.name)
							local partColor = scope:Value(colorData.partColor)
							local lightColor = scope:Value(colorData.lightColor)
							local lightoColor = scope:Value(colorData.lightoColor)

							local childrenProps = {
								rowSize = rowSize,
								actualTableSize = props.actualTableSize,

								options = {
									{
										type = "string",
										layoutOrder = 1,
										value = name,
										disabled = key < 7,
										focusLost = function()
											onOptionChange(1, scope.peek(name))
										end,
									},
									{
										type = "color",
										layoutOrder = 2,
										value = partColor,
										label = "Part Color",
										colorChanged = function()
											onOptionChange(2, scope.peek(partColor))
										end,
									},
									{
										type = "color",
										layoutOrder = 3,
										value = lightColor,
										label = "Light Color",
										colorChanged = function()
											onOptionChange(3, scope.peek(lightColor))
										end,
									},
									{
										type = "color",
										layoutOrder = 4,
										value = lightoColor,
										label = "Lighto Color",
										colorChanged = function()
											onOptionChange(4, scope.peek(lightoColor))
										end,
									},
								} :: { createChildren.option },
							}

							if key > 6 then
								childrenProps.onDelete = function()
									popup:addPopup(scope, {
										title = "Remove Color",
										description = `Are you sure you want to delete color {scope.peek(
											colorData.name
										)}?\nAll data will be lost.`,
										actions = {
											{
												text = "Cancel",
												type = "primary",
												key = 1,
												callback = function(newPopup)
													popup:removePopup(newPopup)
												end,
												keybind = Enum.KeyCode.Escape,
											},
											{
												text = "Delete",
												type = "danger",
												key = 2,
												callback = function(newPopup)
													popup:removePopup(newPopup)
													local currentColors = scope.peek(currentLightSettings.colors)
													table.remove(currentColors, key)
													currentLightSettings.colors:set(currentColors)
													props.updateCurrentConfiguration()
												end,
												keybind = Enum.KeyCode.Return,
											},
										},
									})
								end
							end

							return key,
								scope:base {
									Size = scope:Computed(function(use)
										return UDim2.new(1, 0, 0, (use(rowSize) / 820) * use(props.actualTableSize).Y)
									end),
									BackgroundColor3 = currentTheme.colors.crust,
									BackgroundTransparency = if key % 2 == 0 then 1 else 0,
									LayoutOrder = key,

									[Fusion.Children] = {
										createChildren(scope, childrenProps),
									},
								}
						end
					)
				end

				return {} :: any
			end),

			scope:base {
				Size = UDim2.fromScale(1, 0.0914634146),
				BackgroundTransparency = 1,
				LayoutOrder = 4000,

				[Fusion.Children] = {
					scope:textButton {
						Size = UDim2.fromScale(1, 0.6666666667),
						MaxSize = Vector2.new(175, 50),
						AnchorPoint = Vector2.new(0.5, 0.5),
						Position = UDim2.fromScale(0.5, 0.5),
						BackgroundColor3 = currentTheme.colors.crust,
						CornerRadius = UDim.new(0, 5),
						Border = 1,
						Text = "Add Color",
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Medium,
						TextXAlignment = Enum.TextXAlignment.Center,
						Reactive = true,

						[Fusion.OnEvent "Activated"] = function()
							local currentLightSettings = scope.peek(props.lightSettings)
							if currentLightSettings then
								local currentColors = scope.peek(currentLightSettings.colors)
								table.insert(currentColors, {
									name = "New Color",
									partColor = Color3.new(1, 1, 1),
									lightColor = Color3.new(1, 1, 1),
									lightoColor = Color3.new(1, 1, 1),
								})
								currentLightSettings.colors:set(currentColors)
								props.updateCurrentConfiguration()
							end
						end,
					},
				},
			},
		},
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local chassisHandler = require(root.Plugin.chassisHandler)
local log = require(root.Plugin.log)

local mainSettings = require(script.mainSettings)
local colors = require(script.colors)
local lightGroups = require(script.lightGroups)
local components = {
	mainSettings = mainSettings,
	colors = colors,
	lightGroups = lightGroups,
}

type props = {
	UnsavedChanges: Fusion.Value<boolean>,
	Mode: Fusion.Value<types.mode>,
	CurrentPanel: Fusion.Value<types.mainPanels>,
	CurrentPage: Fusion.Value<types.pages?>,
	CurrentVehicle: Fusion.Value<Model | string?>,
}

local SPRING_SPEED = 20
local SPRING_DAMPING = 0.75
--[[
	Light Settings
	Creates the light settings page for the main app
]]
return function(baseScope: types.Scope, props: props): Fusion.Child
	local scope = baseScope:innerScope(components)
	local currentTheme = RedonUI.theme.theme:now()
	local firstScope = scope:innerScope()

	local currentContent: Fusion.Value<"settings" | "colors" | "light groups"> = scope:Value("settings" :: any)
	local currentConfiguration = nil
	local lightSettings: Fusion.Value<chassisHandler.lightSettingsState?> = scope:Value(nil)
	local lightParts: Fusion.Value<{ string }> = scope:Value({})

	scope:Observer(props.CurrentVehicle):onChange(function()
		local currentVehicle = scope.peek(props.CurrentVehicle)
		if typeof(currentVehicle) == "Instance" then
			currentConfiguration = chassisHandler:getConfiguration(currentVehicle)
			if currentConfiguration ~= nil then
				local newLightSettings = {}

				local newColors = {}
				for colorId, color in currentConfiguration.lightSettings.colors do
					local colorState = {
						name = color.name,
						partColor = color.partColor,
						lightColor = color.lightColor,
						lightoColor = color.lightoColor,
					}
					table.insert(newColors, colorId, colorState)
				end
				newLightSettings.colors = firstScope:Value(newColors)

				newLightSettings.configuration = {
					shouldChangeNeons = firstScope:Value(
						currentConfiguration.lightSettings.configuration.shouldChangeNeons
					),
					shouldChangeLights = firstScope:Value(
						currentConfiguration.lightSettings.configuration.shouldChangeLights
					),
					shouldChangeLightos = firstScope:Value(
						currentConfiguration.lightSettings.configuration.shouldChangeLightos
					),
					shouldChangeParticleEmitters = firstScope:Value(
						currentConfiguration.lightSettings.configuration.shouldChangeParticleEmitters
					),
					partTransparency = firstScope:Value(
						currentConfiguration.lightSettings.configuration.partTransparency
					),
				}

				local newLightGroups = {}
				for groupName, group in currentConfiguration.lightSettings.lightGroups do
					local newLightGroup = {
						name = firstScope:Value(group.name),
						lights = firstScope:Value(group.lights),
					}
					newLightGroups[groupName] = newLightGroup
				end
				newLightSettings.lightGroups = firstScope:Value(newLightGroups)

				lightParts:set(chassisHandler.getLights(currentConfiguration, currentVehicle))
				lightSettings:set(newLightSettings)
			end
		end
	end)

	local function updateCurrentConfiguration()
		local currentLightSettings = scope.peek(lightSettings)
		if currentConfiguration ~= nil and currentLightSettings ~= nil then
			local assembledLightSettings = {
				version = currentConfiguration.lightSettings.version,
				colors = {},
				configuration = {
					shouldChangeNeons = scope.peek(currentLightSettings.configuration.shouldChangeNeons),
					shouldChangeLights = scope.peek(currentLightSettings.configuration.shouldChangeLights),
					shouldChangeLightos = scope.peek(currentLightSettings.configuration.shouldChangeLightos),
					shouldChangeParticleEmitters = scope.peek(
						currentLightSettings.configuration.shouldChangeParticleEmitters
					),
					partTransparency = scope.peek(currentLightSettings.configuration.partTransparency),
				},
				lightGroups = {},
			}

			for colorId, color in scope.peek(currentLightSettings.colors) do
				table.insert(assembledLightSettings.colors, colorId, {
					name = scope.peek(color.name),
					partColor = scope.peek(color.partColor),
					lightColor = scope.peek(color.lightColor),
					lightoColor = scope.peek(color.lightoColor),
				})
			end

			for groupName, group in scope.peek(currentLightSettings.lightGroups) do
				assembledLightSettings.lightGroups[groupName] = {
					name = scope.peek(group.name),
					lights = scope.peek(group.lights),
				}
			end

			currentConfiguration.lightSettings = assembledLightSettings
			props.UnsavedChanges:set(true)
		end
	end

	scope:Observer(props.CurrentPage):onChange(function()
		if scope.peek(props.CurrentPage) ~= "Light Settings" then
			return
		end
		log.debug("Recomputing light parts")
		local currentVehicle = scope.peek(props.CurrentVehicle)
		if currentVehicle ~= nil and typeof(currentVehicle) == "Instance" then
			currentConfiguration = chassisHandler:getConfiguration(currentVehicle)
			if currentConfiguration ~= nil then
				lightParts:set(chassisHandler.getLights(currentConfiguration, currentVehicle))
			end
		end
	end)

	local actualTableSize = scope:Value(Vector2.one)
	local topbarSize = scope:Value(Vector2.one)
	local topbarPosition = scope:Value(Vector2.one)
	local buttonData = {
		position = scope:Value(Vector2.one),
		size = scope:Value(Vector2.one),
	}

	-- 1820, 895
	return scope:base {
		Name = "Light Settings",
		AnchorPoint = Vector2.new(0.5, 0),
		Position = scope:Spring(
			scope:Computed(function(use)
				local currentPage = use(props.CurrentPage)
				if currentPage == "Light Settings" then
					return UDim2.fromScale(0.5, 0.0462962963)
				end
				return UDim2.fromScale(1.5, 0.0462962963)
			end),
			20,
			0.75
		),
		Size = UDim2.fromScale(1, 0.9537037037),
		BackgroundColor3 = currentTheme.colors.base,

		[Fusion.Children] = {
			scope:New("UIAspectRatioConstraint") {
				AspectRatio = 1.8640776699,
			},

			scope:New("UIPadding") {
				PaddingTop = UDim.new(0.0231481481, 0),
				PaddingBottom = UDim.new(0.0231481481, 0),
				PaddingLeft = UDim.new(0.0260416667, 0),
				PaddingRight = UDim.new(0.0260416667, 0),
			},

			scope:textLabel {
				Size = UDim2.fromScale(1, 0.0555555556),
				AnchorPoint = Vector2.new(0.5, 0),
				Position = UDim2.fromScale(0.5, 0),
				Text = "Light Settings",
				FontWeight = Enum.FontWeight.Bold,
				TextScaled = true,
			},

			scope:base {
				Size = UDim2.fromScale(1, 0.9212962963),
				AnchorPoint = Vector2.new(0.5, 1),
				Position = UDim2.fromScale(0.5, 1),
				BackgroundColor3 = currentTheme.colors.mantle,
				CornerRadius = UDim.new(0.0179640719, 0),
				ClipsDescendants = true,

				[Fusion.Children] = {
					scope:base {
						Size = UDim2.fromScale(1, 0.0558659218),
						AnchorPoint = Vector2.new(0.5, 0),
						Position = UDim2.fromScale(0.5, 0.0145251397),
						BackgroundTransparency = 1,
						ClipsDescendants = true,
						[Fusion.Out "AbsoluteSize"] = topbarSize :: unknown,
						[Fusion.Out "AbsolutePosition"] = topbarPosition,

						[Fusion.Children] = {
							scope:base {
								CornerRadius = UDim.new(0.5, 0),
								BackgroundColor3 = currentTheme.colors.blue,
								Size = scope:Spring(
									scope:Computed(function(use)
										return UDim2.new(0, use(buttonData.size).X, 0.2, 0)
									end),
									SPRING_SPEED,
									SPRING_DAMPING
								),
								Position = scope:Spring(
									scope:Computed(function(use)
										return UDim2.new(0, use(buttonData.position).X - use(topbarPosition).X, 0.9, 0)
									end),
									SPRING_SPEED,
									SPRING_DAMPING
								),
							},

							scope:base {
								ClassName = "ScrollingFrame",
								Name = "Buttons",
								Size = UDim2.fromScale(1, 1),
								Position = UDim2.fromScale(0, 0.9),
								AnchorPoint = Vector2.new(0, 1),
								BackgroundTransparency = 1,
								CanvasSize = UDim2.new(),
								AutomaticCanvasSize = Enum.AutomaticSize.X,
								ScrollBarThickness = 0,

								[Fusion.Children] = Fusion.Child {
									scope:New("UIListLayout") {
										FillDirection = Enum.FillDirection.Horizontal,
										HorizontalAlignment = Enum.HorizontalAlignment.Center,
										SortOrder = Enum.SortOrder.LayoutOrder,
										Padding = scope:Computed(function(use)
											return UDim.new(0, 0.015625 * use(topbarSize).X)
										end),
									},

									scope:ForPairs(
										{ "Settings", "Colors", "Light Groups" },
										function(_, scope: typeof(scope), key, value)
											local desiredButtonPosition = scope:Value(UDim2.fromOffset(0, 0))
											local animatedButtonPosition = scope:Spring(desiredButtonPosition, 30, 1)
											local isHovered = scope:Value(false)
											local loweredValue = value:lower()
											local data = {
												position = scope:Value(Vector2.one),
												size = scope:Value(Vector2.one),
											}
											return key,
												scope:base {
													Size = UDim2.new(0, 0, 1, -2),
													AutomaticSize = Enum.AutomaticSize.X,
													LayoutOrder = key,
													BackgroundTransparency = 1,
													[Fusion.Out "AbsolutePosition"] = data.position :: unknown,
													[Fusion.Out "AbsoluteSize"] = data.size,
													MaxSize = Vector2.new(185, 100),

													[Fusion.OnChange "AbsoluteSize"] = function(size)
														if scope.peek(currentContent) == loweredValue then
															buttonData.size:set(size)
														end
													end,

													[Fusion.OnChange "AbsolutePosition"] = function(position)
														if scope.peek(currentContent) == loweredValue then
															buttonData.position:set(position)
														end
													end,

													[Fusion.Children] = {
														scope:textLabel {
															Size = UDim2.fromScale(0, 1),
															ClassName = "TextButton",
															Position = animatedButtonPosition,
															Text = value,
															TextScaled = true,
															AutomaticSize = Enum.AutomaticSize.X,
															TextColor3 = scope:Computed(function(use)
																return if use(currentContent) == loweredValue
																	then currentTheme.colors.blue
																	else currentTheme.colors.text
															end),
															FontFace = scope:Computed(function(use)
																return if use(currentContent) == loweredValue
																	then currentTheme.font[Enum.FontWeight.Bold]
																	else currentTheme.font[Enum.FontWeight.Medium]
															end),
															BackgroundTransparency = 1,
															MaxTextSize = 25,

															[Fusion.OnEvent "MouseEnter"] = function()
																desiredButtonPosition:set(UDim2.fromOffset(0, -3))
																isHovered:set(true)
															end,

															[Fusion.OnEvent "MouseLeave"] = function()
																desiredButtonPosition:set(UDim2.fromOffset(0, 0))
																isHovered:set(false)
															end,

															[Fusion.OnEvent "MouseButton1Down"] = function()
																desiredButtonPosition:set(UDim2.fromOffset(0, 3))
															end,

															[Fusion.OnEvent "MouseButton1Up"] = function()
																if scope.peek(isHovered) == true then
																	desiredButtonPosition:set(UDim2.fromOffset(0, -3))
																else
																	desiredButtonPosition:set(UDim2.fromOffset(0, 0))
																end
															end,

															[Fusion.OnEvent "Activated"] = function()
																currentContent:set(loweredValue :: any)
																buttonData.position:set(scope.peek(data.position))
																buttonData.size:set(scope.peek(data.size))
															end,
														},
													},
												}
										end
									),
								},
							},
						},
					},

					scope:mainSettings {
						actualTableSize = actualTableSize,
						currentContent = currentContent,
						lightSettings = lightSettings,
						updateCurrentConfiguration = updateCurrentConfiguration,
					},

					scope:colors {
						actualTableSize = actualTableSize,
						currentContent = currentContent,
						lightSettings = lightSettings,
						updateCurrentConfiguration = updateCurrentConfiguration,
					},

					scope:lightGroups {
						firstScope = firstScope,
						actualTableSize = actualTableSize,
						currentContent = currentContent,
						lightSettings = lightSettings,
						lightParts = lightParts,
						updateCurrentConfiguration = updateCurrentConfiguration,
					},
				},
			},
		},
	}
end


--#selene: allow(shadowing)
-- Redon Tech Emergency Vehicle Creator, MIT License
local root = script.Parent.Parent.Parent.Parent.Parent.Parent

local Fusion = require(root.Packages.fusion)
local RedonUI = require(root.Packages["redon-ui"])
local types = require(root.Plugin.types)
local assets = require(root.Plugin.assets)
local chassisHandler = require(root.Plugin.chassisHandler)
local popup = require(root.Plugin.Components.popup)

type props = {
	firstScope: types.Scope,
	actualTableSize: Fusion.Value<Vector2>,
	currentContent: Fusion.Value<"settings" | "colors" | "light groups">,
	lightSettings: Fusion.Value<chassisHandler.lightSettingsState?>,
	lightParts: Fusion.Value<{ string }>,
	updateCurrentConfiguration: () -> (),
}

local SPRING_SPEED = 20
local SPRING_DAMPING = 0.75
--[[
	Main Settings
	Creates the main settings panel for the light settings page
]]
return function(scope: types.Scope, props: props)
	local currentTheme = RedonUI.theme.theme:now()
	local holdingShift = false

	return scope:base {
		ClassName = "ScrollingFrame",
		Size = UDim2.fromScale(1, 0.9162011173), -- 1820, 820
		AnchorPoint = Vector2.new(0.5, 1),
		Position = scope:Spring(
			scope:Computed(function(use)
				local activeContent = use(props.currentContent)
				if activeContent == "light groups" then
					return UDim2.fromScale(0.5, 1)
				else
					return UDim2.fromScale(1.5, 1)
				end
			end),
			SPRING_SPEED,
			SPRING_DAMPING
		),
		BackgroundTransparency = 1,
		ScrollBarThickness = 3,
		ScrollBarImageColor3 = currentTheme.colors.text,
		TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
		BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
		AutomaticCanvasSize = Enum.AutomaticSize.Y,
		CanvasSize = UDim2.new(),

		[Fusion.OnEvent "InputBegan"] = function(input)
			if input.UserInputType == Enum.UserInputType.Keyboard then
				if input.KeyCode == Enum.KeyCode.LeftShift then
					holdingShift = true
				end
			end
		end :: unknown,

		[Fusion.OnEvent "InputEnded"] = function(input)
			if input.UserInputType == Enum.UserInputType.Keyboard then
				if input.KeyCode == Enum.KeyCode.LeftShift then
					holdingShift = false
				end
			end
		end :: unknown,

		[Fusion.Children] = Fusion.Child {
			scope:New("UIListLayout") {
				SortOrder = Enum.SortOrder.LayoutOrder,
			},

			scope:Computed(function(use, scope: typeof(scope))
				local currentLightSettings = use(props.lightSettings)
				local lastLight = 0
				if currentLightSettings ~= nil then
					return scope:ForPairs(
						currentLightSettings.lightGroups,
						function(_, scope: typeof(scope), key: number, value)
							local isOpen = scope:Value(false)
							local name = scope:Value(scope.peek(value.name))
							local size = scope:Value(Vector2.one)

							local function lightClicked(lightKey: number, lightName: string)
								for _, testGroup in scope.peek(currentLightSettings.lightGroups) do
									if scope.peek(testGroup.name) == lightName then
										return
									end
								end

								local currentLightParts = scope.peek(props.lightParts)
								local currentLights = scope.peek(value.lights)
								local lightIndex = table.find(currentLights, lightName)
								if lightIndex ~= nil then
									table.remove(currentLights, lightIndex)
								else
									table.insert(currentLights, lightName)
								end

								if holdingShift == true then
									local adding = false
									if lightIndex == nil then
										adding = true
									end

									for i, v in currentLightParts do
										if
											(lightKey < lastLight and i > lightKey and i <= lastLight)
											or (lightKey > lastLight and i < lightKey and i >= lastLight)
										then
											if adding == true then
												table.insert(currentLights, v)
											else
												local index = table.find(currentLights, v)
												if index ~= nil then
													table.remove(currentLights, index)
												end
											end
										end
									end
								end

								lastLight = lightKey
								value.lights:set(currentLights)
							end

							local isTrashHovered = scope:Value(false)
							return key,
								scope:base {
									Size = UDim2.fromScale(1, 0),
									AutomaticSize = Enum.AutomaticSize.Y,
									BackgroundColor3 = currentTheme.colors.crust,
									BackgroundTransparency = if key % 2 == 0 then 1 else 0,
									LayoutOrder = key,

									[Fusion.Children] = {
										scope:baseButton {
											Size = scope:Computed(function(use)
												return UDim2.new(1, 0, 0, 0.0914634146 * use(props.actualTableSize).Y)
											end),
											BackgroundTransparency = 1,

											[Fusion.OnEvent "Activated"] = function()
												isOpen:set(not scope.peek(isOpen))
											end :: unknown,

											[Fusion.Children] = {
												scope:textBox {
													Size = UDim2.fromScale(0.1373626374, 0.6666666667),
													Position = UDim2.fromScale(0.0082417582, 0.5),
													AnchorPoint = Vector2.new(0, 0.5),
													BackgroundColor3 = currentTheme.colors.crust,
													CornerRadius = UDim.new(0, 5),
													Border = 1,
													TextScaled = true,
													MaxTextSize = 20,
													FontWeight = Enum.FontWeight.Regular,
													MaxSize = Vector2.new(300, 50),
													PaddingBottom = UDim.new(0.2, 0),
													PaddingTop = UDim.new(0.2, 0),
													PaddingLeft = UDim.new(0.04, 0),
													PaddingRight = UDim.new(0.04, 0),

													Text = name,
													[Fusion.Out "Text"] = name :: unknown,
													TextXAlignment = Enum.TextXAlignment.Left,
													[Fusion.OnEvent "FocusLost"] = function()
														local currentLightSettings = scope.peek(props.lightSettings)
														if currentLightSettings ~= nil then
															local currentLightGroups =
																scope.peek(currentLightSettings.lightGroups)
															currentLightGroups[key].name:set(scope.peek(name))
															currentLightSettings.lightGroups:set(currentLightGroups)
														end
														props.updateCurrentConfiguration()
													end,
												},

												scope:New("ImageLabel") {
													Name = "Arrow",
													AnchorPoint = Vector2.new(1, 0.5),
													Position = UDim2.fromScale(0.9615384615, 0.5),
													Size = UDim2.fromScale(0.0219780220, 0.2933333333),
													BackgroundTransparency = 1,
													Image = assets.images.redonUI.arrow,
													ImageColor3 = currentTheme.colors.text,
													Rotation = scope:Spring(
														scope:Computed(function(use)
															return use(isOpen) and 180 or 0
														end),
														SPRING_SPEED,
														SPRING_DAMPING
													),
													ScaleType = Enum.ScaleType.Fit,
												},

												scope:iconButton {
													Size = UDim2.fromScale(0.0219780220, 0.7666666667),
													Position = UDim2.fromScale(0.9917582418, 0.5),
													AnchorPoint = Vector2.new(1, 0.5),
													BackgroundTransparency = 1,
													Image = scope:Computed(function(use)
														return if use(isTrashHovered)
															then assets.images.redonUI.trashFilled
															else assets.images.redonUI.trash
													end),
													Reactive = true,
													ScaleType = Enum.ScaleType.Fit,
													LayoutOrder = 3,

													MouseEnter = function()
														isTrashHovered:set(true)
													end,

													MouseLeave = function()
														isTrashHovered:set(false)
													end,

													[Fusion.OnEvent "Activated"] = function()
														popup:addPopup(scope, {
															title = "Remove Light Group",
															description = `Are you sure you want to delete light group {scope.peek(
																value.name
															)}?\nAll data will be lost.`,
															actions = {
																{
																	text = "Cancel",
																	type = "primary",
																	key = 1,
																	callback = function(newPopup)
																		popup:removePopup(newPopup)
																	end,
																	keybind = Enum.KeyCode.Escape,
																},
																{
																	text = "Delete",
																	type = "danger",
																	key = 2,
																	callback = function(newPopup)
																		popup:removePopup(newPopup)
																		local currentLightSettings =
																			scope.peek(props.lightSettings)
																		if currentLightSettings then
																			local currentLightGroups = scope.peek(
																				currentLightSettings.lightGroups
																			)
																			table.remove(currentLightGroups, key)
																			currentLightSettings.lightGroups:set(
																				currentLightGroups
																			)
																			props.updateCurrentConfiguration()
																		end
																	end,
																	keybind = Enum.KeyCode.Return,
																},
															},
														})
													end,
												},
											},
										},

										scope:base {
											ClassName = "ScrollingFrame",
											Size = scope:Spring(
												scope:Computed(function(use)
													return if use(isOpen)
														then UDim2.new(
															1,
															0,
															0,
															0.2743902439 * use(props.actualTableSize).Y
														)
														else UDim2.fromScale(1, 0)
												end),
												20,
												0.75
											),
											Position = scope:Computed(function(use)
												return UDim2.fromOffset(0, 0.0914634146 * use(props.actualTableSize).Y)
											end),
											BackgroundTransparency = 1,
											ScrollBarThickness = 3,
											ScrollBarImageColor3 = currentTheme.colors.text,
											TopImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
											BottomImage = "rbxasset://textures/ui/Scroll/scroll-middle.png",
											AutomaticCanvasSize = scope:Computed(function(use)
												return if use(isOpen)
													then Enum.AutomaticSize.Y
													else Enum.AutomaticSize.None
											end),
											CanvasSize = UDim2.new(),
											Visible = scope:Computed(function(use)
												return if use(size).Y < 1 then false else true
											end),
											[Fusion.Out "AbsoluteSize"] = size :: unknown,

											[Fusion.Children] = Fusion.Child {
												scope:New("UIGridLayout") {
													CellSize = scope:Computed(function(use)
														local currentSize = use(size)
														return UDim2.fromOffset(
															0.0824175824 * currentSize.X,
															0.2 * currentSize.Y
														)
													end),
													SortOrder = Enum.SortOrder.LayoutOrder,
													HorizontalAlignment = Enum.HorizontalAlignment.Left,
													VerticalAlignment = Enum.VerticalAlignment.Top,
													FillDirection = Enum.FillDirection.Horizontal,
													CellPadding = scope:Computed(function(use)
														local currentSize = use(size)
														return UDim2.fromOffset(
															0.0082417582 * currentSize.X,
															0.0666666667 * currentSize.Y
														)
													end),
												},

												scope:New("UIPadding") {
													PaddingLeft = UDim.new(0.0082417582, 0),
													PaddingTop = UDim.new(0, 5),
													PaddingBottom = UDim.new(0, 5),
												},

												scope:ForPairs(
													props.lightParts,
													function(_, scope: typeof(scope), lightKey, lightName)
														return lightKey,
															scope:textButton {
																BackgroundColor3 = currentTheme.colors.crust,
																Border = 1,
																CornerRadius = UDim.new(0.2222222222, 0),
																Text = lightName,
																TextScaled = true,
																MaxTextSize = 20,
																FontWeight = Enum.FontWeight.Regular,
																TextXAlignment = Enum.TextXAlignment.Left,
																Reactive = true,
																LayoutOrder = lightKey,

																[Fusion.OnEvent "Activated"] = function()
																	lightClicked(lightKey, lightName)
																	props.updateCurrentConfiguration()
																end :: unknown,

																[Fusion.Children] = {
																	scope:checkBox {
																		Size = UDim2.fromScale(0.2, 0.6666666667),
																		AnchorPoint = Vector2.new(1, 0.5),
																		Position = UDim2.fromScale(0.9333333333, 0.5),
																		BackgroundColor3 = currentTheme.colors.crust,
																		CornerRadius = scope:Computed(function(use)
																			return UDim.new(
																				0,
																				0.0091463415
																					* use(props.actualTableSize).Y
																			)
																		end),
																		Border = 1,
																		BorderColor3 = currentTheme.colors.white,
																		SelectedColor3 = currentTheme.colors.blue,
																		SelectedCheckColor3 = currentTheme.colors.crust,
																		Enabled = scope:Computed(function(use)
																			local currentLights = use(value.lights)
																			return table.find(currentLights, lightName)
																				~= nil
																		end),

																		[Fusion.OnEvent "Activated"] = function()
																			lightClicked(lightKey, lightName)
																			props.updateCurrentConfiguration()
																		end,
																		-- TriggerHover = isHovered,
																		-- TriggerPush = isPushed,
																	},
																},
															}
													end
												),
											},
										},
									},
								}
						end
					)
				end

				return {} :: any
			end),

			scope:base {
				Size = UDim2.fromScale(1, 0.0914634146),
				BackgroundTransparency = 1,
				LayoutOrder = 4000,

				[Fusion.Children] = {
					scope:textButton {
						Size = UDim2.fromScale(1, 0.6666666667),
						MaxSize = Vector2.new(175, 50),
						AnchorPoint = Vector2.new(0.5, 0.5),
						Position = UDim2.fromScale(0.5, 0.5),
						BackgroundColor3 = currentTheme.colors.crust,
						CornerRadius = UDim.new(0, 5),
						Border = 1,
						Text = "Add Light Group",
						TextScaled = true,
						MaxTextSize = 30,
						FontWeight = Enum.FontWeight.Medium,
						TextXAlignment = Enum.TextXAlignment.Center,
						Reactive = true,

						[Fusion.OnEvent "Activated"] = function()
							local currentLightSettings = scope.peek(props.lightSettings)
							if currentLightSettings then
								local currentLightGroups = scope.peek(currentLightSettings.lightGroups)
								table.insert(currentLightGroups, {
									name = props.firstScope:Value("Group"),
									lights = props.firstScope:Value({}),
								})
								currentLightSettings.lightGroups:set(currentLightGroups)
								props.updateCurrentConfiguration()
							end
							props.updateCurrentConfiguration()
						end,
					},
				},
			},
		},
	}
end