<?php
namespace App\Controller\Public;
use App\Entity\Person\Person;
use App\Entity\World;
use App\Service\WsServerHttpClient;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
class PublicController extends AbstractController
{
public function __construct(
private readonly EntityManagerInterface $entityManager,
private readonly WsServerHttpClient $httpClient,
) {}
#[Route('/game', name: 'public_game', methods: ['GET'])]
public function game(): Response
{
return $this->render('public/game.html.twig', [
'name' => 'Чат',
'gameServerUrl' => $_ENV['GAME_WSSERVER_URL'],
]);
}
#[Route('/game/invite/{roomId}', name: 'public_invite', methods: ['GET'])]
public function invite(?string $roomId): Response
{
try {
// Делаем запрос к серверу для получения информации о комнатах
$response = $this->httpClient->request('GET', 'room/get');
$rooms = $response->toArray();
// Ищем комнату по roomId
$foundRoom = null;
foreach ($rooms as $room) {
if ($room['id'] === $roomId) {
$foundRoom = $room;
break;
}
}
if (!$foundRoom) {
throw $this->createNotFoundException('Room not found');
}
// Получаем worldId из найденной комнаты
$worldId = $foundRoom['worldId'] ?? null;
if (!$worldId) {
throw $this->createNotFoundException('World ID not found in room');
}
// Ищем мир в репозитории
$worldRepository = $this->entityManager->getRepository(World::class);
$world = $worldRepository->find($worldId);
if (!$world) {
throw $this->createNotFoundException('World not found');
}
$personRepository = $this->entityManager->getRepository(Person::class);
$persons = $personRepository->findBy(['world' => $world]);
return $this->render('public/invite/king.html.twig', [
'roomId' => $roomId,
'worldName' => $world->getName(),
'worldDescription' => $world->getDescription(),
'persons' => $persons,
]);
} catch (\Exception $e) {
throw $this->createNotFoundException('Room not found: ' . $e->getMessage());
}
}
#[Route('/', name: 'public_index', methods: ['GET'])]
public function index(): Response
{
// Получаем список всех миров из репозитория
$worldRepository = $this->entityManager->getRepository(World::class);
$worlds = $worldRepository->findAll();
// Фильтруем миры, которые публичные
$availableWorlds = array_filter($worlds, function (World $world) {
return $world->isPublic();
});
$availableWorlds = array_values($availableWorlds);
return $this->render('public/game_list.html.twig', [
'worlds' => $availableWorlds,
]);
}
#[Route('/world/{id}', name: 'public_world_view', methods: ['GET'])]
public function viewWorld(string $id): Response
{
// Получаем мир из репозитория
$worldRepository = $this->entityManager->getRepository(World::class);
$world = $worldRepository->find($id);
if (!$world) {
throw $this->createNotFoundException('Мир не найден');
}
if (!$world->isPublic()) {
throw $this->createNotFoundException('Мир не доступен');
}
return $this->render('public/world_view.html.twig', [
'world' => $world,
]);
}
#[Route('/game/create/{worldId}', name: 'public_create_room', methods: ['POST'])]
public function createRoom(string $worldId): Response
{
try {
// Проверяем существование мира
$worldRepository = $this->entityManager->getRepository(World::class);
$world = $worldRepository->find($worldId);
if (!$world) {
throw $this->createNotFoundException('World not found');
}
// Проверяем, что мир готов к публикации
if (!$world->isReadyToPub()) {
throw $this->createNotFoundException('World is not ready to publish');
}
// Создаем комнату через WebSocket сервер
$response = $this->httpClient->request('POST', 'room/create', [
'json' => [
'worldId' => $worldId
]
]);
$roomData = $response->toArray();
$roomId = $roomData['room_id'] ?? null;
if (!$roomId) {
throw new \Exception('Request failed');
}
// Перенаправляем на страницу приглашения
return $this->redirectToRoute('public_invite', ['roomId' => $roomId]);
} catch (\Exception $e) {
throw $this->createNotFoundException('Failed to create room: ' . $e->getMessage());
}
}
#[Route('/game/register/{roomId}', name: 'public_game_register', methods: ['POST'])]
public function register(string $roomId, Request $request): Response
{
try {
// Получаем данные из запроса
$data = json_decode($request->getContent(), true, 512, JSON_THROW_ON_ERROR);
// Формируем данные для отправки на сервер регистрации
$registerData = [
'name' => $data['name'] ?? '',
'person_id' => $data['person_id'] ?? '',
'room_id' => $roomId,
];
// Отправляем запрос на существующий маршрут /register через WebSocket клиент
$response = $this->httpClient->request('POST', 'register', [
'json' => $registerData
]);
// Возвращаем ответ от сервера
$responseData = $response->toArray();
// Создаем JSON ответ с cookie в теле
return new JsonResponse($responseData);
} catch (\Exception $e) {
return new JsonResponse(['error' => 'Registration failed: ' . $e->getMessage()], 500);
}
}
}