local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local UserInputService = game:GetService("UserInputService")
local RunService = game:GetService("RunService")

local player = Players.LocalPlayer
local camera = workspace.CurrentCamera

-- Configuration
local THIRD_PERSON_ZOOM = 12 -- Distance for third-person view
local CAMERA_HEIGHT_OFFSET = 2 -- How high above the character to position camera
local CAMERA_SMOOTHING = 0.1 -- Lower = smoother camera movement (0.1 - 1.0)

-- State tracking
local isMedkitActive = false
local originalMaxZoomDistance = nil
local originalMinZoomDistance = nil
local originalCameraType = nil
local originalCameraSubject = nil
local currentMedkitTool = nil
local toolConnections = {}
local hiddenViewModel = nil
local cameraConnection = nil
local isRestoringCamera = false
local cameraUpdateConnection = nil

-- Function to hide ViewModel
local function hideViewModel()
	local viewModel = ReplicatedStorage:FindFirstChild("ViewModel")
	if viewModel then
		viewModel.Parent = nil
		return viewModel
	end
	return nil
end

-- Function to show ViewModel
local function showViewModel(viewModel)
	if viewModel then
		viewModel.Parent = ReplicatedStorage
	end
end

-- Function to restore first person camera
local function restoreFirstPersonCamera()
	if isRestoringCamera then
		print("Camera restoration already in progress, skipping...")
		return
	end
	
	isRestoringCamera = true
	print("Restoring first-person camera...")

	-- Disconnect camera update connection
	if cameraUpdateConnection then
		pcall(function()
			cameraUpdateConnection:Disconnect()
		end)
		cameraUpdateConnection = nil
	end

	-- Disconnect other camera connections
	if cameraConnection then
		pcall(function()
			cameraConnection:Disconnect()
		end)
		cameraConnection = nil
	end

	-- Wait a frame to ensure connections are properly disconnected
	task.wait()

	-- Restore original camera settings
	if originalCameraType then
		camera.CameraType = originalCameraType
		originalCameraType = nil
	else
		camera.CameraType = Enum.CameraType.Custom
	end

	if originalCameraSubject then
		camera.CameraSubject = originalCameraSubject
		originalCameraSubject = nil
	else
		-- Set to player's humanoid as fallback
		local character = player.Character
		if character then
			local humanoid = character:FindFirstChild("Humanoid")
			if humanoid then
				camera.CameraSubject = humanoid
			end
		end
	end

	-- Restore zoom distance settings
	if originalMaxZoomDistance then
		player.CameraMaxZoomDistance = originalMaxZoomDistance
		print("Restored max zoom distance to:", originalMaxZoomDistance)
		originalMaxZoomDistance = nil
	else
		player.CameraMaxZoomDistance = 400
	end

	if originalMinZoomDistance then
		player.CameraMinZoomDistance = originalMinZoomDistance
		print("Restored min zoom distance to:", originalMinZoomDistance)
		originalMinZoomDistance = nil
	else
		player.CameraMinZoomDistance = 0.5
	end

	-- Force camera mode to allow normal behavior
	pcall(function()
		player.CameraMode = Enum.CameraMode.Classic
	end)

	isRestoringCamera = false
	print("First-person camera restored!")
end

-- Function to stop medkit camera
local function stopMedkitCamera()
	if not isMedkitActive then 
		print("Camera already inactive")
		return 
	end

	print("Stopping medkit camera zoom...")
	isMedkitActive = false

	-- Disconnect all tool connections
	for name, connection in pairs(toolConnections) do
		if connection then
			pcall(function()
				if name == "failsafe" then
					task.cancel(connection)
				else
					connection:Disconnect()
				end
			end)
		end
	end
	toolConnections = {}

	-- Restore camera and ViewModel
	restoreFirstPersonCamera()
	showViewModel(hiddenViewModel)

	-- Clear references
	currentMedkitTool = nil
	hiddenViewModel = nil

	print("Medkit camera zoom stopped!")
end

