<?php

namespace App\Http\Controllers\Authentication;

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

/**
 * @OA\Post(
 *   path="/api/auth/login",
 *   tags={"Authentication"},
 *   summary="Agent Login",
 *   operationId="auth_login",
 *   security={{}},
 *
 *   @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\RequestBody(required=true,
 *     @OA\MediaType(mediaType="application/x-www-form-urlencoded",
 *       @OA\Schema(required={"username","password"},
 *         @OA\Property(property="username", description="Username", type="string", example=""),
 *         @OA\Property(property="password", description="Password", type="string", example=""),
 *       )
 *     )
 *   ),
 *
 *   @OA\Response(response=200, description="success")
 * )
 */
class LoginController extends ApiController
{
    public function __invoke(LoginRequest $request): JsonResponse
    {
        try {
            $data = $this->sanitize($request, [
                'apiKey'   => $request->validated('apiKey'),
                'username' => $request->validated('username'),
                'password' => $request->validated('password'),
            ]);
            $agent = Agent::query()
                ->where([
                    'id'        => $data['apiKey'],
                    'username'  => $data['username'],
                    'is_active' => 1,
                ])
                ->first();
            throw_if(!$agent, new Exception('Invalid credentials', Response::HTTP_BAD_REQUEST));
            throw_if(!Hash::check($data['password'], $agent->password), new Exception('Invalid credentials', Response::HTTP_BAD_REQUEST));
            if ($agent->admin && ! $agent->admin->is_active) {
                throw new Exception('Your account is disabled', Response::HTTP_FORBIDDEN);
            }
            $token = JwtHelper::createToken(Str::ulid()->toString(), $agent->id, 86_400)->toString();
            $refresh = JwtHelper::createToken(Str::ulid()->toString(), $agent->id, 2_592_000)->toString();
            Session::query()->create([
                'agent_id'   => $agent->id,
                'token'      => JwtHelper::getId($token),
                'refresh'    => JwtHelper::getId($refresh),
                'expired_at' => now()->addSeconds(2_592_000),
            ]);
            return $this->success(compact('token', 'refresh'));
        } catch (Throwable $e) {
            return $this->error($e->getMessage(), status: $e->getCode());
        }
    }
}
