-- ROBLOX deviation: predefine variables

local isTaggedTemplateLiteral, isEmptyString, isEmptyTable, pluralize

type TemplateData = Global_TemplateData

local EXPECTED_COLOR = chalk.green
local RECEIVED_COLOR = chalk.red

local function validateArrayTable(table_: unknown): ()
	if not Array.isArray(table_) then
		error(
			Error.new(
				"`.each` must be called with an Array or Tagged Template Literal.\n\n"
					.. ("Instead was called with: %s\n"):format(pretty(table_, { maxDepth = 1, min = true }))
			)
		)
	end

	if isTaggedTemplateLiteral(table_) then
		if isEmptyString(table_[1]) then
			error(Error.new("Error: `.each` called with an empty Tagged Template Literal of table data.\n"))
		end
		error(
			Error.new(
				"Error: `.each` called with a Tagged Template Literal with no data, remember to interpolate with ${expression} syntax.\n"
			)
		)
	end

	if isEmptyTable(table_) then
		error(Error.new("Error: `.each` called with an empty Array of table data.\n"))
	end
end
exports.validateArrayTable = validateArrayTable

function isTaggedTemplateLiteral(array: any)
	return array.raw ~= nil
end

function isEmptyTable(table_: Array<unknown>)
	return #table_ == 0
end

function isEmptyString(str: string | unknown)
	return typeof(str) == "string" and String.trim(str) == ""
end

local function validateTemplateTableArguments(headings: Array<string>, data: TemplateData): ()
	-- ROBLOX deviation START: dealing with arrays instead of a variadic list of values, error if any has less or more elements
	Array.forEach(data, function(array, index)
		local countDifference = #headings - #array
		local missingData = if countDifference >= 0 then countDifference else (countDifference - #headings)

		if missingData ~= 0 then
			error(
				Error.new(
					("%s arguments supplied for given headings:\n"):format(
						if countDifference > 0 then "Not enough" else "Too many"
					)
						.. tostring(EXPECTED_COLOR(Array.join(headings, " | ")))
						.. "\n\n"
						.. "Received:\n"
						.. tostring(RECEIVED_COLOR(pretty(data)))
						.. "\n\n"
						.. ("%s %s %s in row %d"):format(
							if countDifference > 0 then "Missing" else "Remove",
							RECEIVED_COLOR(tostring(missingData)),
							pluralize("argument", missingData),
							index
						)
				)
			)
		end
	end)
	-- ROBLOX deviation END
end
exports.validateTemplateTableArguments = validateTemplateTableArguments

function pluralize(word: string, count: number)
	return word .. (if count == 1 then "" else "s")
end
