import AnalyticsClient

/// Represents all analytics events that can be tracked during the madlibs onboarding flow
public enum MadlibsAnalyticsEvent {
    case containerAppeared
    case stepViewed(step: MadlibsOnboardingProfileStep)
    case nextTapped(currentStep: MadlibsOnboardingProfileStep)
    case backTapped(currentStep: MadlibsOnboardingProfileStep, previousStep: MadlibsOnboardingProfileStep?)
    case skipTapped(currentStep: MadlibsOnboardingProfileStep, nextStep: MadlibsOnboardingProfileStep?)
    case notificationsPermissionRequested(currentStep: MadlibsOnboardingProfileStep)
    case notificationsPermissionResult(currentStep: MadlibsOnboardingProfileStep, allowed: Bool)
    case updateNameSucceeded(currentStep: MadlibsOnboardingProfileStep)
    case updateNameFailed(currentStep: MadlibsOnboardingProfileStep)
    case updateUsernameSucceeded(currentStep: MadlibsOnboardingProfileStep, username: String)
    case updateUsernameFailed(currentStep: MadlibsOnboardingProfileStep)
    case birthdayUpdateSucceeded(currentStep: MadlibsOnboardingProfileStep)
    case birthdayUpdateFailed(currentStep: MadlibsOnboardingProfileStep)
    case musicGenresUpdateSucceeded(currentStep: MadlibsOnboardingProfileStep, genres: String)
    case musicGenresUpdateFailed(currentStep: MadlibsOnboardingProfileStep)
}

// MARK: - Event Properties

public extension MadlibsAnalyticsEvent {
    var actionName: Event.ActionName {
        switch self {
        case .containerAppeared:
            .madlibsContainerAppeared
        case .stepViewed:
            .madlibsStepAppeared
        case .nextTapped:
            .madlibsNextTapped
        case .backTapped:
            .madlibsBackTapped
        case .skipTapped:
            .madlibsSkipTapped
        case .notificationsPermissionRequested:
            .notificationsPermissionsRequested
        case .notificationsPermissionResult(_, allowed: let allowed):
            allowed ? .notificationsPermissionsAllowed : .notificationsPermissionsDenied
        case .updateNameSucceeded:
            .updateNameSucceeded
        case .updateNameFailed:
            .updateNameFailed
        case .updateUsernameSucceeded:
            .updateUsernameSucceeded
        case .updateUsernameFailed:
            .updateUsernameFailed
        case .birthdayUpdateFailed:
            .birthdayUpdateFailed
        case .birthdayUpdateSucceeded:
            .birthdayUpdateCompleted
        case .musicGenresUpdateSucceeded:
            .musicGenresUpdateSucceeded
        case .musicGenresUpdateFailed:
            .musicGenresUpdateFailed
        }
    }

    var actionType: Event.ActionType {
        switch self {
        case .containerAppeared,
             .stepViewed,
             .updateNameSucceeded,
             .updateNameFailed,
             .updateUsernameSucceeded,
             .updateUsernameFailed,
             .birthdayUpdateSucceeded,
             .birthdayUpdateFailed,
             .musicGenresUpdateSucceeded,
             .musicGenresUpdateFailed:
            .event

        case .nextTapped,
             .backTapped,
             .skipTapped,
             .notificationsPermissionRequested,
             .notificationsPermissionResult:
            .tap
        }
    }

    var elementType: Event.ElementType {
        switch self {
        case .containerAppeared,
             .stepViewed,
             .updateNameSucceeded,
             .updateNameFailed,
             .updateUsernameSucceeded,
             .updateUsernameFailed,
             .birthdayUpdateSucceeded,
             .birthdayUpdateFailed,
             .musicGenresUpdateSucceeded,
             .musicGenresUpdateFailed:
            .none
        case .nextTapped, .backTapped, .skipTapped, .notificationsPermissionRequested:
            .button
        case .notificationsPermissionResult:
            .alert
        }
    }

    var elementId: String? {
        switch self {
        case .containerAppeared:
            nil
        case .stepViewed(let step),
             .nextTapped(let step),
             .backTapped(let step, _),
             .skipTapped(let step, _),
             .notificationsPermissionRequested(let step),
             .notificationsPermissionResult(let step, _),
             .updateNameSucceeded(let step),
             .updateNameFailed(let step),
             .updateUsernameSucceeded(let step, _),
             .updateUsernameFailed(let step),
             .birthdayUpdateSucceeded(let step),
             .birthdayUpdateFailed(let step),
             .musicGenresUpdateSucceeded(let step, _),
             .musicGenresUpdateFailed(let step):
            step.analyticsName
        }
    }

    var elementText: String? {
        switch self {
        case .musicGenresUpdateSucceeded(_, let genres):
            genres
        case .notificationsPermissionResult(_, let allowed):
            String(allowed)
        case .updateUsernameSucceeded(_, let username):
            username
        default:
            nil
        }
    }

    var context: String {
        switch self {
        case .backTapped(_, let previousStep):
            "madlibs_flow_to_\(previousStep?.analyticsName ?? "unknown")"
        case .skipTapped(_, let nextStep):
            "madlibs_flow_to_\(nextStep?.analyticsName ?? "complete")"
        default:
            "madlibs_flow"
        }
    }
}
