--[[
	BrickForge Studio Bridge v1.0
	Imports a BrickForge AI project into Roblox Studio as real instances,
	so you can File > Save As a native .rbxl/.rbxm.

	Install: save this file to your Plugins folder (Studio: Plugins tab >
	Plugins Folder), restart Studio, click the BrickForge toolbar button.

	Requirements:
	- Studio settings > Security > Allow HTTP Requests enabled
	- Your BrickForge MCP token (BrickForge app > Settings > MCP)
]]

local HttpService = game:GetService("HttpService")
local ChangeHistoryService = game:GetService("ChangeHistoryService")

local DEFAULT_URL = "https://brickforge-ai.pages.dev"
local BASE = "https://brickforge-ai.pages.dev/api"

local TOOLBAR = plugin:CreateToolbar("BrickForge AI")
local BUTTON = TOOLBAR:CreateButton("BrickForge", "Import a BrickForge AI project", "")
BUTTON.ClickableWhenViewportHidden = true

local token = plugin:GetSetting("bf_token")

local SUPPORTED_PROPS = {
	Part = { Anchored = "bool", CanCollide = "bool", Transparency = "num", Size = "v3", Position = "v3", Color = "c3", Material = "enum:Material", Shape = "enum:PartType" },
	WedgePart = { Anchored = "bool", Size = "v3", Position = "v3", Color = "c3", Material = "enum:Material" },
	SpawnLocation = { Anchored = "bool", Size = "v3", Position = "v3", Color = "c3", Duration = "num" },
	Script = { Disabled = "bool" }, LocalScript = { Disabled = "bool" },
	ScreenGui = { Enabled = "bool", ResetOnSpawn = "bool" },
	Frame = { BackgroundColor3 = "c3", BackgroundTransparency = "num", Size = "ud2", Position = "ud2" },
	ScrollingFrame = { BackgroundColor3 = "c3", Size = "ud2", Position = "ud2" },
	TextLabel = { Text = "str", TextColor3 = "c3", BackgroundColor3 = "c3", BackgroundTransparency = "num", Size = "ud2", Position = "ud2", TextScaled = "bool" },
	TextButton = { Text = "str", TextColor3 = "c3", BackgroundColor3 = "c3", Size = "ud2", Position = "ud2" },
	TextBox = { Text = "str", PlaceholderText = "str", Size = "ud2", Position = "ud2" },
	ImageLabel = { Image = "str", Size = "ud2", Position = "ud2" },
	UICorner = { CornerRadius = "ud" }, UIListLayout = { Padding = "ud" },
	UIStroke = { Color = "c3", Thickness = "num" },
	ProximityPrompt = { ActionText = "str", ObjectText = "str", HoldDuration = "num" },
	ClickDetector = { MaxActivationDistance = "num" },
	NumberValue = { Value = "num" }, IntValue = { Value = "num" }, StringValue = { Value = "str" }, BoolValue = { Value = "bool" },
	PointLight = { Enabled = "bool", Brightness = "num", Color = "c3", Range = "num" },
	Sound = { SoundId = "str", Volume = "num", Looped = "bool" },
	Lighting = { Brightness = "num", ClockTime = "num", Ambient = "c3" },
	StarterPlayer = { EnableMouseLockOption = "bool" },
}

local function setProp(inst, name, kind, value)
	local ok = pcall(function()
		if kind == "bool" then inst[name] = value == true
		elseif kind == "num" or kind == "int" then inst[name] = tonumber(value) or 0
		elseif kind == "str" then inst[name] = tostring(value)
		elseif kind == "v3" then inst[name] = Vector3.new(value[1] or 0, value[2] or 0, value[3] or 0)
		elseif kind == "c3" then inst[name] = Color3.new(value[1] or 0.6, value[2] or 0.6, value[3] or 0.6)
		elseif kind == "ud2" then inst[name] = UDim2.new(value[1] or 0, value[2] or 0, value[3] or 0, value[4] or 0)
		elseif kind == "ud" then inst[name] = UDim.new(value[1] or 0, value[2] or 0)
		elseif kind == "enum:Material" then inst[name] = Enum.Material[tostring(value)]
		elseif kind == "enum:PartType" then inst[name] = Enum.PartType[tostring(value)]
		end
	end)
	if not ok then warn("[BrickForge] skipped property " .. name) end
