package id.iiyh.inatrading.feature.favorite.data.repository

import id.iiyh.inatrading.core.data.remote.ApiService
import id.iiyh.inatrading.core.data.remote.SessionExpiredException
import id.iiyh.inatrading.feature.favorite.data.model.AddToFavoriteRequest
import id.iiyh.inatrading.feature.favorite.data.model.FavoriteCreateRequest
import id.iiyh.inatrading.feature.favorite.domain.FavoriteGroupProduct
import id.iiyh.inatrading.feature.favorite.domain.FavoriteGroupSummary
import id.iiyh.inatrading.feature.favorite.domain.FavoriteRepository
import kotlinx.coroutines.async
import kotlinx.coroutines.awaitAll
import kotlinx.coroutines.coroutineScope
import retrofit2.HttpException
import javax.inject.Inject

class FavoriteRepositoryImpl @Inject constructor(
    private val apiService: ApiService,
) : FavoriteRepository {

    override suspend fun getFavoriteGroups(): Result<List<FavoriteGroupSummary>> {
        return try {
            val response = apiService.getFavorites()
            if (!response.isSuccess) {
                return Result.failure(Exception(response.responseDesc ?: "Gagal memuat koleksi favorit"))
            }

            val groups = coroutineScope {
                response.rows.map { group ->
                    async {
                        val itemResponse = apiService.getFavoriteItems(group.id)
                        val itemCount = if (itemResponse.isSuccess) {
                            itemResponse.totalItem.takeIf { it > 0 } ?: itemResponse.rows.size
                        } else {
                            0
                        }

                        FavoriteGroupSummary(
                            id = group.id,
                            name = group.name,
                            isDefault = group.isDefault,
                            itemCount = itemCount,
                        )
                    }
                }.awaitAll()
            }

            Result.success(groups)
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun createFavoriteGroup(name: String): Result<Unit> {
        return try {
            val response = apiService.createFavorite(FavoriteCreateRequest(name = name))
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal membuat koleksi favorit"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun getFavoriteGroupItems(favoriteId: String): Result<List<FavoriteGroupProduct>> {
        return try {
            val response = apiService.getFavoriteItems(favoriteId)
            if (!response.isSuccess) {
                return Result.failure(Exception(response.responseDesc ?: "Gagal memuat item favorit"))
            }

            Result.success(
                response.rows.mapNotNull { item ->
                    val productId = item.productId ?: return@mapNotNull null
                    val productName = item.productName ?: return@mapNotNull null
                    FavoriteGroupProduct(
                        id = item.id ?: productId,
                        productId = productId,
                        productName = productName,
                        productDescription = item.productDescription,
                        productImage = item.productImage,
                        sellerName = item.sellerName,
                    )
                }
            )
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun updateFavoriteGroup(favoriteId: String, name: String): Result<Unit> {
        return try {
            val response = apiService.updateFavorite(
                favoriteId = favoriteId,
                request = FavoriteCreateRequest(name = name),
            )
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal mengubah nama koleksi"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun deleteFavoriteGroup(favoriteId: String): Result<Unit> {
        return try {
            val response = apiService.deleteFavoriteItem(productId = favoriteId)
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal menghapus koleksi"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun addProductToFavorite(favoriteId: String, productId: String): Result<Unit> {
        return try {
            val response = apiService.addToFavorite(
                AddToFavoriteRequest(
                    favoriteId = favoriteId,
                    productId = productId,
                )
            )
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal menambahkan produk ke favorit"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun removeProductFromFavorite(productId: String): Result<Unit> {
        return try {
            val response = apiService.deleteFavoriteItem(productId = productId)
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal menghapus produk dari favorit"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    private fun HttpException.toRepositoryException(): Exception {
        if (code() == 401) return SessionExpiredException()
        return Exception(parseMessage())
    }

    private fun HttpException.parseMessage(): String {
        return try {
            val body = response()?.errorBody()?.string() ?: return "Terjadi kesalahan (${code()})"
            val match = Regex(""""responseDesc"\s*:\s*"([^"]+)"""").find(body)
            match?.groupValues?.get(1) ?: "Terjadi kesalahan (${code()})"
        } catch (_: Exception) {
            "Terjadi kesalahan (${code()})"
        }
    }
}
