import Foundation

/// Use this when creating new events, as it serves as a source-of-truth for analytics events
public extension Event {
    enum General {
        // We don't need to pass `screenName` or `screenId` in as it's implicitly picked up by the tracking event
        // Internal as it's only called by `AnalyticsClient`
        static func newScreen() -> Event {
            // Important to set the screen before calling `trackV2`, as this will pass the current `screenName` implicitly to the logging event
            Event(
                category: .general,
                actionName: .newScreen
            )
        }
    }
}

public extension Event {
    enum ActionName: String, Codable {
        // MARK: System

        case settingsOpened = "settings_opened"
        case dismissed
        case setNotificationsAsRead = "set_notifications_as_read"
        case newScreen = "new_screen"
        case handleDeepLinkUrl = "handle_deep_link_url"

        case didFinishLaunching
        case rootDestinationChanged

        // MARK: Loading / Fetching

        case contactPermissionsChecked = "contact_permissions_checked"
        case contactPermissionsRequested = "contact_permissions_requested"
        case contactPermissionsAllowed = "contact_permissions_allowed"
        case contactPermissionsDenied = "contact_permissions_denied"
        case smsComposeResultCancelled = "sms_compose_result_cancelled"
        case smsComposeResultFailed = "sms_compose_result_failed"
        case smsComposeResultSent = "sms_compose_result_sent"
        case addPhoneNumberSucceeded = "add_phone_number_succeeded"
        case addPhoneNumberFailed = "add_phone_number_failed"
        case phoneCodeSent = "phone_code_sent"
        case phoneCodeValidationStarted = "phone_code_validation_started"
        case phoneCodeValidationSucceeded = "phone_code_validation_succeeded"
        case phoneCodeValidationFailed = "phone_code_validation_failed"
        case phoneNumberAlreadyValidated = "phone_number_already_validated"
        case phoneNumberValidationFailed = "phone_number_validation_failed"
        case loadMyProfileStarted = "load_my_profile_started"
        case loadPublicProfileStarted = "load_public_profile_started"
        case loadCurrentUserStarted = "load_current_user_started"
        case signInSucceeded = "sign_in_succeeded"
        case phoneVerificationCodeResponse = "phone_verification_code_response"
        case signInFailed = "sign_in_failed"
        case signInFinished = "sign_in_finished"
        case onboardingFlowStarted = "onboarding_flow_started"
        case onboardingFlowFinished = "onboarding_flow_finished"
        case onboardingContactSyncStarted = "onboarding_contact_sync_started"
        case signUpSucceeded = "sign_up_succeeded"
        case signUpFailed = "sign_up_failed"
        case signedOut = "signed_out"
        case updateNameSucceeded = "update_name_succeeded"
        case updateNameFailed = "update_name_failed"
        case updateUsernameSucceeded = "update_username_succeeded"
        case updateUsernameFailed = "update_username_failed"
        case updateDisplayNameSucceeded = "update_display_name_succeeded"
        case updateDisplayNameFailed = "update_display_name_failed"
        case updateHandleSucceeded = "update_handle_succeeded"
        case updateHandleFailed = "update_handle_failed"
        case clipCreationSucceeded = "clip_creation_succeeded"
        case clipCreationFailed = "clip_creation_failed"
        case clipGenerationComplete = "clip_generation_completion"
        case serviceStatusFetchSucceeded = "service_status_fetch_succeeded"
        case serviceStatusFetchFailed = "service_status_fetch_failed"
        case billingInfoFetchSucceeded = "billing_info_fetch_succeeded"
        case billingInfoFetchFailed = "billing_info_fetch_failed"
        case deepLinkClipFetchSucceeded = "deep_link_clip_fetch_succeeded"
        case deepLinkClipFetchFailed = "deep_link_clip_fetch_failed"
        case deepLinkPlaylistFetchSucceeded = "deep_link_playlist_fetch_succeeded"
        case deepLinkPlaylistFetchFailed = "deep_link_playlist_fetch_failed"
        case deepLinkHookFetchSucceeded = "deep_link_hook_fetch_succeeded"
        case deepLinkHookFetchFailed = "deep_link_hook_fetch_failed"
        case audioRecordingFinishedWithSuccess = "audio_recording_finished_with_success"
        case audioRecordingFinishedWithFailure = "audio_recording_finished_with_failure"
        case audioUploadStarted = "audio_upload_started"
        case audioUploadSucceeded = "audio_upload_succeeded"
        case audioUploadFailed = "audio_upload_failed"
        case videoUploadToS3Succeeded = "video_upload_to_s3_succeeded"
        case videoUploadToS3Failed = "video_upload_to_s3_failed"
        case videoUploadSucceeded = "video_upload_succeeded"
        case videoUploadFailed = "video_upload_failed"
        case promoCodeAccepted = "promo_code_accepted"
        case promoCodeRejected = "promo_code_rejected"
        case promoCodeSheetShown = "promo_code_sheet_shown"
        case promoCodeAlertDismissed = "promo_code_alert_dismissed"
        case somethingWentWrongAlertShown = "something_went_wrong_alert_shown"
        case joinWaitlistSucceeded = "join_waitlist_succeeded"
        case loadWelcomeVideoStarted = "load_welcome_video_started"
        case loadWelcomeVideoFailed = "load_welcome_video_failed"
        case welcomeVideoFinishedPlaying = "welcome_video_finished_playing"
        case remoteNotificationsRegistrationSucceeded = "remote_notifications_registration_succeeded"
        case remoteNotificationsRegistrationFailed = "remote_notifications_registration_failed"
        case notificationsPermissionsStatus = "notifications_permissions_status"
        case notificationsPermissionsRequested = "notifications_permissions_requested"
        case notificationsPermissionsAllowed = "notifications_permissions_allowed"
        case notificationsPermissionsDenied = "notifications_permissions_denied"
        case notificationsPermissionsError = "notifications_permissions_error"
        case birthdayUpdateCompleted = "birthday_update_completed"
        case birthdayUpdateFailed = "birthday_update_failed"
        case musicGenresUpdateSucceeded = "music_genres_update_succeeded"
        case musicGenresUpdateFailed = "music_genres_update_failed"
        case attPromptResponse = "att_prompt_response"

