$this->systemConfig->all(), 'groups' => $this->systemConfig->grouped(), 'is_down' => $this->maintenanceService->isDown(), 'ai_models' => AiService::getSupportedModels(), ]); } public function update(UpdateSystemConfigRequest $request) { $this->systemConfig->update( input: $request->validated(), files: $request->allFiles(), actorId: $request->user()?->id, request: $request, ); // ✍️ Log "Action Log" bulk update activity('system-config') ->causedBy($request->user()) ->withProperties([ 'ip' => $request->ip(), 'agent' => $request->userAgent(), 'details' => __('Bulk system configuration update performed.'), ]) ->log(__('Updated System Settings')); // Only sync maintenance state if maintenance fields were part of the request $maintenanceKeys = [ 'maintenance_mode_enabled', 'maintenance_mode_secret', 'maintenance_mode_allowed_ips', 'maintenance_mode_end_at', ]; if ($request->hasAny($maintenanceKeys)) { $this->maintenanceService->syncState(); } if ($request->expectsJson()) { return response()->json([ 'success' => true, 'message' => __('Configuration updated successfully!'), 'settings' => $this->systemConfig->all(true), 'is_down' => $this->maintenanceService->isDown(), ]); } return back()->with('success', __('Configuration updated successfully!')); } public function testEmail(Request $request): JsonResponse { $to = $request->input('to') ?: $this->systemConfig->get('mail_from_address'); if (! $to || ! filter_var($to, FILTER_VALIDATE_EMAIL)) { return response()->json(['success' => false, 'message' => __('No valid recipient email address. Please enter a valid email.')], 422); } try { Mail::raw( __('This automated message confirms that the SMTP configuration for :app has been successfully verified and is operating correctly.', ['app' => config('app.name')]), function ($message) use ($to) { $message->to($to) ->subject(__('SMTP Configuration Verification — :app', ['app' => config('app.name')])); } ); // ✍️ Log "Action Log" test email activity('system-config') ->causedBy($request->user()) ->withProperties([ 'ip' => $request->ip(), 'agent' => $request->userAgent(), 'recipient' => $to, 'details' => __('Sent a test email to :email to verify SMTP configuration.', ['email' => $to]), ]) ->log(__('Sent Test Email')); return response()->json(['success' => true, 'message' => __('Test email sent successfully to :email', ['email' => $to])]); } catch (\Exception $e) { Log::error('Test email failed: '.$e->getMessage()); return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function testSapConnection(Request $request): JsonResponse { $config = [ 'ashost' => $request->input('sap_rfc_ashost'), 'sysnr' => $request->input('sap_rfc_sysnr'), 'client' => $request->input('sap_rfc_client'), 'user' => $request->input('sap_rfc_user'), 'passwd' => $request->input('sap_rfc_passwd'), 'router' => $request->input('sap_rfc_router'), ]; // Check if required fields are present if (empty($config['ashost']) || empty($config['sysnr']) || empty($config['user'])) { return response()->json(['success' => false, 'message' => __('Host, System Number, and User are required for testing.')], 422); } if (! extension_loaded('sapnwrfc')) { return response()->json([ 'success' => false, 'message' => __('The sapnwrfc PHP extension is not installed on this server. Connection cannot be established.'), ], 500); } try { // Attempt to connect using the extension $conn = new Connection($config); $attributes = $conn->getAttributes(); $conn->close(); activity('system-config') ->causedBy($request->user()) ->withProperties(['host' => $config['ashost']]) ->log(__('Successful SAP RFC connection test')); return response()->json([ 'success' => true, 'message' => __('Successfully connected to SAP! (System: :sysid)', ['sysid' => $attributes['sysId'] ?? 'N/A']), ]); } catch (\Exception $e) { return response()->json(['success' => false, 'message' => 'SAP Error: '.$e->getMessage()], 500); } } public function testDatabaseConnection(Request $request): JsonResponse { try { \Illuminate\Support\Facades\DB::connection()->getPdo(); $dbName = \Illuminate\Support\Facades\DB::connection()->getDatabaseName(); activity('system-config') ->causedBy($request->user()) ->withProperties(['db' => $dbName]) ->log(__('Successful database connection test')); return response()->json([ 'success' => true, 'message' => __('Database connection verified successfully! Connected to: :db', ['db' => $dbName]), ]); } catch (\Exception $e) { return response()->json(['success' => false, 'message' => 'Database Error: '.$e->getMessage()], 500); } } public function publicConfig(): JsonResponse { $settings = $this->systemConfig->getPublicSettings(); if (! empty($settings['app_logo'])) { $settings['app_logo_url'] = asset($settings['app_logo']); } if (! empty($settings['app_favicon'])) { $settings['app_favicon_url'] = asset($settings['app_favicon']); } return response() ->json([ 'data' => $settings, 'generated_at' => now()->toIso8601String(), ]) ->header('Cache-Control', 'public, max-age=300, s-maxage=300'); } public function simulateAi(Request $request): JsonResponse { $prompt = $request->input('prompt'); $providerId = $request->input('ai_provider', $this->systemConfig->get('ai_provider', 'gpt')); if (! $prompt) { return response()->json(['success' => false, 'message' => __('Prompt is required.')], 422); } try { $options = [ 'key' => $request->input('ai_key'), 'model' => $request->input('ai_model'), 'instruction' => $request->input('ai_instruction'), 'temperature' => $request->input('ai_temperature'), 'max_tokens' => $request->input('ai_max_tokens'), ]; $result = $this->aiService->provider($providerId)->generate($prompt, $options); if (! $result['success']) { return response()->json(['success' => false, 'message' => $result['error']], 500); } return response()->json([ 'success' => true, 'provider' => $providerId, 'response' => $result['response'], 'usage' => $result['usage'] ?? null, ]); } catch (\Exception $e) { return response()->json(['success' => false, 'message' => $e->getMessage()], 500); } } public function getAiUsageStats(Request $request): JsonResponse { $period = $request->input('period', 'all'); $query = AiUsageLog::query(); if ($period !== 'all') { $date = match ($period) { 'day' => now()->startOfDay(), 'week' => now()->startOfWeek(), 'month' => now()->startOfMonth(), 'year' => now()->startOfYear(), default => null }; if ($date) { $query->where('created_at', '>=', $date); } } $stats = [ 'total_requests' => (clone $query)->count(), 'total_tokens' => (clone $query)->sum('total_tokens'), 'total_cost' => (clone $query)->sum('estimated_cost'), 'providers' => (clone $query)->select('provider', \DB::raw('count(*) as count')) ->groupBy('provider') ->get(), 'recent' => (clone $query)->latest()->take(5)->get(), 'period' => $period, ]; return response()->json(['success' => true, 'stats' => $stats]); } }