import Combine
import Foundation

@MainActor
protocol AnalyticsTracking {
    func track(_ event: String, attributes: [String: String])
}

struct HermesTrackedEvent: Identifiable, Equatable {
    let id = UUID()
    let event: String
    let attributes: [String: String]
    let timestamp: Date
}

@MainActor
final class HermesAnalyticsClient: ObservableObject, AnalyticsTracking {
    @Published private(set) var trackedEvents: [HermesTrackedEvent] = []

    func track(_ event: String, attributes: [String: String]) {
        trackedEvents.append(
            HermesTrackedEvent(
                event: event,
                attributes: attributes,
                timestamp: Date()
            )
        )
    }

    func flush(using repository: HermesRepository) async {
        guard repository.currentSession != nil else {
            return
        }

        let pendingEvents = trackedEvents
        guard !pendingEvents.isEmpty else {
            return
        }

        do {
            try await repository.submitAnalyticsBatch(
                HermesAnalyticsBatchRequest(
                    events: pendingEvents.map { event in
                        HermesAnalyticsEventInput(
                            eventName: event.event,
                            occurredAt: event.timestamp,
                            attributes: event.attributes.map { HermesAnalyticsAttributeInput(key: $0.key, value: $0.value) }
                        )
                    }
                )
            )

            let deliveredIds = Set(pendingEvents.map(\.id))
            trackedEvents.removeAll { deliveredIds.contains($0.id) }
        } catch {
            return
        }
    }
}
