import { query, queryOne, run } from "@/lib/db"; import { cookies } from "next/headers"; import { verifyToken } from "@/app/api/auth/[...nextauth]/route"; export const dynamic = "force-dynamic"; // Disable caching // Helper function to ensure the hunt_timer table exists async function ensureTableExists() { try { // Directly try to create the table (IF NOT EXISTS prevents errors if it already exists) await run(` CREATE TABLE IF NOT EXISTS hunt_timer ( id INTEGER PRIMARY KEY AUTOINCREMENT, active INTEGER NOT NULL DEFAULT 0, start_time TEXT NOT NULL, end_time TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `); // Verify the table exists by inserting a dummy record and then deleting it // This is a more reliable way to test if the table is usable const tempTimestamp = new Date().toISOString(); const tempId = await run( "INSERT INTO hunt_timer (active, start_time) VALUES (0, ?)", [tempTimestamp] ); if (tempId) { // Delete the test record await run("DELETE FROM hunt_timer WHERE id = ?", [tempId]); } console.log("hunt_timer table verified successfully"); return true; } catch (error) { console.error("Error ensuring hunt_timer table:", error); // Try with an alternative approach if the first method failed try { console.log("Attempting alternative table creation method..."); // Execute the CREATE TABLE statement directly await run(` DROP TABLE IF EXISTS hunt_timer; CREATE TABLE hunt_timer ( id INTEGER PRIMARY KEY AUTOINCREMENT, active INTEGER NOT NULL DEFAULT 0, start_time TEXT NOT NULL, end_time TEXT, created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ) `); console.log("hunt_timer table created with alternative method"); return true; } catch (createError) { console.error("Failed to create hunt_timer table:", createError); return false; } } } // Helper function to ensure settings table exists and manage hunt active status async function ensureSettingsTableExists() { try { // Create settings table if it doesn't exist await run(` CREATE TABLE IF NOT EXISTS settings ( key TEXT PRIMARY KEY, value TEXT NOT NULL ) `); // Check if hunt_active setting exists const huntActiveSetting = await queryOne( "SELECT value FROM settings WHERE key = 'hunt_active'" ); // If not, create it with default value "false" if (!huntActiveSetting) { await run("INSERT OR IGNORE INTO settings (key, value) VALUES (?, ?)", [ "hunt_active", "false", ]); } return true; } catch (error) { console.error("Error ensuring settings table:", error); return false; } } // Helper function to update hunt active status async function updateHuntActiveStatus(isActive) { try { await ensureSettingsTableExists(); await run("INSERT OR REPLACE INTO settings (key, value) VALUES (?, ?)", [ "hunt_active", isActive ? "true" : "false", ]); console.log("Hunt active status updated:", isActive); return true; } catch (error) { console.error("Failed to update hunt active status:", error); return false; } } // GET endpoint to get current timer status export async function GET(request) { try { // Verify the user is authenticated const cookieStore = await cookies(); // Add await here const sessionToken = cookieStore.get("next-auth.session-token")?.value; if (!sessionToken) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } const userData = verifyToken(sessionToken); if (!userData) { return Response.json({ error: "Invalid session" }, { status: 401 }); } // Ensure both tables exist const tableExists = await ensureTableExists(); await ensureSettingsTableExists(); if (!tableExists) { return Response.json( { error: "Database table not found" }, { status: 500 } ); } // Get the current hunt timer status const timerStatus = await queryOne( "SELECT active, start_time, end_time FROM hunt_timer ORDER BY id DESC LIMIT 1" ); // Get the hunt active status from settings const huntActiveSetting = await queryOne( "SELECT value FROM settings WHERE key = 'hunt_active'" ); const huntActive = huntActiveSetting ? huntActiveSetting.value === "true" : false; if (!timerStatus) { return Response.json({ active: huntActive, // Use settings value if timer not found startTime: null, endTime: null, }); } return Response.json({ active: huntActive, // Return settings value for consistency timerActive: !!timerStatus.active, // Also return timer status for admin panel startTime: timerStatus.start_time, endTime: timerStatus.end_time, }); } catch (error) { console.error("Error getting timer status:", error); return Response.json( { error: "Failed to get timer status" }, { status: 500 } ); } } // POST endpoint to start/stop timer export async function POST(request) { try { // Verify the user is authenticated and is an admin const cookieStore = await cookies(); // Add await here const sessionToken = cookieStore.get("next-auth.session-token")?.value; if (!sessionToken) { return Response.json({ error: "Unauthorized" }, { status: 401 }); } const userData = verifyToken(sessionToken); if (!userData) { return Response.json({ error: "Invalid session" }, { status: 401 }); } console.log("User role:", userData.role); // Check if user is admin (more lenient check) if ( !( userData.role === "admin" || userData.isAdmin === true || userData.is_admin === 1 ) ) { return Response.json( { error: "Unauthorized: Admin access required" }, { status: 403 } ); } // Create required tables if they don't exist const tableExists = await ensureTableExists(); await ensureSettingsTableExists(); if (!tableExists) { return Response.json( { error: "Failed to create hunt_timer database table" }, { status: 500 } ); } const body = await request.json(); const { action, endTime } = body; console.log("Timer action:", action, "End time:", endTime); if (action === "start") { try { // Get current time in ISO format const startTime = new Date().toISOString(); // First, deactivate any existing timers await run("UPDATE hunt_timer SET active = 0 WHERE active = 1"); // Insert new timer record await run( "INSERT INTO hunt_timer (active, start_time, end_time) VALUES (?, ?, ?)", [1, startTime, endTime || null] ); // Update hunt active status to true await updateHuntActiveStatus(true); return Response.json({ success: true, message: "Timer started successfully", startTime, endTime: endTime || null, }); } catch (dbError) { console.error("Database error starting timer:", dbError); return Response.json( { error: "Database error: " + dbError.message }, { status: 500 } ); } } else if (action === "stop") { try { // Update the most recent timer to inactive await run( "UPDATE hunt_timer SET active = 0, end_time = ? WHERE active = 1", [new Date().toISOString()] ); // Update hunt active status to false await updateHuntActiveStatus(false); return Response.json({ success: true, message: "Timer stopped successfully", }); } catch (dbError) { console.error("Database error stopping timer:", dbError); return Response.json( { error: "Database error: " + dbError.message }, { status: 500 } ); } } else { return Response.json( { error: "Invalid action. Use 'start' or 'stop'." }, { status: 400 } ); } } catch (error) { console.error("Error managing timer:", error); return Response.json( { error: "Failed to manage timer: " + error.message, }, { status: 500 } ); } }