// // AnalyticsEvent.swift // SportsTime // // Type-safe analytics event definitions. // import Foundation enum AnalyticsEvent { // MARK: - Navigation case tabSwitched(tab: String, previousTab: String?) case screenViewed(screen: String) // MARK: - Trip Planning case tripWizardStarted(mode: String) case tripWizardStepCompleted(step: String, mode: String) case tripPlanned(sportCount: Int, stopCount: Int, dayCount: Int, mode: String) case tripPlanFailed(mode: String, error: String) case tripSaved(tripId: String, stopCount: Int, gameCount: Int) case tripDeleted(tripId: String) case tripViewed(tripId: String, source: String) case suggestedTripTapped(region: String, stopCount: Int) // MARK: - Schedule case scheduleViewed(sports: [String]) case scheduleFiltered(sport: String, dateRange: String) case gameTapped(gameId: String, sport: String, homeTeam: String, awayTeam: String) // MARK: - Progress case stadiumVisitAdded(stadiumId: String, sport: String) case stadiumVisitDeleted(stadiumId: String, sport: String) case progressCardShared(sport: String) case sportSwitched(sport: String) // MARK: - Export case pdfExportStarted(tripId: String, stopCount: Int) case pdfExportCompleted(tripId: String) case pdfExportFailed(tripId: String, error: String) case tripShared(tripId: String) // MARK: - IAP case paywallViewed(source: String) case purchaseStarted(productId: String) case purchaseCompleted(productId: String) case purchaseFailed(productId: String, error: String) case purchaseRestored case subscriptionStatusChanged(isPro: Bool, plan: String?) // MARK: - Settings case themeChanged(from: String, to: String) case appearanceChanged(mode: String) case sportToggled(sport: String, enabled: Bool) case animationsToggled(enabled: Bool) case drivingHoursChanged(hours: Int) case analyticsToggled(enabled: Bool) case settingsReset // MARK: - Polls case pollCreated(optionCount: Int) case pollVoted(pollId: String) case pollShared(pollId: String) // MARK: - Onboarding case onboardingPaywallViewed case onboardingPaywallDismissed // MARK: - Errors case errorOccurred(domain: String, message: String, screen: String?) // MARK: - Computed Properties var name: String { switch self { case .tabSwitched: return "tab_switched" case .screenViewed: return "screen_viewed" case .tripWizardStarted: return "trip_wizard_started" case .tripWizardStepCompleted: return "trip_wizard_step_completed" case .tripPlanned: return "trip_planned" case .tripPlanFailed: return "trip_plan_failed" case .tripSaved: return "trip_saved" case .tripDeleted: return "trip_deleted" case .tripViewed: return "trip_viewed" case .suggestedTripTapped: return "suggested_trip_tapped" case .scheduleViewed: return "schedule_viewed" case .scheduleFiltered: return "schedule_filtered" case .gameTapped: return "game_tapped" case .stadiumVisitAdded: return "stadium_visit_added" case .stadiumVisitDeleted: return "stadium_visit_deleted" case .progressCardShared: return "progress_card_shared" case .sportSwitched: return "sport_switched" case .pdfExportStarted: return "pdf_export_started" case .pdfExportCompleted: return "pdf_export_completed" case .pdfExportFailed: return "pdf_export_failed" case .tripShared: return "trip_shared" case .paywallViewed: return "paywall_viewed" case .purchaseStarted: return "purchase_started" case .purchaseCompleted: return "purchase_completed" case .purchaseFailed: return "purchase_failed" case .purchaseRestored: return "purchase_restored" case .subscriptionStatusChanged: return "subscription_status_changed" case .themeChanged: return "theme_changed" case .appearanceChanged: return "appearance_changed" case .sportToggled: return "sport_toggled" case .animationsToggled: return "animations_toggled" case .drivingHoursChanged: return "driving_hours_changed" case .analyticsToggled: return "analytics_toggled" case .settingsReset: return "settings_reset" case .pollCreated: return "poll_created" case .pollVoted: return "poll_voted" case .pollShared: return "poll_shared" case .onboardingPaywallViewed: return "onboarding_paywall_viewed" case .onboardingPaywallDismissed: return "onboarding_paywall_dismissed" case .errorOccurred: return "error_occurred" } } var properties: [String: Any] { switch self { case .tabSwitched(let tab, let previousTab): var props: [String: Any] = ["tab_name": tab] if let prev = previousTab { props["previous_tab"] = prev } return props case .screenViewed(let screen): return ["screen_name": screen] case .tripWizardStarted(let mode): return ["mode": mode] case .tripWizardStepCompleted(let step, let mode): return ["step_name": step, "mode": mode] case .tripPlanned(let sportCount, let stopCount, let dayCount, let mode): return ["sport_count": sportCount, "stop_count": stopCount, "day_count": dayCount, "mode": mode] case .tripPlanFailed(let mode, let error): return ["mode": mode, "error": error] case .tripSaved(let tripId, let stopCount, let gameCount): return ["trip_id": tripId, "stop_count": stopCount, "game_count": gameCount] case .tripDeleted(let tripId): return ["trip_id": tripId] case .tripViewed(let tripId, let source): return ["trip_id": tripId, "source": source] case .suggestedTripTapped(let region, let stopCount): return ["region": region, "stop_count": stopCount] case .scheduleViewed(let sports): return ["sports": sports] case .scheduleFiltered(let sport, let dateRange): return ["sport": sport, "date_range": dateRange] case .gameTapped(let gameId, let sport, let homeTeam, let awayTeam): return ["game_id": gameId, "sport": sport, "home_team": homeTeam, "away_team": awayTeam] case .stadiumVisitAdded(let stadiumId, let sport): return ["stadium_id": stadiumId, "sport": sport] case .stadiumVisitDeleted(let stadiumId, let sport): return ["stadium_id": stadiumId, "sport": sport] case .progressCardShared(let sport): return ["sport": sport] case .sportSwitched(let sport): return ["sport": sport] case .pdfExportStarted(let tripId, let stopCount): return ["trip_id": tripId, "stop_count": stopCount] case .pdfExportCompleted(let tripId): return ["trip_id": tripId] case .pdfExportFailed(let tripId, let error): return ["trip_id": tripId, "error": error] case .tripShared(let tripId): return ["trip_id": tripId] case .paywallViewed(let source): return ["source": source] case .purchaseStarted(let productId): return ["product_id": productId] case .purchaseCompleted(let productId): return ["product_id": productId] case .purchaseFailed(let productId, let error): return ["product_id": productId, "error": error] case .purchaseRestored: return [:] case .subscriptionStatusChanged(let isPro, let plan): var props: [String: Any] = ["is_pro": isPro] if let plan { props["plan"] = plan } return props case .themeChanged(let from, let to): return ["from": from, "to": to] case .appearanceChanged(let mode): return ["mode": mode] case .sportToggled(let sport, let enabled): return ["sport": sport, "enabled": enabled] case .animationsToggled(let enabled): return ["enabled": enabled] case .drivingHoursChanged(let hours): return ["hours": hours] case .analyticsToggled(let enabled): return ["enabled": enabled] case .settingsReset: return [:] case .pollCreated(let optionCount): return ["option_count": optionCount] case .pollVoted(let pollId): return ["poll_id": pollId] case .pollShared(let pollId): return ["poll_id": pollId] case .onboardingPaywallViewed: return [:] case .onboardingPaywallDismissed: return [:] case .errorOccurred(let domain, let message, let screen): var props: [String: Any] = ["domain": domain, "message": message] if let screen { props["screen"] = screen } return props } } }