        // MARK: Gestures

        case permissionRequestAlertOpenSettingsTapped = "permission_request_alert_open_settings_tapped"
        case permissionRequestAlertCancelOpenSettingsTapped = "permission_request_alert_cancel_open_settings_tapped"
        case bannerTapped = "banner_tapped"
        case dismissTapped = "dismiss_tapped"
        case followTapped = "follow_tapped"
        case unfollowTapped = "unfollow_tapped"
        case backTapped = "back_tapped"
        case inviteContactTapped = "invite_contact_tapped"
        case closeTapped = "close_tapped"
        case confirmTapped = "confirm_tapped"
        case skipTapped = "skip_tapped"
        case resendTapped = "resent_tapped"
        case cancelTapped = "cancel_tapped"
        case hideRecommendedUserTapped = "hide_recommended_user_tapped"
        case showMoreTapped = "show_more_tapped"
        case showMoreHooksTapped = "show_more_hooks_tapped"
        case shareTapped = "share_tapped"
        case playAllTapped = "play_all_tapped"
        case playTapped = "play_tapped"
        case notificationsTapped = "notifications_tapped"
        case addPhoneNumberBannerTapped = "add_phone_number_banner_tapped"
        case profileTapped = "profile_tapped"
        case clipOrPlaylistTapped = "clip_or_playlist_tapped"
        case doneTapped = "done_tapped"
        case welcomePageAppeared = "welcome_page_appeared"
        case signInTapped = "sign_in_tapped"
        case signUpTapped = "sign_up_tapped"
        case updateDisplayNameTapped = "update_display_name_tapped"
        case updateHandleTapped = "update_handle_tapped"
        case searchTapped = "search_tapped"
        case menuTapped = "menu_tapped"
        case createTapped = "create_tapped"
        case showGeneratedClipsTapped = "show_generated_clips_tapped"
        case upgradeTapped = "upgrade_tapped"
        case infoTapped = "info_tapped"
        case uploadTapped = "upload_tapped"
        case folderTapped = "folder_tapped"
        case stopTapped = "stop_tapped"
        case restartTapped = "restart_tapped"
        case trashTapped = "trash_tapped"
        case pauseTapped = "pause_tapped"
        case deleteTapped = "delete_tapped"
        case noRedirectTriggered = "no_redirect_triggered"
        case redirectToProfile = "redirect_to_profile"
        case redirectToClip = "redirect_to_clip"
        case redirectToHook = "redirect_to_hook"
        case redirectToURL = "redirect_to_url"
        case redirectToPlaylist = "redirect_to_playlist"
        case enterLyricsExpandedTapped = "enter_lyrics_expanded_tapped"
        case exitLyricsExpandedTapped = "exit_lyrics_expanded_tapped"
        case acceptTOSTapped = "accept_TOS_tapped"
        case confirmDeleteTapped = "confirm_delete_tapped"
        case selectRandomStyleTapped = "select_random_style_tapped"
        case selectStyleTapped = "select_style_tapped"
        case generateLyricsTapped = "generate_lyrics_tapped"
        case photoTaken = "photo_taken"
        case videoRecordingStarted = "recording_started"
        case videoRecordingStopped = "recording_stopped"
        case enableCameraFlashTapped = "enable_camera_flash_tapped"
        case disableCameraFlashTapped = "disable_camera_flash_tapped"
        case mediaPickerImageSelected = "media_picker_image_selected"
        case mediaPickerVideoSelected = "media_picker_video_selected"
        case mediaPickerTapped = "media_picker_tapped"
        case audioModeSet = "audio_mode_set"
        case tabTapped = "tab_tapped"
        case saveTapped = "save_tapped"
        case dragEnded = "drag_ended"
        case makePublicTapped = "make_public_tapped"
        case makePrivateTapped = "make_private_tapped"
        case addToPlaylistTapped = "add_to_playlist_tapped"
        case reportInappropriateTapped = "report_inappropriate_tapped"
        case reuseTapped = "reuse_tapped"
        case remasterTapped = "remaster_tapped"
        case downloadSongTapped = "download_song_tapped"
        case downloadVideoTapped = "download_video_tapped"
        case promoCodeEntered = "promo_code_entered"
        case joinWaitlistTapped = "join_waitlist_tapped"
        case visitWebsiteTapped = "visit_website_tapped"
        case copyInviteLinkTapped = "copy_invite_link_tapped"
        case languageSettingsTapped = "language_settings_tapped"
        case navigateToLanguageSettingsTapped = "navigate_to_language_settings_tapped"
        case reportProblemTapped = "report_problem_tapped"
        case muteTapped = "mute_tapped"
        case unmuteTapped = "unmute_tapped"
        case audioLengthUpsellTapped = "audio_length_upsell_tapped"
        case aukTooltipUpgradeTapped = "auk_tooltip_upgrade_tapped"

