-- StarterGui/MainGui/GuiInitializer.lua
-- This script loads and initializes all controller modules for the MainGui.

local mainGui = script.Parent
local controllersFolder = mainGui:WaitForChild("Controllers")

local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players") -- Added Players service
local UserInputService = game:GetService("UserInputService") -- Added UserInputService
local player = Players.LocalPlayer -- Get the local player
local playerGui = player:WaitForChild("PlayerGui") -- Get PlayerGui

local Modules = ReplicatedStorage:WaitForChild("Modules")

-- <<< ADDED: Initial delay for stability >>>
task.wait(0.5) -- Wait half a second before loading controllers
print("GuiInitializer: Initial delay complete, loading controllers...")
-- <<< END ADDED >>>

local controllers = {}
local activeControllers = {} -- <<< ADDED: To store active instances

-- <<< MODIFIED: Use a table with paths and locations >>>
-- List of controller modules to load and initialize, specifying paths and locations
local controllerPaths = {
	-- Controllers at the root of Controllers folder
	{ Path = "StatsDisplayController", Location = controllersFolder },
	{ Path = "MenuOpeningController", Location = controllersFolder },
	{ Path = "SettingsUIController", Location = controllersFolder },
	{ Path = "LeaderboardSectUIController", Location = controllersFolder },
	{ Path = "SectCreateController", Location = controllersFolder },
	{ Path = "SectDisplayController", Location = controllersFolder },
	{ Path = "SectInviteNotifyController", Location = controllersFolder },
	{ Path = "LeaderboardController", Location = controllersFolder },

	-- Controllers in Cultivation subfolder
	{ Path = "Cultivation/AptitudeSpinController", Location = controllersFolder },
	{ Path = "Cultivation/RealmListController", Location = controllersFolder },
	{ Path = "Cultivation/MeridianUIController", Location = controllersFolder },
	{ Path = "Cultivation/SpiritualRootsController", Location = controllersFolder },
	-- Controllers in Combat subfolder
	{ Path = "Combat/CombatController", Location = controllersFolder },

	-- <<< AJOUTÉ : Contrôleur pour l'invocation de compétences >>>
	{ Path = "SkillSummonController", Location = controllersFolder },
	-- <<< AJOUTÉ : Contrôleur pour la gestion des compétences >>>
	{ Path = "SkillManagementController", Location = controllersFolder },
	{ Path = "PvPNotificationController", Location = controllersFolder },
	-- CombatRewardUIController est un LocalScript, il ne doit pas être chargé ici.
	-- Remarque: CombatUIManager a été déplacé dans le sous-dossier Modules et sera chargé par CombatController
	-- Add other controller module info here as you create them
}
-- <<< END MODIFIED >>>

-- <<< ADDED: Helper function to find module by path parts >>>
local function findModuleByPath(startFolder, pathString)
	local parts = string.split(pathString, "/")
	local currentItem = startFolder
	for _, part in ipairs(parts) do
		if not currentItem then return nil end -- Stop if any part of the path is missing
		currentItem = currentItem:FindFirstChild(part)
	end
	-- Final check if the found item is a ModuleScript
	if currentItem and currentItem:IsA("ModuleScript") then
		return currentItem
	else
		--warn("GuiInitializer: Could not find valid ModuleScript at path:", pathString, "starting from", startFolder.Name)
		return nil
	end
end
-- <<< END ADDED >>>

