<?php

namespace App\Http\Controllers\Api\V1;

use App\Http\Controllers\Api\V1\Auth\Register\AuthRegisterRequest;
use App\Http\Controllers\Controller;
use App\Http\Requests\Api\V1\Auth\AuthLoginRequest;
use App\Http\Requests\Api\V1\Auth\AuthVerifyRequest;
use App\Models\User;
use App\Repositories\UserRepository;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Str;

class AuthController extends Controller
{
    /**
     * Guest token (walk-in-user)
     *
     * Use when user visits website/app for the first time, and save the token in cache.
     */
    public function guestToken(): JsonResponse
    {
        return response()->rest(
            data: UserRepository::guestUser()->createToken(Str::random(20))->plainTextToken,
            code: 201
        );
    }

    /**
     * Register user
     *
     * Register a new user and send a verification code to their phone number. Then make another request to verification route.
     */
    public function register(AuthRegisterRequest $request): JsonResponse
    {
        UserRepository::registerUser($request)();

        sendSMSVerification($request->phone_number);

        return response()->rest(
            data: [],
            code: 201,
            message: sprintf('%s: %s', __('Verification code sent to'), $request->phone_number)
        );
    }

    /**
     * Login
     *
     * Send a verification code to the phone number. Then make another request to verify route.
     */
    public function login(AuthLoginRequest $request): JsonResponse
    {
        sendSMSVerification($request->phone_number);

        return response()->rest(
            data: [],
            code: 201,
            message: sprintf('%s: %s', __('Verification code sent to'), $request->phone_number)
        );
    }

    /**
     * Verify the code
     *
     * After verification, bearer token will be returned.
     */
    public function verify(AuthVerifyRequest $request): JsonResponse
    {
        $user = User::where('phone_number', $request->phone_number)->firstOr(UserRepository::registerUser($request));

        return response()->rest(
            data: $user->createToken(bin2hex(random_bytes(20)))->plainTextToken,
            code: 201
        );
    }

    /**
     * (Auth)* Delete user
     *
     * @authenticated
     */
    public function delete(): JsonResponse
    {
        auth()->user()->delete();

        return response()->rest();
    }
}
