get(self::SESSION_KEY); if (! $data) { session()->forget(self::SESSION_KEY); } return view('admin.radio.wizard.step-1', [ 'step' => 1, 'selectedPlatform' => $data['platform'] ?? null, ]); } public function processStep1(Request $request): RedirectResponse { $validated = $request->validate([ 'platform' => ['required', 'string', 'in:shoutcast,icecast,azurecast,other'], ]); session()->put(self::SESSION_KEY . '.platform', $validated['platform']); return redirect()->route('admin.radio.wizard.step', ['step' => 2]); } public function step(int $step): View|RedirectResponse { $data = session()->get(self::SESSION_KEY); if (! $data && $step > 1) { return redirect()->route('admin.radio.wizard'); } return match ($step) { 2 => $this->step2($data), 3 => $this->step3($data), 4 => $this->step4($data), 5 => $this->step5($data), default => redirect()->route('admin.radio.wizard'), }; } private function step2(array $data): View { $platform = $data['platform'] ?? 'other'; $platformLabels = [ 'shoutcast' => 'SHOUTcast', 'icecast' => 'Icecast', 'azurecast' => 'AzureCast', 'other' => 'Anders', ]; return view('admin.radio.wizard.step-2', [ 'step' => 2, 'platform' => $platform, 'platformLabel' => $platformLabels[$platform] ?? 'Onbekend', 'streamUrl' => session()->get(self::SESSION_KEY . '.stream_url', ''), 'streamName' => session()->get(self::SESSION_KEY . '.stream_name', ''), 'azurecastBaseUrl' => session()->get(self::SESSION_KEY . '.azurecast_base_url', ''), 'azurecastStationId' => session()->get(self::SESSION_KEY . '.azurecast_station_id', '1'), ]); } public function processStep2(Request $request): RedirectResponse { $platform = session()->get(self::SESSION_KEY . '.platform', 'other'); $rules = [ 'stream_url' => ['required', 'string', 'max:500'], 'stream_name' => ['nullable', 'string', 'max:100'], ]; if ($platform === 'azurecast') { $rules['azurecast_base_url'] = ['nullable', 'string', 'max:500']; $rules['azurecast_station_id'] = ['nullable', 'integer', 'min:1']; } $validated = $request->validate($rules); session()->put(self::SESSION_KEY . '.stream_url', $validated['stream_url']); session()->put(self::SESSION_KEY . '.stream_name', $validated['stream_name'] ?? 'Mijn Radio'); if ($platform === 'azurecast') { session()->put(self::SESSION_KEY . '.azurecast_base_url', $validated['azurecast_base_url'] ?? ''); session()->put(self::SESSION_KEY . '.azurecast_station_id', $validated['azurecast_station_id'] ?? '1'); } return redirect()->route('admin.radio.wizard.step', ['step' => 3]); } private function step3(array $data): View { $platform = $data['platform'] ?? 'other'; $streamUrl = $data['stream_url'] ?? ''; $autoDetected = null; if (! empty($streamUrl)) { $autoDetected = $this->streamService->detectStreamType($streamUrl); } return view('admin.radio.wizard.step-3', [ 'step' => 3, 'platform' => $platform, 'autoDetected' => $autoDetected, 'nowPlayingApi' => session()->get(self::SESSION_KEY . '.now_playing_api', $autoDetected['now_playing_api'] ?? ''), 'listenersApi' => session()->get(self::SESSION_KEY . '.listeners_api', $autoDetected['listeners_api'] ?? ''), 'enableNowPlaying' => session()->get(self::SESSION_KEY . '.enable_now_playing', true), 'enableListeners' => session()->get(self::SESSION_KEY . '.enable_listeners', true), 'enableCurrentDj' => session()->get(self::SESSION_KEY . '.enable_current_dj', true), ]); } public function processStep3(Request $request): RedirectResponse { $validated = $request->validate([ 'now_playing_api' => ['nullable', 'string', 'max:500'], 'listeners_api' => ['nullable', 'string', 'max:500'], 'enable_now_playing' => ['nullable', 'boolean'], 'enable_listeners' => ['nullable', 'boolean'], 'enable_current_dj' => ['nullable', 'boolean'], ]); session()->put(self::SESSION_KEY . '.now_playing_api', $validated['now_playing_api'] ?? ''); session()->put(self::SESSION_KEY . '.listeners_api', $validated['listeners_api'] ?? ''); session()->put(self::SESSION_KEY . '.enable_now_playing', (bool) ($validated['enable_now_playing'] ?? false)); session()->put(self::SESSION_KEY . '.enable_listeners', (bool) ($validated['enable_listeners'] ?? false)); session()->put(self::SESSION_KEY . '.enable_current_dj', (bool) ($validated['enable_current_dj'] ?? false)); return redirect()->route('admin.radio.wizard.step', ['step' => 4]); } private function step4(array $data): View { return view('admin.radio.wizard.step-4', [ 'step' => 4, 'enableShouts' => session()->get(self::SESSION_KEY . '.enable_shouts', true), 'enableApplications' => session()->get(self::SESSION_KEY . '.enable_applications', true), 'enableWidget' => session()->get(self::SESSION_KEY . '.enable_widget', true), 'enableWidgetGlobally' => session()->get(self::SESSION_KEY . '.enable_widget_globally', true), 'enablePoints' => session()->get(self::SESSION_KEY . '.enable_points', true), 'enableRequests' => session()->get(self::SESSION_KEY . '.enable_requests', true), 'enableContests' => session()->get(self::SESSION_KEY . '.enable_contests', true), 'enableGiveaways' => session()->get(self::SESSION_KEY . '.enable_giveaways', false), 'enableDiscord' => session()->get(self::SESSION_KEY . '.enable_discord', false), 'discordWebhook' => session()->get(self::SESSION_KEY . '.discord_webhook', ''), 'widgetPosition' => session()->get(self::SESSION_KEY . '.widget_position', 'bottom-right'), ]); } public function processStep4(Request $request): RedirectResponse { $validated = $request->validate([ 'enable_shouts' => ['nullable', 'boolean'], 'enable_applications' => ['nullable', 'boolean'], 'enable_widget' => ['nullable', 'boolean'], 'enable_widget_globally' => ['nullable', 'boolean'], 'enable_points' => ['nullable', 'boolean'], 'enable_requests' => ['nullable', 'boolean'], 'enable_contests' => ['nullable', 'boolean'], 'enable_giveaways' => ['nullable', 'boolean'], 'enable_discord' => ['nullable', 'boolean'], 'discord_webhook' => ['nullable', 'string', 'max:500'], 'widget_position' => ['nullable', 'string', 'in:bottom-right,bottom-left,top-right,top-left'], ]); session()->put(self::SESSION_KEY . '.enable_shouts', (bool) ($validated['enable_shouts'] ?? false)); session()->put(self::SESSION_KEY . '.enable_applications', (bool) ($validated['enable_applications'] ?? false)); session()->put(self::SESSION_KEY . '.enable_widget', (bool) ($validated['enable_widget'] ?? false)); session()->put(self::SESSION_KEY . '.enable_widget_globally', (bool) ($validated['enable_widget_globally'] ?? false)); session()->put(self::SESSION_KEY . '.enable_points', (bool) ($validated['enable_points'] ?? false)); session()->put(self::SESSION_KEY . '.enable_requests', (bool) ($validated['enable_requests'] ?? false)); session()->put(self::SESSION_KEY . '.enable_contests', (bool) ($validated['enable_contests'] ?? false)); session()->put(self::SESSION_KEY . '.enable_giveaways', (bool) ($validated['enable_giveaways'] ?? false)); session()->put(self::SESSION_KEY . '.enable_discord', (bool) ($validated['enable_discord'] ?? false)); session()->put(self::SESSION_KEY . '.discord_webhook', $validated['discord_webhook'] ?? ''); session()->put(self::SESSION_KEY . '.widget_position', $validated['widget_position'] ?? 'bottom-right'); return redirect()->route('admin.radio.wizard.step', ['step' => 5]); } private function step5(array $data): View { $platform = $data['platform'] ?? 'other'; $streamUrl = $data['stream_url'] ?? ''; $platformLabels = [ 'shoutcast' => 'SHOUTcast', 'icecast' => 'Icecast', 'azurecast' => 'AzureCast', 'other' => 'Anders', ]; $testResults = null; if (! empty($streamUrl)) { $testResults = $this->streamService->testStreamConnection( $streamUrl, $data['now_playing_api'] ?? null, $data['listeners_api'] ?? null, ); } $settingsList = $this->buildSettingsList($data); return view('admin.radio.wizard.step-5', [ 'step' => 5, 'platform' => $platform, 'platformLabel' => $platformLabels[$platform] ?? 'Onbekend', 'data' => $data, 'testResults' => $testResults, 'settingsList' => $settingsList, ]); } public function runTest(): JsonResponse { $data = session()->get(self::SESSION_KEY); if (! $data || empty($data['stream_url'])) { return response()->json([ 'success' => false, 'error' => 'Geen stream URL gevonden. Start de wizard opnieuw.', ]); } $testResults = $this->streamService->testStreamConnection( $data['stream_url'], $data['now_playing_api'] ?? null, $data['listeners_api'] ?? null, ); return response()->json([ 'success' => true, 'results' => $testResults, ]); } public function complete(): RedirectResponse { $data = session()->get(self::SESSION_KEY); if (! $data) { return redirect()->route('admin.radio.wizard') ->with('error', 'Geen wizard data gevonden. Start opnieuw.'); } try { $this->saveAllSettings($data); $this->createDefaultRanks(); Artisan::call('config:clear'); Artisan::call('cache:clear'); session()->forget(self::SESSION_KEY); return redirect()->route('admin.radio.setup') ->with('success', 'Radio systeem is succesvol geïnstalleerd en geconfigureerd!'); } catch (\Exception $e) { return redirect()->route('admin.radio.wizard.step', ['step' => 5]) ->with('error', 'Fout tijdens opslaan: ' . $e->getMessage()); } } private function saveAllSettings(array $data): void { $platform = $data['platform'] ?? 'other'; $settings = [ 'radio_enabled' => '1', 'radio_stream_url' => $data['stream_url'] ?? '', 'radio_stream_name' => $data['stream_name'] ?? 'Mijn Radio', 'radio_style' => 'dark', 'radio_auto_play' => '0', 'radio_stream_platform' => $platform, 'radio_now_playing_enabled' => ($data['enable_now_playing'] ?? true) ? '1' : '0', 'radio_listeners_enabled' => ($data['enable_listeners'] ?? true) ? '1' : '0', 'radio_show_current_dj' => ($data['enable_current_dj'] ?? true) ? '1' : '0', 'radio_shouts_enabled' => ($data['enable_shouts'] ?? true) ? '1' : '0', 'radio_applications_enabled' => ($data['enable_applications'] ?? true) ? '1' : '0', 'radio_widget_enabled' => ($data['enable_widget'] ?? true) ? '1' : '0', 'radio_widget_show_globally' => ($data['enable_widget_globally'] ?? true) ? '1' : '0', 'radio_widget_position' => $data['widget_position'] ?? 'bottom-right', 'radio_auto_dj_detection' => '1', 'radio_show_song_history' => '1', 'radio_show_schedule_preview' => '1', 'radio_word_filter_enabled' => '1', ]; if ($platform === 'azurecast') { $settings['radio_azurecast_base_url'] = $data['azurecast_base_url'] ?? ''; $settings['radio_azurecast_station_id'] = $data['azurecast_station_id'] ?? '1'; } if (! empty($data['now_playing_api'])) { $settings['radio_now_playing_api_url'] = $data['now_playing_api']; } if (! empty($data['listeners_api'])) { $settings['radio_listeners_api_url'] = $data['listeners_api']; } if ($data['enable_points'] ?? true) { $settings['points_enabled'] = '1'; $settings['points_per_minute'] = '2'; $settings['max_points_per_day'] = '100'; $settings['points_for_request'] = '5'; $settings['points_for_vote'] = '2'; $settings['points_for_giveaway_win'] = '50'; $settings['points_for_contest_win'] = '100'; } if ($data['enable_requests'] ?? true) { $settings['radio_request_form_enabled'] = '1'; } if ($data['enable_contests'] ?? true) { $settings['radio_contests_enabled'] = '1'; } if ($data['enable_giveaways'] ?? false) { $settings['radio_giveaways_enabled'] = '1'; } if ($data['enable_discord'] ?? false && ! empty($data['discord_webhook'])) { $settings['radio_discord_enabled'] = '1'; $settings['radio_discord_webhook_url'] = $data['discord_webhook']; $settings['radio_discord_dj_live'] = '1'; $settings['radio_discord_song_changes'] = '1'; } foreach ($settings as $key => $value) { WebsiteSetting::updateOrCreate( ['key' => $key], ['value' => (string) $value, 'comment' => 'Radio wizard configuratie'], ); } } private function createDefaultRanks(): void { $ranks = [ ['name' => 'Trainee DJ', 'level' => 1, 'is_active' => true, 'description' => 'Beginnende DJ'], ['name' => 'Junior DJ', 'level' => 2, 'is_active' => true, 'description' => 'Ervaren DJ'], ['name' => 'Senior DJ', 'level' => 3, 'is_active' => true, 'description' => 'Professionele DJ'], ['name' => 'Head DJ', 'level' => 4, 'is_active' => true, 'description' => 'Hoofd DJ'], ['name' => 'Radio Manager', 'level' => 5, 'is_active' => true, 'description' => 'Radio Manager'], ]; foreach ($ranks as $rank) { RadioRank::updateOrCreate( ['name' => $rank['name']], $rank, ); } } private function buildSettingsList(array $data): array { $list = []; $list['Stream URL'] = $data['stream_url'] ?? '-'; $list['Stream Naam'] = $data['stream_name'] ?? 'Mijn Radio'; $list['Platform'] = match ($data['platform'] ?? 'other') { 'shoutcast' => 'SHOUTcast', 'icecast' => 'Icecast', 'azurecast' => 'AzureCast', default => 'Anders', }; if (! empty($data['now_playing_api'])) { $list['Now Playing API'] = $data['now_playing_api']; } if (! empty($data['listeners_api'])) { $list['Listeners API'] = $data['listeners_api']; } $list['Nu Afspelen'] = ($data['enable_now_playing'] ?? true) ? 'Aan' : 'Uit'; $list['Luisteraars'] = ($data['enable_listeners'] ?? true) ? 'Aan' : 'Uit'; $list['Huidige DJ'] = ($data['enable_current_dj'] ?? true) ? 'Aan' : 'Uit'; $list['Shouts'] = ($data['enable_shouts'] ?? true) ? 'Aan' : 'Uit'; $list['DJ Aanmeldingen'] = ($data['enable_applications'] ?? true) ? 'Aan' : 'Uit'; $list['Radio Widget'] = ($data['enable_widget'] ?? true) ? 'Aan' : 'Uit'; $list['Widget Overal'] = ($data['enable_widget_globally'] ?? true) ? 'Ja' : 'Nee'; $list['Widget Positie'] = $data['widget_position'] ?? 'bottom-right'; $list['Punten Systeem'] = ($data['enable_points'] ?? true) ? 'Aan' : 'Uit'; $list['Song Verzoeken'] = ($data['enable_requests'] ?? true) ? 'Aan' : 'Uit'; $list['Contesten'] = ($data['enable_contests'] ?? true) ? 'Aan' : 'Uit'; $list['Giveaways'] = ($data['enable_giveaways'] ?? false) ? 'Aan' : 'Uit'; $list['Discord'] = ($data['enable_discord'] ?? false) ? 'Aan' : 'Uit'; return $list; } }