        // MARK: Presentation

        case viewAppeared = "view_appeared"
        case contactsAuthorizationAlertShown = "contacts_authorization_alert_shown"
        case showBrandedAlert = "show_branded_alert"
        case mediaPickerDismissed = "media_picker_dismissed"
        case videoTrimmerPresented = "video_trimmer_presented"
        case videoTrimmerDismissed = "video_trimmer_dismissed"
        case showSubscriptions = "show_subscriptions"
        case showDurationError = "show_duration_error"
        case showAukTooltip = "show_auk_tooltip"
        case aukTooltipDismissed = "auk_tooltip_dismissed"

        // MARK: Audio

        case pauseAndDismissPlayer = "pause_and_dismiss_player"
        case playNewClips = "play_new_clips"
        case audioReachedEndTime = "audio_reached_end_time"

        // MARK: Audio Player

        // Basic playback controls
        case playNewSong = "PlayNewSong"
        case playNewSongPauseSong = "PlayNewSongPauseSong"
        case songEnd = "SongEnd"
        case playSong = "PlaySong"
        case pauseSong = "PauseSong"

        // Auto repeat and advancing
        case autoRepeatPlayNewSong = "AutoRepeatPlayNewSong"
        case autoRepeatPlaySong = "AutoRepeatPlaySong"
        case endOfQueue = "EndOfQueue"

