<?php

namespace App\Http\Controllers\Api\Auth;

use App\Http\Controllers\Api\Core\BaseApiController;
use App\Http\Requests\Roles\RoleSwitchRequest;
use App\Services\Roles\RoleSwitchService;
use Illuminate\Http\JsonResponse;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpFoundation\Response;

class RoleSwitcherController extends BaseApiController
{
    public function __construct(private RoleSwitchService $switchService)
    {
        parent::__construct();
    }

    public function index(): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $roles = $this->switchService->getUserRoleNames($guard);
        if (empty($roles)) {
            return $this->error('No roles assigned to this user.', Response::HTTP_NOT_FOUND);
        }

        return $this->success([
            'roles' => $roles,
        ]);
    }

    public function switch(RoleSwitchRequest $request): JsonResponse
    {
        $guard = $this->authenticatedUserIdOrUnauthorized();
        if ($guard instanceof JsonResponse) {
            return $guard;
        }

        $role = (string) $request->validated()['role'];
        try {
            $route = $this->switchService->switchRole($guard, $role);
        } catch (AccessDeniedHttpException $e) {
            return $this->error($e->getMessage(), Response::HTTP_FORBIDDEN);
        } catch (NotFoundHttpException $e) {
            return $this->error($e->getMessage(), Response::HTTP_NOT_FOUND);
        }

        return $this->success([
            'role' => $role,
            'dashboard_route' => $route,
        ], 'Role switched successfully.');
    }

    /**
     * @return int|JsonResponse
     */
    private function authenticatedUserIdOrUnauthorized(): int|JsonResponse
    {
        $userId = (int) (auth()->id() ?? 0);
        if ($userId <= 0) {
            return $this->error('Please log in first.', Response::HTTP_UNAUTHORIZED);
        }

        return $userId;
    }
}
