package com.github.nullptroma.wallenc.infrastructure.android.db.app.repository

import com.github.nullptroma.wallenc.infrastructure.android.db.app.dao.YandexAccountDao
import com.github.nullptroma.wallenc.infrastructure.android.db.app.model.DbYandexAccount
import com.github.nullptroma.wallenc.domain.vault.model.YandexAccount
import com.github.nullptroma.wallenc.domain.vault.ports.YandexAccountStore
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext

class YandexAccountRepository(
    private val dao: YandexAccountDao,
    private val ioDispatcher: CoroutineDispatcher
) : YandexAccountStore {
    override fun observeAll(): Flow<List<YandexAccount>> = dao.observeAll().map { rows ->
        rows.map { it.toModel() }
    }

    override suspend fun getByYandexUserId(id: String): YandexAccount? = withContext(ioDispatcher) {
        dao.getByYandexUserId(id)?.toModel()
    }

    override suspend fun getByVaultUuid(vaultUuid: String): YandexAccount? = withContext(ioDispatcher) {
        dao.getByVaultUuid(vaultUuid)?.toModel()
    }

    override suspend fun insert(account: YandexAccount) = withContext(ioDispatcher) {
        dao.insert(fromModel(account))
    }

    override suspend fun updateCredentials(vaultUuid: String, email: String, token: String) =
        withContext(ioDispatcher) {
            dao.updateCredentials(vaultUuid, email, token)
        }

    override suspend fun deleteByVaultUuid(vaultUuid: String) = withContext(ioDispatcher) {
        dao.deleteByVaultUuid(vaultUuid)
    }

    private fun DbYandexAccount.toModel(): YandexAccount =
        YandexAccount(
            vaultUuid = vaultUuid,
            yandexUserId = yandexUserId,
            email = email,
            oauthToken = oauthToken,
        )

    private fun fromModel(model: YandexAccount): DbYandexAccount =
        DbYandexAccount(
            vaultUuid = model.vaultUuid,
            yandexUserId = model.yandexUserId,
            email = model.email,
            oauthToken = model.oauthToken,
        )
}
