export interface ScriptTemplate {
  id: string;
  name: string;
  description: string;
  code: string;
  category: 'beginner' | 'gameplay' | 'ui' | 'tools' | 'advanced';
}

export const templates: ScriptTemplate[] = [
  {
    id: 'hello-world',
    name: 'Hello World',
    description: 'Basic print statement to test scripts',
    category: 'beginner',
    code: `-- Hello World Script
print("Hello from Roblox!")

local message = "Welcome to scripting!"
print(message)`,
  },
  {
    id: 'player-join',
    name: 'Player Join Handler',
    description: 'Detect when players join and leave the game',
    category: 'beginner',
    code: `local Players = game:GetService("Players")

Players.PlayerAdded:Connect(function(player)
    print(player.Name .. " joined the game!")
    
    -- Create leaderstats folder
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player
    
    -- Add coins value
    local coins = Instance.new("IntValue")
    coins.Name = "Coins"
    coins.Value = 0
    coins.Parent = leaderstats
end)

Players.PlayerRemoving:Connect(function(player)
    print(player.Name .. " left the game!")
end)`,
  },
  {
    id: 'part-touch',
    name: 'Part Touch Detector',
    description: 'Detect when a player touches a part',
    category: 'gameplay',
    code: `local part = script.Parent

part.Touched:Connect(function(hit)
    local humanoid = hit.Parent:FindFirstChild("Humanoid")
    
    if humanoid then
        local player = game.Players:GetPlayerFromCharacter(hit.Parent)
        
        if player then
            print(player.Name .. " touched the part!")
            -- Do something here
        end
    end
end)`,
  },
  {
    id: 'teleport-part',
    name: 'Teleport Part',
    description: 'Teleport players when they touch a part',
    category: 'gameplay',
    code: `local part = script.Parent
local destination = Vector3.new(0, 10, 0) -- Change this to your destination

part.Touched:Connect(function(hit)
    local humanoid = hit.Parent:FindFirstChild("Humanoid")
    
    if humanoid then
        local rootPart = hit.Parent:FindFirstChild("HumanoidRootPart")
        
        if rootPart then
            rootPart.CFrame = CFrame.new(destination)
            print("Teleported " .. hit.Parent.Name)
        end
    end
end)`,
  },
  {
    id: 'gui-button',
    name: 'GUI Button Click',
    description: 'Handle button clicks in a GUI',
    category: 'ui',
    code: `local button = script.Parent

button.MouseButton1Click:Connect(function()
    print("Button clicked!")
    
    -- Add button feedback
    button.BackgroundColor3 = Color3.fromRGB(0, 255, 0)
    wait(0.1)
    button.BackgroundColor3 = Color3.fromRGB(255, 255, 255)
end)`,
  },
  {
    id: 'give-tool',
    name: 'Give Tool to Player',
    description: 'Give a tool to players when they join',
    category: 'tools',
    code: `local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

local toolName = "YourToolName" -- Change this to your tool name

Players.PlayerAdded:Connect(function(player)
    player.CharacterAdded:Connect(function(character)
        wait(1) -- Wait for character to load
        
        local tool = ReplicatedStorage:FindFirstChild(toolName)
        
        if tool then
            local toolClone = tool:Clone()
            toolClone.Parent = player.Backpack
            print("Gave " .. toolName .. " to " .. player.Name)
        end
    end)
end)`,
  },
  {
    id: 'tween-part',
    name: 'Tween Part Animation',
    description: 'Smoothly animate a part using TweenService',
    category: 'gameplay',
    code: `local TweenService = game:GetService("TweenService")
local part = script.Parent

local tweenInfo = TweenInfo.new(
    2, -- Duration
    Enum.EasingStyle.Quad,
    Enum.EasingDirection.InOut,
    -1, -- Repeat count (-1 = infinite)
    true, -- Reverse
    0 -- Delay
)

local goal = {
    Position = part.Position + Vector3.new(0, 5, 0)
}

local tween = TweenService:Create(part, tweenInfo, goal)
tween:Play()`,
  },
  {
    id: 'datastore',
    name: 'DataStore Save/Load',
    description: 'Save and load player data using DataStore',
    category: 'gameplay',
    code: `local DataStoreService = game:GetService("DataStoreService")
local Players = game:GetService("Players")

local playerDataStore = DataStoreService:GetDataStore("PlayerData")

Players.PlayerAdded:Connect(function(player)
    local userId = "Player_" .. player.UserId
    
    local data
    local success, errorMsg = pcall(function()
        data = playerDataStore:GetAsync(userId)
    end)
    
    if success then
        if data then
            print("Loaded data for " .. player.Name)
            -- Use the data here
        else
            print("New player: " .. player.Name)
        end
    else
        warn("Error loading data: " .. errorMsg)
    end
end)

Players.PlayerRemoving:Connect(function(player)
    local userId = "Player_" .. player.UserId
    local data = {
        coins = 100, -- Replace with actual data
        level = 5
    }
    
    local success, errorMsg = pcall(function()
        playerDataStore:SetAsync(userId, data)
    end)
    
    if success then
        print("Saved data for " .. player.Name)
    else
        warn("Error saving data: " .. errorMsg)
    end
end)`,
  },
  {
    id: 'proximity-prompt',
    name: 'Proximity Prompt Interaction',
    description: 'Interactive prompt that appears when player is near',
    category: 'ui',
    code: `local part = script.Parent
local ProximityPromptService = game:GetService("ProximityPromptService")

-- Create proximity prompt
local prompt = Instance.new("ProximityPrompt")
prompt.ObjectText = "Treasure Chest"
prompt.ActionText = "Open"
prompt.MaxActivationDistance = 10
prompt.Parent = part

prompt.Triggered:Connect(function(player)
    print(player.Name .. " opened the chest!")

    -- Add your interaction logic here
    part.BrickColor = BrickColor.new("Bright green")

    -- Disable for a cooldown
    prompt.Enabled = false
    wait(5)
    prompt.Enabled = true
    part.BrickColor = BrickColor.new("Bright yellow")
end)`,
  },
  {
    id: 'round-system',
    name: 'Round System',
    description: 'Complete round-based game loop system',
    category: 'advanced',
    code: `local ReplicatedStorage = game:GetService("ReplicatedStorage")
local Players = game:GetService("Players")

local roundLength = 60
local intermissionLength = 10
local minimumPlayers = 2

local status = ReplicatedStorage:WaitForChild("Status")

while true do
    -- Intermission
    repeat
        status.Value = "Waiting for " .. minimumPlayers .. " players..."
        wait(1)
    until #Players:GetPlayers() >= minimumPlayers

    status.Value = "Intermission"
    wait(intermissionLength)

    -- Round start
    status.Value = "Game starting..."
    wait(2)

    -- Game round
    for i = roundLength, 0, -1 do
        status.Value = "Round: " .. i .. " seconds remaining"
        wait(1)
    end

    status.Value = "Round ended!"
    wait(3)
end`,
  },
  {
    id: 'leaderstats-advanced',
    name: 'Advanced Leaderstats with XP',
    description: 'Complete leaderstats system with coins, XP, and level',
    category: 'gameplay',
    code: `local Players = game:GetService("Players")

local function calculateLevel(xp)
    return math.floor(xp / 100) + 1
end

Players.PlayerAdded:Connect(function(player)
    local leaderstats = Instance.new("Folder")
    leaderstats.Name = "leaderstats"
    leaderstats.Parent = player

    local coins = Instance.new("IntValue")
    coins.Name = "Coins"
    coins.Value = 0
    coins.Parent = leaderstats

    local level = Instance.new("IntValue")
    level.Name = "Level"
    level.Value = 1
    level.Parent = leaderstats

    local xp = Instance.new("IntValue")
    xp.Name = "XP"
    xp.Value = 0
    xp.Parent = player

    -- Update level when XP changes
    xp.Changed:Connect(function(newXP)
        level.Value = calculateLevel(newXP)
    end)

    -- Example: Award XP every 10 seconds
    spawn(function()
        while player.Parent do
            wait(10)
            xp.Value = xp.Value + 10
            coins.Value = coins.Value + 5
        end
    end)
end)`,
  },
  {
    id: 'shop-system',
    name: 'Shop System',
    description: 'Basic shop system with purchase handling',
    category: 'gameplay',
    code: `local Players = game:GetService("Players")
local ReplicatedStorage = game:GetService("ReplicatedStorage")

-- Shop items configuration
local shopItems = {
    SpeedBoost = {
        price = 100,
        name = "Speed Boost",
        duration = 30
    },
    DoubleJump = {
        price = 250,
        name = "Double Jump Power",
        duration = 60
    }
}

-- Purchase handler (put in ServerScriptService)
local function purchaseItem(player, itemName)
    local item = shopItems[itemName]

    if not item then
        return false, "Item not found"
    end

    local leaderstats = player:FindFirstChild("leaderstats")
    local coins = leaderstats and leaderstats:FindFirstChild("Coins")

    if not coins then
        return false, "Player data not loaded"
    end

    if coins.Value < item.price then
        return false, "Not enough coins"
    end

    -- Deduct coins
    coins.Value = coins.Value - item.price

    -- Grant item effect
    if itemName == "SpeedBoost" then
        local character = player.Character
        if character then
            local humanoid = character:FindFirstChild("Humanoid")
            if humanoid then
                humanoid.WalkSpeed = humanoid.WalkSpeed * 2
                task.wait(item.duration)
                humanoid.WalkSpeed = humanoid.WalkSpeed / 2
            end
        end
    end

    return true, "Purchased " .. item.name
end

-- Example usage:
-- local success, message = purchaseItem(player, "SpeedBoost")`,
  },
  {
    id: 'camera-manipulation',
    name: 'Camera Manipulation',
    description: 'Custom camera angles and cinematic views',
    category: 'advanced',
    code: `local Players = game:GetService("Players")
local RunService = game:GetService("RunService")

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

-- Set camera mode
camera.CameraType = Enum.CameraType.Scriptable

-- Example 1: Fixed camera position
local function setFixedCamera(position, lookAt)
    camera.CFrame = CFrame.new(position, lookAt)
end

-- Example 2: Follow a part
local targetPart = workspace:WaitForChild("CameraTarget")

RunService.RenderStepped:Connect(function()
    if targetPart then
        local offset = Vector3.new(0, 10, 20)
        camera.CFrame = CFrame.new(targetPart.Position + offset, targetPart.Position)
    end
end)

-- Example 3: Cinematic orbit
local angle = 0
local radius = 30
local center = Vector3.new(0, 10, 0)

RunService.RenderStepped:Connect(function(delta)
    angle = angle + delta * 0.5
    local x = math.cos(angle) * radius
    local z = math.sin(angle) * radius
    local position = center + Vector3.new(x, 15, z)
    camera.CFrame = CFrame.new(position, center)
end)`,
  },
  {
    id: 'combat-system',
    name: 'Basic Combat System',
    description: 'Simple damage and health system',
    category: 'gameplay',
    code: `local tool = script.Parent
local damage = 10
local cooldown = 1
local canAttack = true

tool.Activated:Connect(function()
    if not canAttack then return end

    canAttack = false
    local player = tool.Parent.Parent
    local character = player.Character or player.CharacterAdded:Wait()
    local humanoid = character:FindFirstChild("Humanoid")

    if humanoid then
        -- Play attack animation
        local animation = Instance.new("Animation")
        animation.AnimationId = "rbxassetid://YOUR_ANIMATION_ID"
        local animTrack = humanoid:LoadAnimation(animation)
        animTrack:Play()

        -- Detect hit
        local handle = tool:FindFirstChild("Handle")
        if handle then
            local hitPart = nil
            local connection

            connection = handle.Touched:Connect(function(hit)
                if hit.Parent ~= character then
                    local enemyHumanoid = hit.Parent:FindFirstChild("Humanoid")
                    if enemyHumanoid then
                        enemyHumanoid:TakeDamage(damage)
                        print("Dealt " .. damage .. " damage!")
                        connection:Disconnect()
                    end
                end
            end)

            wait(0.5) -- Attack window
            connection:Disconnect()
        end
    end

    wait(cooldown)
    canAttack = true
end)`,
  },
  {
    id: 'admin-commands',
    name: 'Basic Admin Commands',
    description: 'Simple admin command system with permissions',
    category: 'tools',
    code: `local Players = game:GetService("Players")

local admins = {
    123456789, -- Replace with actual UserIds
    987654321,
}

local commands = {
    ["kill"] = function(admin, targetName)
        local target = Players:FindFirstChild(targetName)
        if target and target.Character then
            target.Character.Humanoid.Health = 0
            return true, "Killed " .. targetName
        end
        return false, "Player not found"
    end,

    ["tp"] = function(admin, targetName)
        local target = Players:FindFirstChild(targetName)
        if target and target.Character and admin.Character then
            admin.Character.HumanoidRootPart.CFrame =
                target.Character.HumanoidRootPart.CFrame
            return true, "Teleported to " .. targetName
        end
        return false, "Cannot teleport"
    end,

    ["heal"] = function(admin, targetName)
        local target = Players:FindFirstChild(targetName)
        if target and target.Character then
            target.Character.Humanoid.Health =
                target.Character.Humanoid.MaxHealth
            return true, "Healed " .. targetName
        end
        return false, "Player not found"
    end,
}

local function isAdmin(player)
    return table.find(admins, player.UserId) ~= nil
end

Players.PlayerAdded:Connect(function(player)
    if isAdmin(player) then
        print(player.Name .. " is an admin!")

        player.Chatted:Connect(function(message)
            local args = string.split(message, " ")
            local cmd = string.lower(args[1])

            if commands[cmd] then
                local success, result = commands[cmd](player, args[2])
                print(result)
            end
        end)
    end
end)`,
  },
];
