package com.example.scanwich import android.graphics.Bitmap import android.util.Base64 import com.google.firebase.Firebase import com.google.firebase.functions.functions import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import java.io.ByteArrayOutputStream import java.text.SimpleDateFormat import java.util.* fun Float.format(digits: Int) = "%.${digits}f".format(this) fun getOptimizedImageBase64(bitmap: Bitmap): String { val outputStream = ByteArrayOutputStream() val width = bitmap.width val height = bitmap.height val maxSize = 1024 val (newWidth, newHeight) = if (width > maxSize || height > maxSize) { val ratio = width.toFloat() / height.toFloat() if (width > height) { maxSize to (maxSize / ratio).toInt() } else { (maxSize * ratio).toInt() to maxSize } } else { width to height } val resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true) resized.compress(Bitmap.CompressFormat.JPEG, 70, outputStream) return Base64.encodeToString(outputStream.toByteArray(), Base64.NO_WRAP) } fun parseStravaDate(dateStr: String): Long { return try { val inputFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'", Locale.US) inputFormat.timeZone = TimeZone.getTimeZone("UTC") inputFormat.parse(dateStr)?.time ?: 0L } catch (_: Exception) { 0L } } fun estimateCaloriesFromDb(activity: SportActivity, weightKg: Double): Int { if (activity.calories != null && activity.calories > 0) return activity.calories.toInt() val met = when (activity.type.lowercase()) { "run" -> 10.0 "ride" -> 8.0 "walk" -> 3.5 "hike" -> 6.0 "swim" -> 7.0 "weighttraining" -> 5.0 "workout" -> 4.5 else -> 5.0 } val durationHours = activity.movingTime / 3600.0 return (met * weightKg * durationHours).toInt() } fun analyzeImage( bitmap: Bitmap?, textDescription: String?, setAnalyzing: (Boolean) -> Unit, onResult: (Triple>?, String?) -> Unit, scope: CoroutineScope ) { setAnalyzing(true) scope.launch { try { val base64 = withContext(Dispatchers.Default) { bitmap?.let { getOptimizedImageBase64(it) } } val data = hashMapOf("imageBase64" to base64, "mealName" to textDescription) Firebase.functions("us-central1") .getHttpsCallable("analyzeMealProxy") .call(data) .addOnSuccessListener { result -> try { val responseData = result.data as? Map<*, *> if (responseData != null) { onResult(Triple( (responseData["name"] as? String) ?: textDescription ?: "Repas", (responseData["description"] as? String) ?: "Analyse réussie", listOf( (responseData["calories"] as? Number)?.toInt() ?: 0, (responseData["carbs"] as? Number)?.toInt() ?: 0, (responseData["protein"] as? Number)?.toInt() ?: 0, (responseData["fat"] as? Number)?.toInt() ?: 0 ) ), null) } else { onResult(null, "Format invalide") } } catch (e: Exception) { onResult(null, e.message) } setAnalyzing(false) } .addOnFailureListener { e -> onResult(null, e.message) setAnalyzing(false) } } catch (e: Exception) { onResult(null, e.localizedMessage) setAnalyzing(false) } } }