-- Function to set initial visibility of frames, including platform-specific controls
local function setupFramesVisibility()
	--print("GuiInitializer: === Running setupFramesVisibility ===")

	-- Platform detection
	local isMobile = UserInputService.TouchEnabled and not UserInputService.KeyboardEnabled
	print("  - Detected platform: " .. (isMobile and "Mobile" or "PC"))

	-- <<< MODIFIED: Define essential frames based on platform >>>
	local essentialFrames = {
		["PlayerInfoFrame"] = true,
		["Keybinds"] = true,
		["AutoBreakthroughButton"] = true, -- <<< ADDED: Make AutoBreakthroughButton essential
		["RealmsList"] = true,
		-- Platform specific are handled below
	}
	local platformSpecificEssential = isMobile and "MobileControllersFrame" or "Keybinds"
	essentialFrames[platformSpecificEssential] = true

	-- <<< ADDED: Get InGameFrame reference >>>
	local inGameFrame = mainGui:FindFirstChild("InGameFrame")
	if not inGameFrame then
		warn("GuiInitializer.setupFramesVisibility: Could not find InGameFrame!")
		-- Decide how to handle this - return? proceed with top-level only?
		-- For now, we will try to proceed, but elements inside InGameFrame won't be found.
	end
	-- <<< END ADDED >>>

	--print(string.format("  - InGameFrame found: %s", tostring(inGameFrame ~= nil)))

	-- Ensure CombatFrame is always initially hidden
	local combatFrameRef = mainGui:FindFirstChild("CombatFrame")
	if combatFrameRef then
		--print("  - Making sure CombatFrame is hidden initially. Current visibility:", combatFrameRef.Visible)
		combatFrameRef.Visible = false
	else
		--print("  - WARNING: CombatFrame not found during initial setup")
	end

	-- <<< MODIFIED: Iterate through top-level AND check inside InGameFrame for essentials >>>
	-- Process top-level frames first
	for _, item in ipairs(mainGui:GetChildren()) do
		-- Skip InGameFrame itself for now, handle its contents separately
		if item:IsA("GuiObject") and item.Name ~= "CombatFrame" and item ~= inGameFrame then
			--print(string.format("    - Checking top-level item: %s (Current Visible: %s)", item.Name, tostring(item.Visible))) -- DEBUG
			-- For top-level items, visibility depends ONLY if they are *specifically* listed as essential 
			-- (e.g., MobileControllersFrame, or if Keybinds was NOT moved)
			local shouldBeVisible = essentialFrames[item.Name] or false 

			-- Special handling for platform toggle for top-level items
			if item.Name == "MobileControllersFrame" then
				shouldBeVisible = isMobile
			elseif item.Name == "Keybinds" then 
				-- This case is now unlikely if Keybinds is in InGameFrame, but kept for safety
				shouldBeVisible = not isMobile
			end

			if item.Visible ~= shouldBeVisible then
				--print(string.format("    - Setting TOP-LEVEL %s visibility to %s (was %s)", item.Name, tostring(shouldBeVisible), tostring(item.Visible)))
				item.Visible = shouldBeVisible
			else
				--print(string.format("    - TOP-LEVEL %s visibility already correct (%s)", item.Name, tostring(item.Visible)))
			end
		end
	end

	-- Now, explicitly handle essential items expected inside InGameFrame
	if inGameFrame then
		for essentialName, _ in pairs(essentialFrames) do
			--print(string.format("    - Checking for essential IN-GAME item: %s", essentialName)) -- DEBUG
			local essentialItem = inGameFrame:FindFirstChild(essentialName)
			--print(string.format("      - Found %s in InGameFrame: %s", essentialName, tostring(essentialItem ~= nil))) -- DEBUG
			if essentialItem and essentialItem:IsA("GuiObject") then
				--print(string.format("        - Current Visible: %s", tostring(essentialItem.Visible))) -- DEBUG
				local shouldBeVisible = true -- Essential items inside InGameFrame should generally be visible

				-- Apply platform visibility rules if the item name matches
				if essentialName == "MobileControllersFrame" then -- If Mobile frame was moved here too
					shouldBeVisible = isMobile
				elseif essentialName == "Keybinds" then
					shouldBeVisible = not isMobile
				end

				if essentialItem.Visible ~= shouldBeVisible then
					--print(string.format("    - Setting IN-GAME %s visibility to %s (was %s)", essentialName, tostring(shouldBeVisible), tostring(essentialItem.Visible)))
					essentialItem.Visible = shouldBeVisible
				else
					--print(string.format("    - IN-GAME %s visibility already correct (%s)", essentialName, tostring(essentialItem.Visible)))
				end
			end
		end
		-- <<< ADDED: Check visibility of InGameFrame itself at the end >>>
		-- <<< MODIFIED: Explicitly set InGameFrame visible >>>
		inGameFrame.Visible = true
		-- <<< END MODIFIED >>>
		--print(string.format("  - Final check: InGameFrame.Visible = %s", tostring(inGameFrame.Visible))) 
		-- <<< END ADDED >>>
	end
	-- <<< END MODIFIED >>>

	--print("GuiInitializer: === Frame visibility setup complete ===")
end

