"use server"; import { getDb } from "@/lib/mongodb"; import { getLoggedInUser } from "@/lib/actions/auth"; import type { PlatformApiKeyInput, UpdateUserCoinsAdminInput, UpdateUserRoleAdminInput } from "@/lib/schemas"; import type { User, Deployment } from "@/lib/types"; import { ObjectId } from "mongodb"; import { revalidatePath } from "next/cache"; const API_KEY_ID = "platformApiKey"; async function isAdmin(): Promise { const user = await getLoggedInUser(); return !!user && user.role === 'admin'; } export async function getPlatformApiKey(): Promise<{ success: boolean; apiKey?: string; message?: string }> { // Removed isAdmin() check here. Reading the system's API key for operational purposes // (like a deployment) should not require the current actor to be an admin. // The SETTING of the key (updatePlatformApiKey) IS correctly admin-gated. try { const db = await getDb(); const settingsCollection = db.collection("settings"); const apiKeyDoc = await settingsCollection.findOne({ _id: API_KEY_ID }); if (apiKeyDoc && apiKeyDoc.value && typeof apiKeyDoc.value === 'string' && apiKeyDoc.value.trim() !== "") { return { success: true, apiKey: apiKeyDoc.value }; } // If keyDoc doesn't exist, or value is null/empty, treat as not configured. return { success: true, apiKey: "" }; // Return empty string to indicate not set or empty } catch (error) { console.error("Error fetching platform API key:", error); return { success: false, message: "Failed to fetch API key." }; } } export async function updatePlatformApiKey(data: PlatformApiKeyInput): Promise<{ success: boolean; message: string }> { if (!(await isAdmin())) { return { success: false, message: "Unauthorized access." }; } try { const db = await getDb(); const settingsCollection = db.collection("settings"); await settingsCollection.updateOne( { _id: API_KEY_ID }, { $set: { value: data.apiKey } }, { upsert: true } ); revalidatePath("/admin/dashboard"); return { success: true, message: "Platform API Key updated successfully." }; } catch (error) { console.error("Error updating platform API key:", error); return { success: false, message: "Failed to update API key." }; } } export async function getAllUsersForAdmin(): Promise<{ success: boolean; users?: User[]; message?: string }> { if (!(await isAdmin())) { return { success: false, message: "Unauthorized access." }; } try { const db = await getDb(); const usersArray = await db.collection("users").find({}, { projection: { passwordHash: 0 } }).sort({createdAt: -1}).toArray(); const users: User[] = usersArray.map(u => ({ ...u, _id: u._id.toString(), lastCoinClaim: u.lastCoinClaim ? new Date(u.lastCoinClaim) : null, createdAt: u.createdAt ? new Date(u.createdAt) : new Date(0), })); return { success: true, users }; } catch (error) { console.error("Error fetching all users:", error); return { success: false, message: "Failed to fetch users." }; } } export async function updateUserRoleAdmin(data: UpdateUserRoleAdminInput): Promise<{ success: boolean; message: string }> { const adminUser = await getLoggedInUser(); if (!adminUser || adminUser.role !== 'admin') { return { success: false, message: "Unauthorized access." }; } if (adminUser._id === data.userId && data.newRole === 'user') { const dbCheck = await getDb(); const adminCount = await dbCheck.collection("users").countDocuments({ role: 'admin' }); if (adminCount <= 1) { return { success: false, message: "Cannot change the role of the only admin." }; } } try { const db = await getDb(); const usersCollection = db.collection("users"); const result = await usersCollection.updateOne( { _id: data.userId }, { $set: { role: data.newRole } } ); if (result.modifiedCount === 0) { return { success: false, message: "User not found or role already set to this value." }; } revalidatePath("/admin/dashboard"); revalidatePath("/admin/stats"); return { success: true, message: "User role updated successfully." }; } catch (error) { console.error("Error updating user role:", error); return { success: false, message: "Failed to update user role." }; } } export async function updateUserCoinsAdmin(data: UpdateUserCoinsAdminInput): Promise<{ success: boolean; message: string }> { if (!(await isAdmin())) { return { success: false, message: "Unauthorized access." }; } try { const db = await getDb(); const usersCollection = db.collection("users"); const result = await usersCollection.updateOne( { _id: data.userId }, { $inc: { coins: data.coinAdjustment } } ); if (result.modifiedCount === 0 && result.matchedCount === 0) { return { success: false, message: "User not found." }; } revalidatePath("/admin/dashboard"); revalidatePath("/admin/stats"); return { success: true, message: `User coins adjusted by ${data.coinAdjustment}.` }; } catch (error) { console.error("Error adjusting user coins:", error); return { success: false, message: "Failed to adjust user coins." }; } } export async function deleteUserAdmin(userId: string): Promise<{ success: boolean; message: string }> { if (!(await isAdmin())) { return { success: false, message: "Unauthorized access." }; } console.log(`Admin trying to delete user ${userId}`); return { success: false, message: "User deletion not yet implemented." }; } export async function getPlatformStats(): Promise<{ success: boolean; stats?: { totalUsers: number; totalDeployments: number; totalCoinsInSystem: number; }; message?: string; }> { if (!(await isAdmin())) { return { success: false, message: "Unauthorized access." }; } try { const db = await getDb(); const usersCollection = db.collection("users"); const deploymentsCollection = db.collection("deployments"); const totalUsers = await usersCollection.countDocuments(); const totalDeployments = await deploymentsCollection.countDocuments(); const coinAggregation = await usersCollection.aggregate([ { $group: { _id: null, totalCoins: { $sum: "$coins" } } } ]).toArray(); const totalCoinsInSystem = coinAggregation[0]?.totalCoins || 0; return { success: true, stats: { totalUsers, totalDeployments, totalCoinsInSystem }, }; } catch (error) { console.error("Error fetching platform stats:", error); return { success: false, message: "Failed to fetch platform statistics." }; } }