<?php

namespace App\WebAuthn\Repository;

use App\Models\WebauthnCredential;
use Illuminate\Database\Eloquent\Builder;
use Webauthn\PublicKeyCredentialSource;
use Webauthn\PublicKeyCredentialSourceRepository;
use Webauthn\PublicKeyCredentialUserEntity;

class PublicKeyCredentialSourceRepositoryImpl implements PublicKeyCredentialSourceRepository
{

    public function findOneByCredentialId(string $publicKeyCredentialId): ?PublicKeyCredentialSource
    {
        $model = $this->findOneModelByCredentialId($publicKeyCredentialId);
        if ($model) {
            return $model->getPublicKeyCredentialSourceAttribute();
        } else {
            return null;
        }
    }

    /**
     * @inheritDoc
     */
    public function findAllForUserEntity(PublicKeyCredentialUserEntity $publicKeyCredentialUserEntity): array
    {
        if ($publicKeyCredentialUserEntity->getId() == 0) {
            $modelList = $this->findAllModelByTypeFree();
        } else {
            $modelList = $this->findAllModelByUserId($publicKeyCredentialUserEntity->getId());
        }
        return array_map(function (WebauthnCredential $cred) {
            return $cred->getPublicKeyCredentialSourceAttribute();
        }, $modelList);
    }

    public function saveCredentialSource(PublicKeyCredentialSource $publicKeyCredentialSource): void
    {
        $model = $this->findOneModelByCredentialId($publicKeyCredentialSource->getPublicKeyCredentialId());
        if ($model === null) {
            $model = new WebauthnCredential();
            $model->setPublicKeyCredentialSourceAttribute($publicKeyCredentialSource);
        }
        $model->counter += 1;
        $model->last_used_at = now();
        $model->save();
    }

    private function findOneModelByCredentialId(string $publicKeyCredentialId): ?WebauthnCredential
    {
        /**
         * @var WebauthnCredential
         */
        return WebauthnCredential::query()->where(function (Builder $query) use ($publicKeyCredentialId) {
            $query->where("credential_id", "=", base64_encode($publicKeyCredentialId));
        })->first();
    }

    private function findAllModelByTypeFree(): array
    {
        return WebauthnCredential::query()->where("type_free", "=", "1")->get()->all();
    }

    private function findAllModelByUserId(string $userId): array
    {
        return WebauthnCredential::query()->where("user_id", "=", $userId)->get()->all();
    }
}