<?php

declare(strict_types=1);

namespace App\Controller;

use App\Enum\GameModeType;
use App\Repository\GameRepository;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;

#[Route('/games')]
class GameController extends AbstractController
{
    public function __construct(
        private readonly GameRepository $gameRepository,
    ) {
    }

    #[Route('/new', name: 'game_new', methods: ['GET'])]
    public function new(Request $request): Response
    {
        return $this->render('game/new.html.twig', [
            'selectedModeKey' => (string) $request->query->get('mode', ''),
        ]);
    }

    #[Route('/{id}/guest', name: 'game_guest_show', methods: ['GET'])]
    public function guestShow(string $id, Request $request): Response
    {
        return $this->render('game/guest_show.html.twig', [
            'gameId' => $id,
            'websocketUri' => $this->resolveWebsocketUri($request),
        ]);
    }

    #[Route('/{id}', name: 'game_show', methods: ['GET'])]
    public function show(string $id, Request $request): Response
    {
        $game = $this->gameRepository->findWithPlayers($id);
        if ($game === null) {
            throw $this->createNotFoundException('Game not found');
        }

        $template = $game->getMode()->getType() === GameModeType::ATW
            ? 'game/show_atw.html.twig'
            : 'game/show.html.twig';

        return $this->render($template, [
            'gameId' => $id,
            'websocketUri' => $this->resolveWebsocketUri($request),
        ]);
    }

    private function resolveWebsocketUri(Request $request): string
    {
        $value = trim((string) (getenv('WEBSOCKET_URI') ?: ''));
        if ($value === '') {
            return '';
        }

        $parts = parse_url($value);
        if (!\is_array($parts)) {
            return $value;
        }

        $host = strtolower((string) ($parts['host'] ?? ''));

        $internalHosts = ['dart_traefik', 'dart_websocket', 'dart_app'];
        if (!\in_array($host, $internalHosts, true)) {
            return $value;
        }

        $scheme = strtolower((string) ($parts['scheme'] ?? 'https'));
        $path = (string) ($parts['path'] ?? '');
        $query = isset($parts['query']) ? '?' . $parts['query'] : '';
        $fragment = isset($parts['fragment']) ? '#' . $parts['fragment'] : '';

        if ($scheme === 'ws' || $scheme === 'wss') {
            return sprintf('%s://%s%s%s%s', $scheme, $request->getHttpHost(), $path, $query, $fragment);
        }

        return sprintf('%s://%s%s%s', $request->getScheme(), $request->getHttpHost(), $path, $query);
    }
}
