<?php

namespace App\Controller;

use App\Entity\User;
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\Attribute\Route;
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
use Symfony\Component\Security\Csrf\CsrfToken;
use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface;

final class ParentSecurityController extends AbstractController
{
    public function __construct(private readonly CsrfTokenManagerInterface $csrf)
    {
    }

    #[Route('/api/v1/parent/csrf', name: 'api_parent_csrf', methods: ['GET'])]
    public function csrf(): JsonResponse
    {
        return new JsonResponse([
            'loginToken' => $this->csrf->getToken('authenticate')->getValue(),
            'apiToken' => $this->getUser() instanceof User ? $this->csrf->getToken('parent_api')->getValue() : null,
        ]);
    }

    #[Route('/api/v1/parent/login', name: 'api_parent_login', methods: ['POST'])]
    public function login(): never
    {
        throw new \LogicException('La requête de connexion doit être interceptée par Symfony Security.');
    }

    #[Route('/api/v1/parent/logout', name: 'api_parent_logout', methods: ['POST'])]
    public function logout(Request $request, TokenStorageInterface $tokens): JsonResponse
    {
        if (!$this->isApiCsrfValid($request)) {
            return new JsonResponse(['error' => 'invalid_csrf_token'], Response::HTTP_FORBIDDEN);
        }

        $tokens->setToken(null);
        $request->getSession()->invalidate();

        return new JsonResponse(null, Response::HTTP_NO_CONTENT);
    }

    #[Route('/api/v1/parent/me', name: 'api_parent_me', methods: ['GET'])]
    public function me(): JsonResponse
    {
        $user = $this->requireParent();

        return new JsonResponse([
            'id' => $user->getId(),
            'email' => $user->getEmail(),
            'displayName' => $user->getDisplayName(),
            'family' => [
                'id' => $user->getFamily()->getId(),
                'name' => $user->getFamily()->getName(),
                'timezone' => $user->getFamily()->getTimezone(),
            ],
        ]);
    }

    private function isApiCsrfValid(Request $request): bool
    {
        $value = $request->headers->get('X-CSRF-Token');

        return is_string($value) && $this->csrf->isTokenValid(new CsrfToken('parent_api', $value));
    }

    private function requireParent(): User
    {
        $user = $this->getUser();

        if (!$user instanceof User) {
            throw $this->createAccessDeniedException();
        }

        return $user;
    }
}