end

local function build(node, parent)
	local class = node.class
	-- StarterPlayerScripts/StarterCharacterScripts already exist in Studio
	if class == "StarterPlayerScripts" or class == "StarterCharacterScripts" then
		for _, child in ipairs(node.children or {}) do build(child, parent) end
		return
	end
	local inst
	local ok, err = pcall(function() inst = Instance.new(class) end)
	if not ok then
		warn("[BrickForge] unsupported class " .. tostring(class) .. " (" .. tostring(node.name) .. ") - skipped")
		return
	end
	inst.Name = node.name
	local schema = SUPPORTED_PROPS[class] or {}
	for propName, propValue in pairs(node.props or {}) do
		local kind = schema[propName]
		if kind then setProp(inst, propName, kind, propValue) end
	end
	if (class == "Script" or class == "LocalScript" or class == "ModuleScript") and node.source then
		local ok2 = pcall(function() inst.Source = node.source end)
		if not ok2 then warn("[BrickForge] could not set Source on " .. node.name) end
	end
	inst.Parent = parent
	for _, child in ipairs(node.children or {}) do build(child, inst) end
end

local function showResult(text, ok)
	local gui = Instance.new("ScreenGui")
	gui.Name = "BrickForgeBridgeResult"
	gui.ResetOnSpawn = false
	local frame = Instance.new("Frame")
	frame.Size = UDim2.new(0, 380, 0, 90)
	frame.Position = UDim2.new(0.5, -190, 0.5, -45)
	frame.BackgroundColor3 = Color3.fromRGB(18, 21, 29)
	frame.BorderSizePixel = 0
	frame.Parent = gui
	local label = Instance.new("TextLabel")
	label.Size = UDim2.new(1, -24, 1, -24)
	label.Position = UDim2.new(0, 12, 0, 12)
	label.BackgroundTransparency = 1
	label.TextWrapped = true
	label.TextColor3 = ok and Color3.fromRGB(120, 220, 170) or Color3.fromRGB(250, 130, 120)
	label.Text = text
	label.Parent = frame
	gui.Parent = game:GetService("CoreGui")
	game:GetService("Debris"):AddItem(gui, 6)
end

local function import()
	if not token or token == "" then
		showResult("No BrickForge token saved. Click the BrickForge button and paste your MCP token (BrickForge app > Settings > MCP).", false)
		return
	end
	ChangeHistoryService:SetWaypoint("Before BrickForge import")
	local projectId = game:GetAttribute("BrickForgeProjectId")
	local url = BASE .. "/bridge/tree" .. (projectId and ("?projectId=" .. projectId) or "")
	local res = HttpService:RequestAsync({
		Url = url,
		Method = "GET",
		Headers = { ["Authorization"] = "Bearer " .. token },
	})
	if not res.Success then
		showResult("Request failed (" .. tostring(res.StatusCode) .. "). Check your token and that HTTP requests are allowed in Studio.", false)
		return
	end
	local data = HttpService:JSONDecode(res.Body)
	local services = game
	local built = 0
	for _, root in ipairs(data.roots or {}) do
		local svc = services:FindFirstChild(root.name)
		if svc then
			for _, child in ipairs(root.children or {}) do
				build(child, svc)
				built = built + 1
			end
		else
			warn("[BrickForge] service not found: " .. root.name)
		end
	end
	ChangeHistoryService:SetWaypoint("After BrickForge import")
	showResult(("Imported '%s': %d top-level items built. Use File > Save As to save a native .rbxl."):format(data.name or "project", built), true)
end

BUTTON.Click:Connect(function()
	if not token then
		token = "\0"
		-- simple prompt: paste token into Output via dialog is not available, use settings
		plugin:CreateDockWidgetPluginGui("BrickForgeSetup", Enum.InitialDockState.Floating, true, false, "BrickForge")
		showResult("Paste your token: run this in the command bar:  shared.BrickForgeSetToken(\"YOUR_TOKEN\")", false)
	end
	import()
end)

shared.BrickForgeSetToken = function(newToken)
	token = newToken
	plugin:SetSetting("bf_token", newToken)
	showResult("BrickForge token saved. Click the toolbar button to import.", true)
end

print("[BrickForge Studio Bridge] loaded - click the BrickForge toolbar button to import your project")
