company_id !== 1 || $request->role !== 'admin') { $response->status(403)->json(['error' => 'Forbidden: Super Admin privileges required.']); return false; } return true; } /** * Get platform statistics and companies list * GET /api/admin/stats */ public function getStats(Request $request, Response $response): void { if (!$this->verifySuperAdmin($request, $response)) { return; } try { // Overall stats $companiesCount = Database::selectOne("SELECT COUNT(*) as count FROM companies")['count'] ?? 0; $sessionsCount = Database::selectOne("SELECT COUNT(*) as count FROM whatsapp_sessions")['count'] ?? 0; $connectedSessions = Database::selectOne("SELECT COUNT(*) as count FROM whatsapp_sessions WHERE status = 'connected'")['count'] ?? 0; // Detailed list of all companies and their current subscriptions $companies = Database::select(" SELECT c.id, c.name, c.status, cs.plan_id, sp.name as plan_name, cs.status as subscription_status, cs.starts_at as subscription_starts, cs.ends_at as subscription_ends, (SELECT COUNT(*) FROM whatsapp_sessions WHERE company_id = c.id) as sessions_count, (SELECT COUNT(*) FROM whatsapp_sessions WHERE company_id = c.id AND status = 'connected') as active_sessions, COALESCE(cu.request_count, 0) as request_usage, COALESCE(cu.voice_count, 0) as voice_usage, COALESCE(cu.ocr_count, 0) as ocr_usage FROM companies c LEFT JOIN company_subscriptions cs ON cs.company_id = c.id AND cs.status = 'active' LEFT JOIN subscription_plans sp ON cs.plan_id = sp.id LEFT JOIN company_subscription_usage cu ON cu.company_id = c.id AND cu.billing_start <= CURRENT_DATE() AND cu.billing_end >= CURRENT_DATE() ORDER BY c.id ASC "); // Fetch list of available subscription plans $plans = Database::select("SELECT id, name, price, max_sessions FROM subscription_plans ORDER BY price ASC"); $response->json([ 'status' => 'success', 'data' => [ 'stats' => [ 'total_companies' => (int)$companiesCount, 'total_sessions' => (int)$sessionsCount, 'connected_sessions' => (int)$connectedSessions ], 'companies' => $companies, 'plans' => $plans ] ]); } catch (\Exception $e) { error_log("[SuperAdminController Error] " . $e->getMessage()); $response->status(500)->json(['error' => 'Failed to fetch platform stats: ' . $e->getMessage()]); } } /** * Subscribe or upgrade a company to a plan * POST /api/admin/companies/subscribe */ public function subscribeCompany(Request $request, Response $response): void { if (!$this->verifySuperAdmin($request, $response)) { return; } $body = $request->getBody(); $targetCompanyId = isset($body['company_id']) ? (int)$body['company_id'] : null; $planId = isset($body['plan_id']) ? (int)$body['plan_id'] : null; $durationDays = isset($body['duration_days']) ? (int)$body['duration_days'] : 30; if (!$targetCompanyId || !$planId) { $response->status(400)->json(['error' => 'Missing company_id or plan_id']); return; } // Verify company exists $companyExists = Database::selectOne("SELECT id FROM companies WHERE id = ?", [$targetCompanyId]); if (!$companyExists) { $response->status(404)->json(['error' => 'Company not found']); return; } // Verify plan exists $planExists = Database::selectOne("SELECT id FROM subscription_plans WHERE id = ?", [$planId]); if (!$planExists) { $response->status(404)->json(['error' => 'Subscription plan not found']); return; } try { // Subscribe the company $subId = CompanySubscription::subscribeCompany($targetCompanyId, $planId, $durationDays, 'manual_admin', 'admin_' . $request->user_id); // Clean active subscription cache for the company if (class_exists('App\Core\Cache')) { \App\Core\Cache::delete("company_subscription:{$targetCompanyId}"); \App\Core\Cache::delete("company_subscription_{$targetCompanyId}"); } $response->json([ 'status' => 'success', 'message' => 'Subscription updated successfully', 'subscription_id' => $subId ]); } catch (\Exception $e) { error_log("[SuperAdminController Error] " . $e->getMessage()); $response->status(500)->json(['error' => 'Failed to update subscription: ' . $e->getMessage()]); } } }