<?php

declare(strict_types=1);

namespace App\Controller;

use App\Entity\User;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\DependencyInjection\Attribute\Autowire;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Security\Http\Attribute\IsGranted;

#[IsGranted('ROLE_USER')]
class SpaController extends AbstractController
{
    public function __construct(
        #[Autowire('%kernel.project_dir%/public/build')]
        private readonly string $buildDir,
    ) {}

    #[Route(
        '/{path}',
        name: 'spa',
        requirements: ['path' => '^(?!api|setup|token|login|register|logout|_profiler|_wdt).*'],
        defaults: ['path' => ''],
    )]
    public function index(): Response
    {
        $indexFile = $this->buildDir . '/index.html';

        if (!file_exists($indexFile)) {
            throw $this->createNotFoundException('SPA not built — run npm run build in frontend/.');
        }

        /** @var User $user */
        $user = $this->getUser();
        $theme = $user->getTheme() ?? 'warm-craft';

        $userData = json_encode([
            'id'       => $user->getId(),
            'email'    => $user->getEmail(),
            'roles'    => $user->getRoles(),
            'theme'    => $theme,
            'timezone' => $user->getTimezone(),
        ], JSON_HEX_TAG | JSON_HEX_APOS | JSON_HEX_AMP | JSON_HEX_QUOT);

        $html = (string) file_get_contents($indexFile);

        // Inject theme on <html> so CSS applies before JS hydrates (no FOUC)
        $html = str_replace('<html lang="en">', '<html lang="en" data-theme="' . htmlspecialchars($theme, ENT_QUOTES) . '">', $html);

        // Bootstrap current user into window so Pinia auth store needs no initial API call
        $html = str_replace('</head>', '<script>window.__PF_USER__=' . $userData . ';</script></head>', $html);

        return new Response($html, headers: ['Content-Type' => 'text/html; charset=utf-8']);
    }
}
