model = $model; } /** * Pobiera ustawienia w formacie API * Separuje reguły gry od personalizacji * * @param string $discipline Nazwa dyscypliny * @return array Ustawienia z metadanymi */ public function getSettingsForAPI($discipline) { // Waliduj nazwę dyscypliny $this->validateDisciplineName($discipline); $settings = $this->model->getSettings($discipline); if (!$settings) { // Jeśli nie istnieją, zwróć defaults return [ 'discipline' => $discipline, 'settingsVersion' => 1, 'rules' => [ 'pointsToWin' => DisciplineSettingsModel::getDefaults($discipline)['pointsToWin'], 'setsToWin' => DisciplineSettingsModel::getDefaults($discipline)['setsToWin'], 'serveRotation' => DisciplineSettingsModel::getDefaults($discipline)['serveRotation'], 'specialRules' => DisciplineSettingsModel::getDefaults($discipline)['specialRules'] ?? null ], 'customization' => DisciplineSettingsModel::getDefaults($discipline)['customization'] ?? [], 'status' => 'default' ]; } return [ 'discipline' => $settings['discipline'], 'settingsVersion' => (int)$settings['settingsVersion'], 'rules' => [ 'pointsToWin' => (int)$settings['pointsToWin'], 'setsToWin' => (int)$settings['setsToWin'], 'serveRotation' => (int)$settings['serveRotation'], 'specialRules' => $settings['specialRules'] ], 'customization' => $settings['customization'] ?? [], 'metadata' => [ 'created_at' => $settings['created_at'], 'updated_at' => $settings['updated_at'], 'updated_by' => $settings['updated_by'] ], 'status' => 'custom' ]; } /** * Waliduje i aktualizuje ustawienia * * @param string $discipline Nazwa dyscypliny * @param array $input Dane wejściowe z API * @param int $userId ID administratora * @return array Zaktualizowane ustawienia * @throws InvalidArgumentException */ public function validateAndUpdate($discipline, array $input, $userId) { // Waliduj nazwę dyscypliny $this->validateDisciplineName($discipline); // Wydziel reguły gry i personalizację $rules = $input['rules'] ?? []; $customization = $input['customization'] ?? null; // Waliduj strukturę if (empty($rules)) { throw new InvalidArgumentException('rules field is required'); } // Przygotuj dane do modelu $settings = [ 'pointsToWin' => $rules['pointsToWin'] ?? 10, 'setsToWin' => $rules['setsToWin'] ?? 2, 'serveRotation' => $rules['serveRotation'] ?? 2, 'specialRules' => $rules['specialRules'] ?? null, 'customization' => $customization ]; // Model zawsze waliduje dane $updated = $this->model->updateSettings($discipline, $settings, $userId); return $this->formatSettingsResponse($updated); } /** * Pobiera snapshot do startu meczu * * @param string $discipline Nazwa dyscypliny * @param int|null $version Opcjonalnie: konkretna wersja * @return array Snapshot */ public function getMatchSnapshot($discipline, $version = null) { $this->validateDisciplineName($discipline); try { $snapshot = $this->model->getSnapshot($discipline, $version); return [ 'success' => true, 'snapshot' => $snapshot ]; } catch (RuntimeException $e) { throw new RuntimeException('Cannot create snapshot: ' . $e->getMessage()); } } /** * Resetuje ustawienia do defaults * (przydatne dla testów lub przywrócenia domyślnych) * * @param string $discipline Nazwa dyscypliny * @param int $userId ID administratora * @return array Ustawienia po resecie */ public function resetToDefaults($discipline, $userId) { $this->validateDisciplineName($discipline); $defaults = DisciplineSettingsModel::getDefaults($discipline); $updated = $this->model->updateSettings($discipline, $defaults, $userId); return $this->formatSettingsResponse($updated); } /** * Waliduje czy dyscyplina jest obsługiwana * * @param string $discipline Nazwa dyscypliny * @throws InvalidArgumentException */ private function validateDisciplineName($discipline) { $allowed = ['ping-pong', 'rock-paper-scissors', 'table-football']; if (!in_array($discipline, $allowed, true)) { throw new InvalidArgumentException( "Invalid discipline: $discipline. Allowed: " . implode(', ', $allowed) ); } } /** * Formatuje odpowiedź z ustawień * * @param array $settings Surowe ustawienia z modelu * @return array Sformatowana odpowiedź */ private function formatSettingsResponse($settings) { return [ 'discipline' => $settings['discipline'], 'settingsVersion' => (int)$settings['settingsVersion'], 'rules' => [ 'pointsToWin' => (int)$settings['pointsToWin'], 'setsToWin' => (int)$settings['setsToWin'], 'serveRotation' => (int)$settings['serveRotation'], 'specialRules' => $settings['specialRules'] ], 'customization' => $settings['customization'] ?? [], 'metadata' => [ 'created_at' => $settings['created_at'], 'updated_at' => $settings['updated_at'], 'updated_by' => $settings['updated_by'] ] ]; } /** * Porównuje wersje ustawień (do debugowania zmian) * * @param array $oldSettings Stare ustawienia * @param array $newSettings Nowe ustawienia * @return array Różnice */ public function compareVersions($oldSettings, $newSettings) { $changes = []; foreach (['pointsToWin', 'setsToWin', 'serveRotation', 'specialRules'] as $field) { if (($oldSettings[$field] ?? null) !== ($newSettings[$field] ?? null)) { $changes[$field] = [ 'old' => $oldSettings[$field] ?? null, 'new' => $newSettings[$field] ?? null ]; } } if (json_encode($oldSettings['customization'] ?? []) !== json_encode($newSettings['customization'] ?? [])) { $changes['customization'] = [ 'old' => $oldSettings['customization'] ?? [], 'new' => $newSettings['customization'] ?? [] ]; } return $changes; } } ?>