        // Seeking
        case seekProgressBarPauseSong = "SeekProgressBarPauseSong"
        case seekProgressBarPlaySong = "SeekProgressBarPlaySong"

        // Backwards navigation
        case backwardPauseSong = "BackwardPauseSong"
        case backwardRepeatSong = "BackwardRepeatSong"
        case backwardPlayNewSong = "BackwardPlayNewSong"

        // Forwards navigation
        case forwardPausePreSong = "ForwardPausePreSong"
        case forwardPlayNewSong = "ForwardPlayNewSong"

        // Player expansions and actions
        case omniplayerExpanded = "OmniplayerExpanded"
        case omniplayerClosed = "OmniplayerClosed"
        case omniplayerCollapsed = "OmniplayerCollapsed"
        case omniplayerOpenedForComment = "OmniplayerOpenedForComment"
        case omniplayerGenerateMore = "OmniplayerGenerateMore"
        case omniplayerEditPrompt = "OmniplayerEditPrompt"
        case omniplayerLikeTapped = "LikeSong"
        case omniplayerUndoLikeTapped = "UndoLikeSong"
        case omniplayerDislikeTapped = "DislikeSong"
        case omniplayerUndoDislikeTapped = "UndoDislikeSong"
        case omniplayerSeeMoreInfo = "OmniplayerSeeMoreInfo"

        // MARK: Comments

        case commentTrackTimestampTapped = "CommentTrackTimestampTapped"

        // MARK: Hooks Player

        case playNewHook = "PlayNewHook"
        case pauseHook = "PauseHook"
        case playHook = "PlayHook"
        case autoRepeatPlayHook = "AutoRepeatPlayHook"
        case autoRepeatPauseHook = "AutoRepeatPauseHook"
        case scrollUpPauseHook = "ScrollUpPauseHook"
        case scrollDownPauseHook = "ScrollDownPauseHook"
        case scrollUpPlayNewHook = "ScrollUpPlayNewHook"
        case scrollDownPlayNewHook = "ScrollDownPlayNewHook"

        // Pause hook events
        case tapCreateHookPauseHook = "TapCreateHookPauseHook"
        case tapCreateSongPauseHook = "TapCreateSongPauseHook"
        case tapTabPauseHook = "TapTabPauseHook"
        case tapProfilePauseHook = "TapProfilePauseHook"
        case closeOmniPlayerPauseSong = "CloseOmniPlayerPauseSong"
        case closeOmniPlayerPlayHook = "CloseOmniPlayerPlayHook"
        case inactiveAppPauseHook = "InactiveAppPauseHook"
        case backgroundAppPauseHook = "BackgroundAppPauseHook"
        case tapSongPillPauseHook = "TapSongPillPauseHook"
        case tapBackPauseHook = "TapBackPauseHook"
        case openDeeplinkPauseHook = "OpenDeeplinkPauseHook"
        case tapCoverPauseHook = "TapCoverPauseHook"
        case tapExtendPauseHook = "TapExtendPauseHook"
        // Play hook events
        case tapTabPlayHook = "TapTabPlayHook"
        case closeCreateHookPlayHook = "CloseCreateHookPlayHook"
        case closeCreateSongPlayHook = "CloseCreateSongPlayHook"
        case foregroundAppPlayHook = "ForegroundAppPlayHook"
        case tapBackPlayHook = "TapBackPlayHook"
        case openDeeplinkPlayHook = "OpenDeeplinkPlayHook"
        case closeCoverPlayHook = "CloseCoverPlayHook"
        case closeExtendPlayHook = "CloseExtendPlayHook"

        case tapSongPillPlayNewSong = "TapSongPillPlayNewSong"

        // MARK: Create

        case startAudioRecording = "start_audio_recording"
        case resetAudioRecordingState = "reset_audio_recording_state"
        case finalAudioRecordingTime = "final_audio_recording_time"
        case audioUploadVerficationCompleted = "audio_upload_verification_completed"
        case lyricsUpdated = "lyrics_updated"
        case imageCaptured = "image_captured"
        case imageImported = "image_imported"
        case videoCaptured = "video_captured"
        case videoImported = "video_imported"
        case cameraFlashSet = "camera_flash_set"
        case videoReachedEndTime = "video_reached_end_time"

