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

import id.iiyh.inatrading.core.data.remote.ApiService
import id.iiyh.inatrading.core.data.remote.SessionExpiredException
import id.iiyh.inatrading.feature.cart.data.model.CartCreateRequest
import id.iiyh.inatrading.feature.cart.data.model.CartGroup
import id.iiyh.inatrading.feature.cart.data.model.CartUpdateRequest
import id.iiyh.inatrading.feature.cart.domain.CartRepository
import retrofit2.HttpException
import javax.inject.Inject

class CartRepositoryImpl @Inject constructor(
    private val apiService: ApiService,
) : CartRepository {

    override suspend fun getCartGroups(): Result<List<CartGroup>> {
        return try {
            val response = apiService.getCarts()
            if (!response.isSuccess) {
                Result.failure(Exception(response.responseDesc ?: "Gagal memuat keranjang"))
            } else {
                Result.success(response.rows.sanitized())
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun getCartCount(): Result<Int> {
        return try {
            val response = apiService.getCarts()
            if (!response.isSuccess) {
                return Result.failure(Exception(response.responseDesc ?: "Gagal memuat keranjang"))
            }
            val sanitizedGroups = response.rows.sanitized()
            val count = sanitizedGroups.sumOf { it.cartItems.size }
                .takeIf { it > 0 }
                ?: sanitizedGroups.sumOf { group ->
                    group.cartItems.sumOf { item -> item.quantity ?: 0 }
                }.takeIf { it > 0 }
                ?: response.totalItem.takeIf { it > 0 }
                ?: 0
            Result.success(count)
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun updateCartQuantity(
        cartItemId: String,
        quantityDelta: Int,
    ): Result<Unit> {
        return try {
            val response = apiService.updateCart(
                CartUpdateRequest(
                    cartItemId = cartItemId,
                    quantity = quantityDelta,
                )
            )
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal memperbarui jumlah keranjang"))
            }
        } catch (e: HttpException) {
            Result.failure(e.toRepositoryException())
        } catch (e: Exception) {
            Result.failure(e)
        }
    }

    override suspend fun addToCart(
        sellerId: String,
        productModelId: String,
        warehouseId: String,
        quantity: Int,
        productMeasurementId: String,
    ): Result<Unit> {
        return try {
            val response = apiService.createCart(
                CartCreateRequest(
                    sellerId = sellerId,
                    quantity = quantity,
                    productModelId = productModelId,
                    productMeasurementId = productMeasurementId,
                    warehouseId = warehouseId,
                )
            )
            if (response.isSuccess) {
                Result.success(Unit)
            } else {
                Result.failure(Exception(response.responseDesc ?: "Gagal menambahkan produk ke keranjang"))
            }
        } 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()})"
        }
    }

    private fun List<CartGroup>.sanitized(): List<CartGroup> {
        return map { group ->
            group.copy(
                cartItems = group.cartItems.filter { item -> (item.quantity ?: 0) > 0 }
            )
        }.filter { it.cartItems.isNotEmpty() }
    }
}
