package com.suno.android.common_data.repos import arrow.core.Either import arrow.core.getOrElse import com.suno.android.common_core_utils.Id import com.suno.android.common_core_utils.SunoLogger import com.suno.android.common_data.mappers.projects.ProjectData import com.suno.android.common_data.mappers.projects.xAsProjectData import com.suno.android.common_networking.extensions.ApiResult import com.suno.android.common_networking.extensions.toThrowable import com.suno.android.common_networking.remote.entities.ProjectCreateSpec import com.suno.android.common_networking.remote.entities.ProjectTrashSpec import com.suno.android.common_networking.remote.entities.ProjectsSchema import com.suno.android.common_networking.remote.projects.ProjectsService import jakarta.inject.Inject interface ProjectsRepository { suspend fun getMyProjects( page: Int = 0, ): ProjectsSchema? suspend fun getProjectById( projectId: Id, page: Int = 0, isLiked: Boolean? = null, hideDisliked: Boolean? = null, hideGenStems: Boolean? = null, hideStudioClips: Boolean? = null, isPublic: Boolean? = null, isUploadedAudio: Boolean? = null, isFullSong: Boolean? = null, isExtend: Boolean? = null, isCover: Boolean? = null, isPersona: Boolean? = null, isUpsample: Boolean? = null, ): ApiResult suspend fun createProject( projectName: String, ): ApiResult suspend fun deleteProject( projectId: Id, ): Either } class ProjectsRepositoryImpl @Inject constructor( loggerFactory: SunoLogger.Factory, private val projectsService: ProjectsService, ) : ProjectsRepository { private val logger = loggerFactory.create(this@ProjectsRepositoryImpl) override suspend fun getMyProjects( page: Int, ): ProjectsSchema? { val projects = projectsService.getMyProjects(page = page).getOrElse { error -> logger.e(error.toThrowable()) return null } return projects } override suspend fun getProjectById( projectId: Id, page: Int, isLiked: Boolean?, hideDisliked: Boolean?, hideGenStems: Boolean?, hideStudioClips: Boolean?, isPublic: Boolean?, isUploadedAudio: Boolean?, isFullSong: Boolean?, isExtend: Boolean?, isCover: Boolean?, isPersona: Boolean?, isUpsample: Boolean?, ): ApiResult = projectsService.getProjectById( projectId = projectId.value, page = page, isLiked = isLiked, hideDisliked = hideDisliked, hideGenStems = hideGenStems, hideStudioClips = hideStudioClips, isPublic = isPublic, isUploadedAudio = isUploadedAudio, isFullSong = isFullSong, isExtend = isExtend, isCover = isCover, isPersona = isPersona, isUpsample = isUpsample, ).map { it.xAsProjectData() } override suspend fun createProject( projectName: String, ): ApiResult { val spec = ProjectCreateSpec( name = projectName, description = "", ) return projectsService.createProject(spec).map { result -> result.xAsProjectData() } } override suspend fun deleteProject( projectId: Id, ): Either = projectsService.trashProject( ProjectTrashSpec( projectId = projectId.value, undo = false, ), ).mapLeft { Unit } }