<?php

declare(strict_types=1);

namespace apexl\Io\modules\user\controllers\twoFactorAuth;

use apexl\Io\includes\Controller;
use apexl\Io\modules\user\exceptions\TwoFactorException;
use apexl\Io\modules\user\services\CurrentUserFactory;
use apexl\Io\modules\user\services\twoFactorAuth\TwoFactorAuthService;
use JsonException;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;

/**
 * POST /api/v1/user/action/two-factor-auth/setup
 *
 * Begins (or restarts) TOTP enrolment for the current user: returns the
 * provisioning URI, a scannable QR data URI, and the manual-entry secret. The
 * method is created INACTIVE — nothing is enforced until complete-setup
 * confirms a code. Guarded by IS_LOGGED_IN.
 */
final readonly class SetupTwoFactorController extends Controller
{
    /**
     * @throws JsonException
     */
    public function __invoke(
        ServerRequestInterface $request,
        ResponseInterface $response,
        CurrentUserFactory $currentUserFactory,
        TwoFactorAuthService $twoFactorService,
    ): ResponseInterface {
        $user = $currentUserFactory->get();
        if ($user === null || !$user->id) {
            return $this->json($response, ['error' => 'Not authenticated'], 401);
        }

        try {
            $setup = $twoFactorService->beginSetup($user);
        } catch (TwoFactorException $exception) {
            $this->output->addResponse($request, ['error' => $exception->getMessage()], false);

            return $this->json($response, [], 409);
        }

        $this->output->addResponse($request, [
            'method_id' => $setup->methodId,
            'type' => $setup->type,
            'secret' => $setup->secret,
            'provisioning_uri' => $setup->provisioningUri,
            'qr_code' => $setup->qrCodeDataUri,
        ]);

        return $this->json($response);
    }
}
