package com.hermes.app.core.analytics

import android.util.Log
import com.hermes.app.domain.HermesAnalyticsAttributeInput
import com.hermes.app.domain.HermesAnalyticsBatchRequest
import com.hermes.app.domain.HermesAnalyticsEventInput
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.SharedFlow
import kotlinx.coroutines.flow.asSharedFlow
import kotlinx.datetime.Clock
import kotlinx.datetime.Instant
import java.util.UUID

data class HermesTrackedEvent(
    val id: UUID,
    val name: String,
    val attributes: Map<String, String>,
    val timestamp: Instant,
)

class HermesAnalyticsTracker {
    private val eventsFlow = MutableSharedFlow<HermesTrackedEvent>(replay = 64, extraBufferCapacity = 64)
    private val pendingEvents = mutableListOf<HermesTrackedEvent>()

    val events: SharedFlow<HermesTrackedEvent> = eventsFlow.asSharedFlow()

    @Synchronized
    fun track(name: String, attributes: Map<String, String> = emptyMap()) {
        val event = HermesTrackedEvent(UUID.randomUUID(), name, attributes, Clock.System.now())
        pendingEvents += event
        eventsFlow.tryEmit(event)
        Log.d("HermesAnalytics", "${event.name} ${event.attributes}")
    }

    @Synchronized
    fun pendingEventsSnapshot(): List<HermesTrackedEvent> {
        return pendingEvents.toList()
    }

    @Synchronized
    fun markDelivered(deliveredIds: Set<UUID>) {
        pendingEvents.removeAll { it.id in deliveredIds }
    }

    fun toBatchRequest(events: List<HermesTrackedEvent>): HermesAnalyticsBatchRequest {
        return HermesAnalyticsBatchRequest(
            events = events.map { event ->
                HermesAnalyticsEventInput(
                    eventName = event.name,
                    occurredAt = event.timestamp,
                    attributes = event.attributes.map { (key, value) ->
                        HermesAnalyticsAttributeInput(key = key, value = value)
                    },
                )
            },
        )
    }
}
