startOfDay(); } /** * Returns the vote start date. */ public static function voteStartAt(): Carbon { return Carbon::parse(config('goldencrush.vote_start_at'))->startOfDay(); } /** * Returns the vote end date. */ public static function voteEndAt(): Carbon { return Carbon::parse(config('goldencrush.vote_end_at'))->endOfDay(); } /** * Returns the start date of the end participation period. * (day after the vote end date) */ public static function endParticipationStartAt(): Carbon { return self::voteEndAt()->copy()->addDay()->startOfDay(); } /** * Returns the end date of the end participation period. */ public static function endParticipationEndAt(): Carbon { return Carbon::parse(config('goldencrush.end_participation_end_at'))->endOfDay(); } /** * Returns the start date of the end game period. * (day after the end participation end date) */ public static function endGameStartAt(): Carbon { return self::endParticipationEndAt()->copy()->addDay()->startOfDay(); } /** * Returns the end date of the game. */ public static function endGameEndAt(): Carbon { return Carbon::parse(config('goldencrush.end_game_end_at'))->endOfDay(); } /** * Checks if the configured periods are valid. * Validates that the vote start date is before or equal to the vote end date * and the end game end date. */ public static function hasValidPeriods(): bool { return self::voteStartAt()->lte(self::voteEndAt()) && self::voteStartAt()->lte(self::endGameEndAt()); } /** * Returns the current game state based on today's date. * * Possible states: * - 'start_game' : between game start and vote start * - 'vote' : between vote start and vote end * - 'end_participation' : between end participation start and end * - 'end_game' : between end game start and end * - 'closed' : outside all periods or invalid config */ public static function state(): string { if (! self::hasValidPeriods()) { Log::error('Config des dates invalide ! '); return 'closed'; } $today = now(); if ($today->betweenIncluded(self::startGameAt(), self::voteStartAt())) { return 'start_game'; } if ($today->betweenIncluded(self::voteStartAt(), self::voteEndAt())) { return 'vote'; } if ($today->betweenIncluded(self::endParticipationStartAt(), self::endParticipationEndAt())) { return 'end_participation'; } if ($today->betweenIncluded(self::endGameStartAt(), self::endGameEndAt())) { return 'end_game'; } return 'closed'; } /** * Returns the route name corresponding to the current game state. */ public static function routeName(): string { return match (self::state()) { 'vote' => 'club.golden-crush', 'end_participation' => 'club.golden-crush.end-of-participation', 'end_game' => 'club.golden-crush.end-of-game', default => 'club.home.show', }; } /** * Checks if today is within the active game period. * (between vote start and end game end) */ public static function isGamePeriod(): bool { return now()->between( self::voteStartAt(), self::endGameEndAt() ); } /** * Checks if the game is currently visible to users. * Returns true if the state is 'start_game', 'vote', 'end_participation' or 'end_game'. */ public static function isGameVisible(): bool { return in_array(self::state(), [ 'start_game', 'vote', 'end_participation', 'end_game', ]); } }