print("GuiInitializer: Starting controller loading loop...")
for _, controllerInfo in ipairs(controllerPaths) do
	local module = findModuleByPath(controllerInfo.Location, controllerInfo.Path)

	if module then
		local reqSuccess, controllerModule = pcall(require, module)
		if reqSuccess then
			if type(controllerModule) == "table" then
				-- Check if it's an OOP-style controller with .new
				if type(controllerModule.new) == "function" then
					-- Attempt to create an instance
					print(string.format("  - Loading OOP controller: %s", controllerInfo.Path))
					local createSuccess, instanceOrErr = pcall(controllerModule.new, mainGui)
					if createSuccess and instanceOrErr then
						local instance = instanceOrErr
						-- Check if instance has an init method
						if type(instance.init) == "function" then
							local initSuccess, initErr = pcall(instance.init, instance, mainGui)
							if initSuccess then
								activeControllers[controllerInfo.Path] = instance
								print(string.format("    - OOP controller %s initialized successfully.", controllerInfo.Path))
							else
								warn(string.format("GuiInitializer: Error calling :init() for %s: %s", controllerInfo.Path, tostring(initErr)))
							end
						else
							warn(string.format("GuiInitializer: Controller %s instance created via .new() but lacks an :init() method.", controllerInfo.Path))
							activeControllers[controllerInfo.Path] = instance
						end
					else
						if not createSuccess then
							warn(string.format("GuiInitializer: Error calling .new() for %s: %s", controllerInfo.Path, tostring(instanceOrErr)))
						else
							-- new() returned nil
							warn(string.format("GuiInitializer: Constructor .new() for %s returned nil.", controllerInfo.Path))
						end
					end
				else
					-- Assume it's a static controller module with .init
					if type(controllerModule.init) == "function" then
						print(string.format("  - Loading static controller: %s", controllerInfo.Path))
						local initSuccess, errMsg = pcall(controllerModule.init, mainGui)
						if initSuccess then
							activeControllers[controllerInfo.Path] = controllerModule
							print(string.format("    - Static controller %s initialized successfully.", controllerInfo.Path))
						else
							warn("GuiInitializer: Error initializing static controller", controllerInfo.Path, ":", errMsg)
						end
					else
						warn("GuiInitializer: Module", controllerInfo.Path, "has no .new() and no static .init(mainGui) function.")
					end
				end
			else
				warn("GuiInitializer: Required module", controllerInfo.Path, "is not a table. Type:", type(controllerModule))
			end
		else
			warn("GuiInitializer: Error requiring", controllerInfo.Path, ":", controllerModule)
		end
	else
		warn("GuiInitializer: Controller module not found:", controllerInfo.Path, "in", controllerInfo.Location.Name)
	end
end
print("GuiInitializer: Finished controller loading loop.")

-- Initial setup when the GUI loads for the first time
setupFramesVisibility()

-- Connect to the CharacterAdded event to reset frame visibility on respawn
player.CharacterAdded:Connect(function(character)
	task.wait(0.1) -- Small delay to ensure character parts are loaded
	setupFramesVisibility()
end)

-- Also update if platform changes during gameplay (e.g., connecting/disconnecting keyboard)
UserInputService.Changed:Connect(function(property)
	if property == "TouchEnabled" or property == "KeyboardEnabled" then
		setupFramesVisibility()
	end
end)

-- <<< ADDED: Connect Sect Leaderboard Open Button >>>
local inGameFrame = mainGui:FindFirstChild("InGameFrame")
if inGameFrame then
	local openSectLBButton = inGameFrame:FindFirstChild("OpenSectLBButton")
	if openSectLBButton and openSectLBButton:IsA("TextButton") then
		openSectLBButton.MouseButton1Click:Connect(function()
			local lbController = activeControllers["LeaderboardSectUIController"]
			if lbController and type(lbController.open) == "function" then
				print("GuiInitializer: OpenSectLBButton clicked, calling LeaderboardSectUIController:open()")
				lbController:open()
			else
				warn("GuiInitializer: LeaderboardSectUIController not found or has no open() method.")
			end
		end)
		print("GuiInitializer: Connected OpenSectLBButton click event.")
	else
		warn("GuiInitializer: Could not find OpenSectLBButton in InGameFrame or it's not a TextButton.")
	end