        // MARK: Extend / Clip Edits

        case extendSongActionTapped = "extend_song_action_tapped"
        case extendTapped = "extend_create_tapped"
        case applyExtensionTapped = "apply_extend_tapped"

        case coverSongActionTapped = "cover_song_action_tapped"
        case coverTapped = "cover_create_tapped"

        // MARK: Video Covers

        case replaceSongArtSongActionTapped = "replace_cover_art_song_action_tapped"
        case replaceSongArtTapped = "replace_song_art_tapped"

        // MARK: Song Details

        case editSongDetailsSongActionTapped = "edit_song_details_song_action_tapped"
        /// Title
        case saveSongDetailsSucceeded = "save_song_details_succeeded"
        case saveSongDetailsFailed = "save_song_details_failed"
        case titleAdded = "title_added"
        case titleUpdated = "title_updated"
        /// Captions
        case setCaptionTapped = "set_caption_tapped"
        case setCaptionFailed = "set_caption_failed"
        case captionAdded = "caption_added"
        case captionUpdated = "caption_updated"
        case captionDeleted = "caption_deleted"
        case editDisplayedLyricsTapped = "edit_displayed_lyrics_tapped"
        case editDisplayedLyricsDismissed = "edit_displayed_lyrics_dismissed"
        case editDisplayedLyricsSaveTapped = "edit_displayed_lyrics_save_tapped"
        case editDisplayedLyricsSucceeded = "edit_displayed_lyrics_succeeded"
        case displayedLyricsAdded = "displayed_lyrics_added"
        case displayedLyricsUpdated = "displayed_lyrics_updated"
        case displayedLyricsDeleted = "displayed_lyrics_deleted"
        case editDisplayedLyricsFailed = "edit_displayed_lyrics_failed"
        case previewTapped = "preview_tapped"
        case previewDismissed = "preview_dismissed"
        case moreSongDetailsOptionsTapped = "more_song_details_options_tapped"
        case moreSongDetailsOptionsDismissed = "more_song_details_options_dismissed"
        case commentsEnabled = "comments_enabled"
        case commentsDisabled = "comments_disabled"

        // MARK: Publish Flow

        case publishSongActionTapped = "publish_song_action_tapped"
        case publishTapped = "publish_tapped"
        case publishSucceeded = "publish_succeeded"
        case publishFailed = "publish_failed"

        // MARK: Paywall

        case paywallScreenAppeared
        case paywallTappedPurchaseSubscription
        case paywallPurchaseSucceeded

        // MARK: Share

        case shareSheetAppeared = "share_sheet_appeared"
        case shareAssetVisualizerCreationStart = "share_asset_visualizer_creation_start"
        case shareAssetVisualizerCreationSucceeded = "share_asset_visualizer_creation_succeeded"
        case shareAssetVisualizerCreationFailed = "share_asset_visualizer_creation_failed"
        case shareSheetDisappeared = "share_sheet_disappeared"
        case shareSheetReachedLoadingScreen = "share_sheet_reached_loading_screen"
        case shareSheetTakeUserToDestinationWithAsset = "share_sheet_take_user_to_destination_with_asset"

        case tappedShareDestination = "tapped_share_destination"

        // MARK: Promo cards on Home

        case promoCardPrimaryCtaTapped = "promo_card_primary_cta_tapped"
        case promoCardSecondaryCtaTapped = "promo_card_secondary_cta_tapped"

        // MARK: - Onboarding auth events

        case authMethodTapped = "auth_method_tapped"
        case authSucceeded = "auth_succeeded"
        case authFailed = "auth_failed"

        // MARK: - Madlibs onboarding events

        case madlibsContainerAppeared = "madlibs_container_appeared"
        case madlibsStepAppeared = "madlibs_step_appeared"
        case madlibsStepCompleted = "madlibs_step_completed"
        case madlibsNextTapped = "madlibs_next_tapped"
        case madlibsBackTapped = "madlibs_back_tapped"
        case madlibsSkipTapped = "madlibs_skip_tapped"
        case madlibsEntryPointAppeared = "madlibs_entry_point_appeared"
        case madlibsEntryPointCreatedTapped = "madlibs_entry_point_create_tapped"
        case madlibsEntryPointDismissTapped = "madlibs_entry_point_dismiss_tapped"
        case madlibsEntryPointCloseTapped = "madlibs_entry_point_close_tapped"

