package dev.inmo.postssystem.services.posts.server

import dev.inmo.micro_utils.common.*
import dev.inmo.micro_utils.repos.create
import dev.inmo.micro_utils.repos.deleteById
import dev.inmo.postssystem.features.content.common.Content
import dev.inmo.postssystem.features.content.common.ContentId
import dev.inmo.postssystem.features.content.server.storage.ServerContentStorage
import dev.inmo.postssystem.features.posts.common.*
import dev.inmo.postssystem.features.posts.server.ServerPostsStorage
import dev.inmo.postssystem.services.posts.common.FullNewPost
import dev.inmo.postssystem.services.posts.common.WritePostsService

class DefaultWritePostsService(
    private val postsStorage: ServerPostsStorage,
    private val contentStorage: ServerContentStorage<Content>
) : WritePostsService {
    override suspend fun create(newPost: FullNewPost): RegisteredPost? {
        val contentIds = contentStorage.create(newPost.content).map { it.id }

        return postsStorage.create(NewPost(contentIds)).firstOrNull()
    }

    override suspend fun update(postId: PostId, content: List<Either<ContentId, Content>>): RegisteredPost? {
        if (!postsStorage.contains(postId)) {
            return null
        }

        val newContent = content.mapNotNull {
            when (it) {
                is EitherFirst -> {
                    it.t1
                }
                is EitherSecond -> {
                    contentStorage.create(it.t2).firstOrNull() ?.id
                }
            }
        }

        return postsStorage.update(
            postId,
            NewPost(newContent)
        )
    }

    override suspend fun remove(postId: PostId) {
        return postsStorage.deleteById(postId)
    }
}
