<?php declare(strict_types=1);

namespace App\Services\Api\V1;

use App\Dto\Request\Api\V1\Captcha\CaptchaPublicToken;
use App\Repositories\DataCaptchaRepository;
use App\ServiceResults\Api\V1\CaptchaService\Captcha;
use App\ServiceResults\ServiceResultError;
use App\Services\Captcha\CaptchaHandler;
use App\Services\Service;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;

final class CaptchaService extends Service
{
    public function __construct(
        private readonly CaptchaGenerateService $captchaGenerateService,
        private readonly CaptchaHandler $captchaHandler,
        private readonly DataCaptchaRepository $dataCaptchaRepository,
    ) { }

    public function createKeyWithCaptcha(CaptchaPublicToken $captchaPublicToken, Carbon $expires): ServiceResultError | Captcha
    {
        try {
            $captcha = $this->captchaGenerateService->generate();
            if ($captcha->isError()) {
                return $captcha;
            }

            $modelCaptcha = DB::transaction(function () use ($captchaPublicToken) {
                return $this->captchaHandler->handleStore($captchaPublicToken->getCaptchaToken(), $captchaPublicToken->getHttpUserData());
            });

            $captchaKey = $this->dataCaptchaRepository->store($modelCaptcha, $captcha->getImageBody()->getCoordinators(), $expires);
        } catch (\Throwable $e) {
            report($e);
            return $this->errService('Captcha service error!');
        }

        return new Captcha(
            imageHead: $captcha->getImageHead()->getImage(),
            imageBody: $captcha->getImageBody()->getImage(),
            key: $captchaKey
        );
    }
}