        // MARK: - SongActions events

        case songActionsLikeTapped = "song_actions_like_song"
        case songActionsUndoLikeTapped = "song_actions_undo_like_song"
        case songActionsDislikeTapped = "song_actions_dislike_song"
        case songActionsUndoDislikeTapped = "song_actions_undo_dislike_song"
        case songActionsMoreInfoTapped = "song_actions_more_info"
        case songActionsMenuOptionsTapped = "song_actions_menu_options_tapped"
        
        // MARK: - Sorting events
        case sortingMenuTapped = "sorting_options_menu_tapped"
        case sortingOptionSelected = "sorting_options_selected"

        // MARK: - Hooks Interaction Events

        case commentTapped = "comment_tapped"
        case commentBeginWrite = "comment_begin_write"
        case createHookTapped = "create_hook_tapped"
        case remixTapped = "remix_tapped"
        case swipeToProfile = "swipe_to_profile"
        case songPillTapped = "song_pill_tapped"
        case omniPlayerCloseTapped = "omni_player_close_tapped"
        case omniPlayerSwipeDown = "omni_player_swipe_down"
        case goToFullSongTapped = "go_to_full_song_tapped"
        case hookCardTapped = "hook_card_tapped"
        case moreTapped = "more_tapped"
        case tapToUnmuteTapped = "tap_to_unmute_tapped"
        case refreshFeedTapped = "refresh_feed_tapped"
        case feedExpandTapped = "feed_expand_tapped"
        case carouselItemTapped = "carousel_item_tapped"
        case carouselSwiped = "carousel_swiped"
        case hookOnboardingModalDismissTapped = "hook_onboarding_modal_dismiss_tapped"
        case hookDownloadTapped = "hook_download_tapped"

        // MARK: - Hook Create Events
        case recentSongsTabTapped = "recent_songs_tab_tapped"
        case publicSongsTabTapped = "public_songs_tab_tapped"
        case likedSongsTabTapped = "liked_songs_tab_tapped"
        case songTapped = "song_tapped"
        case songPlayPauseTapped = "song_play_pause_tapped"
        case songSelectionProceedTapped = "song_selection_proceed_tapped"
        case createNewSongTapped = "create_new_song_tapped"
        case videoSelected = "video_selected"
        case snippetSelectionTapped = "snippet_selection_tapped"
        case snippetSelectionWaveformDragStarted = "snippet_selection_waveform_drag_started"
        case snippetSelectionWaveformDragEnded = "snippet_selection_waveform_drag_ended"
        case snippetSelectionSaveTapped = "snippet_selection_save_tapped"
        case snippetSelectionCancelTapped = "snippet_selection_cancel_tapped"
        case videoTrimmerTapped = "video_trimmer_tapped"
        case volumeSelectorTapped = "volume_selector_tapped"
        case volumeSelectorSaveTapped = "volume_selector_save_tapped"
        case volumeSelectorCancelTapped = "volume_selector_cancel_tapped"
        case videoTrimmerHandleDragStarted = "video_trimmer_handle_drag_started"
        case videoTrimmerHandleDragEnded = "video_trimmer_handle_drag_ended"
        case videoTrimmerSaveTapped = "video_trimmer_save_tapped"
        case videoTrimmerCancelTapped = "video_trimmer_cancel_tapped"
        case nextTapped = "next_tapped"
        case confirmBackTapped = "confirm_back_tapped"
        case captionFieldFocused = "caption_field_focused"
        case captionFieldUnfocused = "caption_field_unfocused"
        case showLyricsToggled = "show_lyrics_toggled"
        case allowCommentsToggled = "allow_comments_toggled"
        case previewCloseTapped = "preview_close_tapped"
        case publishClipTapped = "publish_clip_tapped"
        case publishClipCloseTapped = "publish_clip_close_tapped"
        case postHookTapped = "post_hook_tapped"
    }
}

extension Event.ActionName: CustomStringConvertible {
    public var description: String { rawValue }
}
