<?php

namespace App\Http\Controllers\Authentication;

use App\Helpers\JwtHelper;
use App\Http\Controllers\ApiController;
use App\Http\Requests\Authentication\RefreshRequest;
use App\Models\Session;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Support\Str;
use Symfony\Component\HttpFoundation\Response;
use Throwable;

/**
 * @OA\Patch(
 *   path="/api/auth/refresh",
 *   tags={"Authentication"},
 *   summary="Refresh Token",
 *   operationId="auth_refresh",
 *   security={{"auth":{}}},
 *
 *   @OA\Parameter(name="Accept-Language", in="header", description="Accept-Language", required=true, example="en", @OA\Schema(type="string")),
 *   @OA\Parameter(name="API-Key", in="header", description="API-Key", required=true, example="", @OA\Schema(type="string")),
 *
 *   @OA\Response(response=200, description="success")
 * )
 */
class RefreshController extends ApiController
{
    public function __invoke(RefreshRequest $request): JsonResponse
    {
        try {
            $data = $this->sanitize($request, [
                'token' => $request->validated('token')
            ]);
            $session = Session::query()
                ->where([
                    'refresh'   => JwtHelper::getId($data['token']),
                    'is_active' => 1,
                ])
                ->first();
            throw_if(!$session, new Exception('Invalid token', Response::HTTP_FORBIDDEN));
            $token = JwtHelper::createToken(Str::ulid()->toString(), $session->agent_id, 86_400)->toString();
            $refresh = JwtHelper::createToken(Str::ulid()->toString(), $session->agent_id, 2_592_000)->toString();
            $session->update([
                'token'      => JwtHelper::getId($token),
                'refresh'    => JwtHelper::getId($refresh),
                'expired_at' => now()->addSeconds(2_592_000),
            ]);
            $session->refresh();
            return $this->success(compact('token', 'refresh'));
        } catch (Throwable $e) {
            return $this->error($e->getMessage(), status: $e->getCode());
        }
    }
}
