* @category Class * @license https://www.gnu.org/licenses/lgpl-3.0.en.html GNU Lesser General Public License * @link www.splendidbear.org * @since 2026. 04. 20. */ final readonly class ProfileGameDtoFactory { public function __construct(private CacheManager $cacheManager) { } public function create(PlayedGame $game, int $userId): ProfileGameDto { $isRed = $game->red?->id === $userId; $resign = $game->resign; $myColor = $isRed ? 'red' : 'blue'; $oppColor = $isRed ? 'blue' : 'red'; $myPts = $isRed ? $game->redPoints : $game->bluePoints; $oppPts = $isRed ? $game->bluePoints : $game->redPoints; $redAvatarPath = $game->red?->avatarPath; $blueAvatarPath = $game->blue?->avatarPath; return new ProfileGameDto( id: $game->id, uuid: $game->uuid?->toRfc4122(), redName: $game->red?->getUsername() ?? $game->redAnon?->userName ?? 'Guest', blueName: $game->blue?->getUsername() ?? $game->blueAnon?->userName ?? 'Guest', redAvatar: $redAvatarPath ? $this->cacheManager->generateUrl($redAvatarPath, 'avatar_thumb') : null, blueAvatar: $blueAvatarPath ? $this->cacheManager->generateUrl($blueAvatarPath, 'avatar_thumb') : null, redPoints: $game->redPoints, bluePoints: $game->bluePoints, redExplodedBomb: $game->redExplodedBomb, blueExplodedBomb: $game->blueExplodedBomb, resign: $resign, created: $game->created?->format('Y-m-d H:i'), date: $game->updated?->format('Y-m-d H:i'), isRed: $isRed, result: $this->resolveResult($resign, $myColor, $oppColor, $myPts, $oppPts), myPoints: $myPts, oppPoints: $oppPts, redBonusPoints: $game->redBonusPoints ?? 0.0, blueBonusPoints: $game->blueBonusPoints ?? 0.0, redBonusStats: $game->redBonusStats ?? [], blueBonusStats: $game->blueBonusStats ?? [], ); } private function resolveResult( ?string $resign, string $myColor, string $oppColor, ?int $myPts, ?int $oppPts, ): string { if ($resign === $myColor) { return 'loss'; } if ($resign === $oppColor) { return 'win'; } if ($myPts !== null && $oppPts !== null) { if ($myPts > $oppPts) { return 'win'; } if ($myPts < $oppPts) { return 'loss'; } } return 'draw'; } }