-- Function to update third person camera
local function updateThirdPersonCamera()
	if not isMedkitActive then return end
	
	local character = player.Character
	if not character then return end
	
	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	local humanoid = character:FindFirstChild("Humanoid")
	if not humanoidRootPart or not humanoid then return end
	
	-- Get character's position and rotation
	local rootCFrame = humanoidRootPart.CFrame
	local rootPosition = rootCFrame.Position
	
	-- Calculate camera position behind and above the character
	local backwardVector = -rootCFrame.LookVector
	local upwardVector = Vector3.new(0, 1, 0)
	
	-- Position camera behind the character
	local cameraPosition = rootPosition + (backwardVector * THIRD_PERSON_ZOOM) + (upwardVector * CAMERA_HEIGHT_OFFSET)
	
	-- Look at the character (slightly above their position for better view)
	local lookAtPosition = rootPosition + Vector3.new(0, CAMERA_HEIGHT_OFFSET * 0.5, 0)
	
	-- Smoothly interpolate camera movement for less jarring transitions
	local currentCFrame = camera.CFrame
	local targetCFrame = CFrame.lookAt(cameraPosition, lookAtPosition)
	
	-- Apply smoothing
	local newCFrame = currentCFrame:Lerp(targetCFrame, CAMERA_SMOOTHING)
	camera.CFrame = newCFrame
end

-- Function to set up third-person camera zoom
local function setupThirdPersonCamera(character)
	local humanoidRootPart = character:FindFirstChild("HumanoidRootPart")
	local humanoid = character:FindFirstChild("Humanoid")
	if not humanoidRootPart or not humanoid then 
		warn("Missing HumanoidRootPart or Humanoid!")
		return 
	end

	print("Setting up third-person camera zoom...")

	-- Store original settings only if not already stored
	if not originalMaxZoomDistance then
		originalMaxZoomDistance = player.CameraMaxZoomDistance
	end
	if not originalMinZoomDistance then
		originalMinZoomDistance = player.CameraMinZoomDistance
	end
	if not originalCameraType then
		originalCameraType = camera.CameraType
	end
	if not originalCameraSubject then
		originalCameraSubject = camera.CameraSubject
	end

	print("Original zoom distances:", originalMinZoomDistance, "to", originalMaxZoomDistance)

	-- Use Custom camera type instead of Scriptable for better compatibility
	camera.CameraType = Enum.CameraType.Custom
	camera.CameraSubject = humanoid

	-- Set zoom distances to force third person
	player.CameraMaxZoomDistance = THIRD_PERSON_ZOOM
	player.CameraMinZoomDistance = THIRD_PERSON_ZOOM

	-- Set initial camera position
	local rootCFrame = humanoidRootPart.CFrame
	local rootPosition = rootCFrame.Position
	local backwardVector = -rootCFrame.LookVector
	local initialCameraPosition = rootPosition + (backwardVector * THIRD_PERSON_ZOOM) + Vector3.new(0, CAMERA_HEIGHT_OFFSET, 0)
	local lookAtPosition = rootPosition + Vector3.new(0, CAMERA_HEIGHT_OFFSET * 0.5, 0)
	
	camera.CFrame = CFrame.lookAt(initialCameraPosition, lookAtPosition)

	-- Set up continuous camera update to maintain third person view
	cameraUpdateConnection = RunService.Heartbeat:Connect(updateThirdPersonCamera)

	print("Third-person camera zoom active!")
end

-- Function to monitor medkit tool state
local function monitorMedkitTool(tool)
	if not tool then return end

	currentMedkitTool = tool

	-- Monitor if tool gets destroyed
	toolConnections.ancestryChanged = tool.AncestryChanged:Connect(function()
		task.wait(0.05)
		if not tool.Parent then
			print("Tool destroyed - stopping camera")
			stopMedkitCamera()
		elseif tool.Parent ~= player.Character then
			print("Tool unequipped - stopping camera")
			stopMedkitCamera()
		end
	end)

	-- Monitor tool unequipped event
	pcall(function()
		toolConnections.unequipped = tool.Unequipped:Connect(function()
			print("Tool unequipped event - stopping camera")
			task.wait(0.05)
			stopMedkitCamera()
		end)
	end)

	-- Failsafe monitoring
	toolConnections.failsafe = task.spawn(function()
		while isMedkitActive and currentMedkitTool == tool do
			task.wait(1)
			if not currentMedkitTool or not currentMedkitTool.Parent or currentMedkitTool.Parent ~= player.Character then
				print("Failsafe triggered - tool no longer equipped")
				stopMedkitCamera()
				break
			end
		end
	end)
end