else
	warn("GuiInitializer: Could not find InGameFrame to search for OpenSectLBButton.")
end
-- <<< END ADDED >>>

-- <<< ADDED: Connect Open Sect Menu Button Logic >>>
local openSectMenuButton = inGameFrame and inGameFrame:FindFirstChild("OpenSectMenuButton") -- Assuming this name
if openSectMenuButton and openSectMenuButton:IsA("TextButton") then
	openSectMenuButton.MouseButton1Click:Connect(function()
		-- <<< MODIFIED: Get Display and Create controllers >>>
		local displayController = activeControllers["SectDisplayController"]
		local createController = activeControllers["SectCreateController"]
		-- <<< END MODIFIED >>>

		-- <<< MODIFIED: Check existence of both >>>
		if displayController and createController then
			-- <<< END MODIFIED >>>
			print("GuiInitializer: OpenSectMenuButton clicked.")
			-- Maybe close other frames opened by MenuOpeningController first?
			-- local menuController = activeControllers["MenuOpeningController"]
			-- if menuController and menuController.closeCurrentContent then menuController:closeCurrentContent() end

			local fetchedInfo = nil
			-- <<< MODIFIED: Check type of displayController >>>
			if type(displayController) == "table" and type(displayController.fetchSectInfo) == "function" then
				-- <<< END MODIFIED >>>
				print("GuiInitializer: Fetching latest sect info for decision...")
				-- Call fetchSectInfo and store the returned result
				local fetchSuccess, fetchResult = pcall(displayController.fetchSectInfo, displayController)
				if fetchSuccess then
					fetchedInfo = fetchResult
					print("GuiInitializer: fetchSectInfo returned:", fetchedInfo)
				else
					warn("GuiInitializer: Error calling fetchSectInfo:", tostring(fetchResult))
					-- fetchedInfo remains nil
				end
			else
				warn("GuiInitializer: SectDisplayController has no fetchSectInfo method or is not a table.")
			end

			-- Check the freshly fetched info
			if fetchedInfo then -- Check if the returned value is truthy (i.e., not nil/false)
				-- <<< MODIFIED: Use displayController >>>
				if type(createController.close) == "function" then createController:close() end
				if type(displayController.openDisplayFrame) == "function" then
					displayController:openDisplayFrame()
				else
					warn("GuiInitializer: SectDisplayController is missing openDisplayFrame method.")
				end
				-- <<< END MODIFIED >>>
			else -- If fetchedInfo is nil or false
				-- <<< MODIFIED: Use displayController >>>
				if type(displayController.closeDisplayFrame) == "function" then displayController:closeDisplayFrame() end
				if type(createController.open) == "function" then
					createController:open()
				else
					warn("GuiInitializer: SectCreateController is missing open method.")
				end
				-- <<< END MODIFIED >>>
			end
			-- <<< END MODIFIED >>>
		else
			-- <<< MODIFIED: Update warning >>>
			warn("GuiInitializer: SectDisplayController or SectCreateController instance not found in activeControllers.")
			-- <<< END MODIFIED >>>
		end
	end)
	print("GuiInitializer: Connected OpenSectMenuButton click event.")
else
	warn("GuiInitializer: Could not find OpenSectMenuButton in InGameFrame or it's not a TextButton.")
end
-- <<< END ADDED >>>

mainGui.Destroying:Connect(function()
	print("GuiInitializer: MainGui is Destroying! Running cleanup...")
	for name, instanceOrModule in pairs(activeControllers) do
		-- Check if it has a destroy method (OOP instances)
		if type(instanceOrModule) == "table" and type(instanceOrModule.destroy) == "function" then
			print("GuiInitializer: Calling :destroy() for instance", name)
			pcall(instanceOrModule.destroy, instanceOrModule)
			-- Check for a cleanup method (Could be OOP or static)
		elseif type(instanceOrModule) == "table" and type(instanceOrModule.cleanup) == "function" then
			print("GuiInitializer: Calling .cleanup() for instance/module", name)
			-- Determine if it needs self or not? Assume static for now if no destroy was found.
			-- If cleanup expects self, this might fail for OOP instances without a destroy method.
			pcall(instanceOrModule.cleanup, instanceOrModule)
		end
	end
	activeControllers = {}
end)

print("GuiInitializer finished loading controllers.") Améliore ça