import { createClient } from "@supabase/supabase-js"; const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL!; const supabaseKey = process.env.SUPABASE_SERVICE_ROLE_KEY!; const supabase = createClient(supabaseUrl, supabaseKey); // Matt's user ID const MATT_USER_ID = "0a3e400c-3932-48ae-9b65-f3f9c6f26fe9"; const MAX_USER_ID = "9c29cc99-81a1-4e75-8dff-cd7cc5ceb5aa"; interface ParsedTask { title: string; description?: string; assigneeId: string; priority: "low" | "medium" | "high"; dueDate?: string; projectId?: string; } export function parseTaskInput(input: string): ParsedTask { const lower = input.toLowerCase(); // Extract assignee let assigneeId = MATT_USER_ID; if (lower.includes("assign to max") || lower.includes("for max")) { assigneeId = MAX_USER_ID; } // Extract priority let priority: "low" | "medium" | "high" = "medium"; if (lower.includes("urgent") || lower.includes("asap") || lower.includes("high priority")) { priority = "high"; } else if (lower.includes("low priority") || lower.includes("whenever") || lower.includes("eventually")) { priority = "low"; } // Extract due date phrases let dueDate: string | undefined; const today = new Date(); if (lower.includes("tomorrow")) { const d = new Date(today); d.setDate(d.getDate() + 1); dueDate = d.toISOString().split("T")[0]; } else if (lower.includes("next week")) { const d = new Date(today); d.setDate(d.getDate() + 7); dueDate = d.toISOString().split("T")[0]; } else if (lower.includes("by friday") || lower.includes("this friday")) { const d = new Date(today); const daysUntilFriday = (5 - d.getDay() + 7) % 7 || 7; d.setDate(d.getDate() + daysUntilFriday); dueDate = d.toISOString().split("T")[0]; } else if (lower.includes("by monday") || lower.includes("this monday")) { const d = new Date(today); const daysUntilMonday = (1 - d.getDay() + 7) % 7 || 7; d.setDate(d.getDate() + daysUntilMonday); dueDate = d.toISOString().split("T")[0]; } // Clean up the title - remove assignee/priority/due date phrases let title = input .replace(/assign to (max|matt)/gi, "") .replace(/for (max|matt)/gi, "") .replace(/urgent|asap|high priority|low priority/gi, "") .replace(/tomorrow|next week|by friday|this friday|by monday|this monday/gi, "") .replace(/\s+/g, " ") .trim(); // If it starts with "add task" or similar, remove that title = title.replace(/^(add|create|new)\s+(task|todo|item)\s*[:\-]?\s*/i, ""); // Capitalize first letter title = title.charAt(0).toUpperCase() + title.slice(1); return { title, assigneeId, priority, dueDate, }; } interface TaskResult { id: string; title: string; [key: string]: unknown; } export async function addTaskToGantt(input: string): Promise<{ success: boolean; task?: TaskResult; error?: string }> { try { const parsed = parseTaskInput(input); // Get default project (first one) or use a specific project const { data: projects } = await supabase .from("projects") .select("id") .order("created_at", { ascending: true }) .limit(1); const projectId = projects?.[0]?.id; if (!projectId) { return { success: false, error: "No projects found in gantt board" }; } // Create the task const { data: task, error } = await supabase .from("tasks") .insert({ title: parsed.title, description: parsed.description || null, status: "todo", priority: parsed.priority, assignee_id: parsed.assigneeId, created_by: MATT_USER_ID, project_id: projectId, due_date: parsed.dueDate || null, start_date: new Date().toISOString().split("T")[0], end_date: parsed.dueDate || new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split("T")[0], }) .select() .single(); if (error) { console.error("Error adding task:", error); return { success: false, error: error.message }; } return { success: true, task }; } catch (err: unknown) { console.error("Failed to add task:", err); const message = err instanceof Error ? err.message : "Unknown error"; return { success: false, error: message }; } }