-- Main medkit usage function
local function useMedkit(medkitTool)
	local character = player.Character
	if not character then 
		warn("Character not found!")
		return 
	end

	-- If already active with the same tool, ignore
	if isMedkitActive and currentMedkitTool == medkitTool then
		print("Medkit camera already active for this tool")
		return
	end

	-- Stop previous medkit camera if active
	if isMedkitActive then
		print("Stopping previous medkit camera...")
		stopMedkitCamera()
		task.wait(0.2)
	end

	print("Starting medkit camera zoom...")
	isMedkitActive = true

	-- Hide ViewModel
	hiddenViewModel = hideViewModel()

	-- Set up third-person camera
	setupThirdPersonCamera(character)

	-- Monitor the tool
	if medkitTool then
		monitorMedkitTool(medkitTool)
	else
		warn("No medkit tool provided - camera will stay active until manually stopped!")
	end

	print("Medkit camera zoom active!")
end

-- Global functions
_G.startMedkitCamera = useMedkit
_G.stopMedkitCamera = stopMedkitCamera

-- Emergency restore function
_G.forceRestoreCamera = function()
	print("=== EMERGENCY CAMERA RESTORE ===")
	
	-- Force stop everything
	isMedkitActive = false
	isRestoringCamera = false
	
	-- Disconnect all connections
	if cameraUpdateConnection then
		pcall(function() cameraUpdateConnection:Disconnect() end)
		cameraUpdateConnection = nil
	end
	if cameraConnection then
		pcall(function() cameraConnection:Disconnect() end)
		cameraConnection = nil
	end
	
	for name, connection in pairs(toolConnections) do
		if connection then
			pcall(function()
				if name == "failsafe" then
					task.cancel(connection)
				else
					connection:Disconnect()
				end
			end)
		end
	end
	toolConnections = {}
	
	-- Reset camera to default values
	camera.CameraType = Enum.CameraType.Custom
	player.CameraMaxZoomDistance = 400
	player.CameraMinZoomDistance = 0.5
	
	-- Set camera subject to player's humanoid
	local character = player.Character
	if character then
		local humanoid = character:FindFirstChild("Humanoid")
		if humanoid then
			camera.CameraSubject = humanoid
		end
	end
	
	-- Restore ViewModel
	showViewModel(hiddenViewModel)
	
	-- Clear all references
	originalMaxZoomDistance = nil
	originalMinZoomDistance = nil
	originalCameraType = nil
	originalCameraSubject = nil
	hiddenViewModel = nil
	currentMedkitTool = nil
	
	print("Emergency camera restore completed!")
end

-- Configuration functions for easier tweaking
_G.setThirdPersonDistance = function(distance)
	THIRD_PERSON_ZOOM = distance or 12
	print("Third person distance set to:", THIRD_PERSON_ZOOM)
end

_G.setCameraHeight = function(height)
	CAMERA_HEIGHT_OFFSET = height or 2
	print("Camera height offset set to:", CAMERA_HEIGHT_OFFSET)
end

_G.setCameraSmoothing = function(smoothing)
	CAMERA_SMOOTHING = math.clamp(smoothing or 0.1, 0.01, 1.0)
	print("Camera smoothing set to:", CAMERA_SMOOTHING)
end

-- Legacy function
_G.startMedkitCameraLegacy = function()
	useMedkit(nil)
	task.wait(3)
	stopMedkitCamera()
end

-- Testing controls
UserInputService.InputBegan:Connect(function(input, gameProcessed)
	if gameProcessed then return end

	-- Left click - test medkit camera
	if input.UserInputType == Enum.UserInputType.MouseButton1 then
		local fakeTool = Instance.new("Tool")
		fakeTool.Name = "TestMedkit"
		fakeTool.Parent = player.Character
		useMedkit(fakeTool)

		task.wait(5)
		fakeTool:Destroy()
	end

	-- Right click - manual restore
	if input.UserInputType == Enum.UserInputType.MouseButton2 then
		print("=== MANUAL RESTORE TEST ===")
		restoreFirstPersonCamera()
	end
	
	-- Middle click - emergency restore
	if input.UserInputType == Enum.UserInputType.MouseButton3 then
		_G.forceRestoreCamera()
	end
end)

-- Cleanup on character removal
player.CharacterRemoving:Connect(function()
	_G.forceRestoreCamera()
end) now it doesnt put the player back in first person, and it breaks my "LockFirstPerson" setting