'Sessie ID ontbreekt']); exit; } $stmtSession = $db->prepare("SELECT * FROM brainstorm_sessions WHERE id = ?"); $stmtSession->execute([$sessionId]); $session = $stmtSession->fetch(); if (!$session) { echo json_encode(['error' => 'Sessie niet gevonden']); exit; } $stmtCards = $db->prepare("SELECT id, content, category FROM brainstorm_cards WHERE session_id = ?"); $stmtCards->execute([$sessionId]); $cards = $stmtCards->fetchAll(); if (empty($cards)) { echo json_encode(['error' => 'Er zijn nog geen kaartjes op het canvas om te categoriseren']); exit; } $aiRes = fociz_ai_categorize_cards($session['title'], $session['theme'] ?? 'Algemeen', $cards); if (!$aiRes['success']) { echo json_encode(['error' => $aiRes['error']]); exit; } $validCategories = ['Ideeën', 'Knelpunten', 'Oplossingen', 'Quick Wins']; $updateStmt = $db->prepare("UPDATE brainstorm_cards SET category = ? WHERE id = ? AND session_id = ?"); $updatedCount = 0; foreach ($aiRes['categorized'] as $item) { $cardId = (int)($item['id'] ?? 0); $newCat = trim($item['category'] ?? ''); if ($cardId > 0 && in_array($newCat, $validCategories)) { $updateStmt->execute([$newCat, $cardId, $sessionId]); $updatedCount++; } } echo json_encode(['success' => true, 'updated' => $updatedCount]); exit; } // 2. Automatisch ideeën genereren voor een sessie if ($action === 'generate_ideas') { $data = json_decode(file_get_contents('php://input'), true); $sessionId = (int)($data['session_id'] ?? 0); $count = min(6, max(2, (int)($data['count'] ?? 4))); if (!$sessionId) { echo json_encode(['error' => 'Sessie ID ontbreekt']); exit; } $stmtSession = $db->prepare("SELECT * FROM brainstorm_sessions WHERE id = ?"); $stmtSession->execute([$sessionId]); $session = $stmtSession->fetch(); if (!$session) { echo json_encode(['error' => 'Sessie niet gevonden']); exit; } $aiRes = fociz_ai_generate_ideas($session['title'], $session['theme'] ?? 'Algemeen', $count); if (!$aiRes['success']) { echo json_encode(['error' => $aiRes['error']]); exit; } $insertStmt = $db->prepare(" INSERT INTO brainstorm_cards (session_id, content, category, color, author_name, votes) VALUES (?, ?, 'Ideeën', 'amber', ?, 1) "); $createdCards = []; $authorName = 'AI Co-Pilot'; foreach ($aiRes['ideas'] as $ideaText) { $ideaText = trim($ideaText); if (!empty($ideaText)) { $insertStmt->execute([$sessionId, $ideaText, $authorName]); $createdCards[] = [ 'id' => (int)$db->lastInsertId(), 'content' => $ideaText, 'category' => 'Ideeën', 'color' => 'amber', 'author_name' => $authorName, 'votes' => 1, ]; } } echo json_encode(['success' => true, 'cards' => $createdCards]); exit; } // 3. Brainstorm notitie omzetten naar Roadmap Item if ($action === 'summarize_to_roadmap') { $data = json_decode(file_get_contents('php://input'), true); $content = trim($data['content'] ?? ''); $sessionTitle = trim($data['session_title'] ?? ''); if (empty($content)) { echo json_encode(['error' => 'Geen inhoud opgegeven om samen te vatten']); exit; } $aiRes = fociz_ai_summarize_to_roadmap($content, $sessionTitle); if (!$aiRes['success']) { echo json_encode(['error' => $aiRes['error']]); exit; } echo json_encode(['success' => true, 'item' => $aiRes['item']]); exit; } // 4. Slimme dagindeling berekenen voor taken rondom Outlook afspraken if ($action === 'smart_schedule') { $data = json_decode(file_get_contents('php://input'), true); $date = !empty($data['date']) ? trim($data['date']) : date('Y-m-d'); // Haal daily plan op $stmtPlan = $db->prepare("SELECT id FROM daily_plans WHERE user_id = ? AND plan_date = ?"); $stmtPlan->execute([$user['id'], $date]); $plan = $stmtPlan->fetch(); $planId = $plan['id'] ?? 0; // Haal openstaande taken op voor de dag (inclusief fallback voor ongebonden taken op de huidige dag) $isToday = ($date === date('Y-m-d')); $stmtTasks = $db->prepare(" SELECT t.id, t.title, t.priority, t.duration_minutes FROM tasks t WHERE t.user_id = ? AND (t.daily_plan_id = ? " . ($isToday ? "OR t.daily_plan_id IS NULL" : "") . ") AND t.is_completed = 0 ORDER BY t.priority ASC, t.created_at ASC "); $stmtTasks->execute([$user['id'], $planId]); $tasks = $stmtTasks->fetchAll(); if (empty($tasks)) { echo json_encode(['error' => 'Geen openstaande taken gevonden om in te delen']); exit; } require_once __DIR__ . '/../includes/integrations/microsoft.php'; $events = microsoft_fetch_today_events($user['id'], $date); $workdaySettings = get_workday_settings(); $aiRes = fociz_ai_smart_schedule($tasks, $events, $workdaySettings); if (!$aiRes['success']) { echo json_encode(['error' => $aiRes['error']]); exit; } // Werk de tijdsblokken bij in MariaDB $updateStmt = $db->prepare(" UPDATE tasks SET time_block_start = ?, duration_minutes = COALESCE(?, duration_minutes) WHERE id = ? AND user_id = ? "); $scheduledCount = 0; foreach ($aiRes['scheduled'] as $s) { $taskId = (int)($s['id'] ?? 0); $startTime = trim($s['time_block_start'] ?? ''); $duration = !empty($s['duration_minutes']) ? (int)$s['duration_minutes'] : null; if ($taskId > 0 && preg_match('/^\d{1,2}:\d{2}$/', $startTime)) { $updateStmt->execute([$startTime, $duration, $taskId, $user['id']]); $scheduledCount++; } } echo json_encode(['success' => true, 'scheduled_count' => $scheduledCount]); exit; } // 5. Persoonlijke AI Dagbriefing genereren if ($action === 'daily_briefing') { $data = json_decode(file_get_contents('php://input'), true); $date = !empty($data['date']) ? trim($data['date']) : date('Y-m-d'); $today = date('Y-m-d'); // Haal openstaande taken van vandaag op $stmtPlan = $db->prepare("SELECT id FROM daily_plans WHERE user_id = ? AND plan_date = ?"); $stmtPlan->execute([$user['id'], $date]); $planId = $stmtPlan->fetchColumn(); $isToday = ($date === $today); $taskFilter = $planId ? "t.daily_plan_id = " . (int)$planId . ($isToday ? " OR t.daily_plan_id IS NULL" : "") : ($isToday ? "t.daily_plan_id IS NULL" : "1=0"); $tasks = $db->query(" SELECT id, title, priority, time_block_start, duration_minutes FROM tasks WHERE user_id = {$user['id']} AND is_completed = 0 AND ({$taskFilter}) ORDER BY priority ASC, time_block_start ASC LIMIT 15 ")->fetchAll(); // Haal gisteren niet-voltooide taken op $yesterday = date('Y-m-d', strtotime('-1 day', strtotime($date))); $stmtYest = $db->prepare("SELECT id FROM daily_plans WHERE user_id = ? AND plan_date = ?"); $stmtYest->execute([$user['id'], $yesterday]); $yesterdayPlanId = $stmtYest->fetchColumn(); $unfinishedYest = []; if ($yesterdayPlanId) { $stmtUnf = $db->prepare(" SELECT title FROM tasks WHERE user_id = ? AND daily_plan_id = ? AND is_completed = 0 LIMIT 5 "); $stmtUnf->execute([$user['id'], $yesterdayPlanId]); $unfinishedYest = $stmtUnf->fetchAll(); } // Haal Outlook meetings op als beschikbaar $meetings = []; try { require_once __DIR__ . '/../includes/integrations/microsoft.php'; $meetings = microsoft_fetch_today_events($user['id'], $date); } catch (Throwable $e) { // meetings niet beschikbaar, geen probleem } // Haal urgente Jira tickets op als beschikbaar $jiraIssues = []; try { require_once __DIR__ . '/../includes/integrations/jira.php'; $jiraData = jira_get_dashboard_data($user['id'], false); $jiraIssues = array_merge( $jiraData['assigned_issues'] ?? [], $jiraData['team_issues'] ?? [] ); } catch (Throwable $e) { // Jira niet beschikbaar, geen probleem } $aiSettings = get_ai_settings(); if (empty($aiSettings['ai_enabled']) || empty($aiSettings['has_key'])) { echo json_encode(['error' => 'AI Co-Pilot is niet geconfigureerd']); exit; } $aiRes = fociz_ai_daily_briefing( $user['name'] ?? 'Jij', $date, $tasks, $meetings, $jiraIssues, $unfinishedYest ); if (!$aiRes['success']) { echo json_encode(['error' => $aiRes['error']]); exit; } echo json_encode([ 'success' => true, 'greeting' => $aiRes['greeting'], 'focus_task' => $aiRes['focus_task'], 'tip' => $aiRes['tip'], 'warnings' => $aiRes['warnings'], 'date' => $date, ]); exit; } echo json_encode(['error' => 'Onbekende actie']); } catch (Exception $e) { http_response_code(500); echo json_encode(['error' => $e->getMessage()]); }