import AnalyticsClient
import ComposableArchitecture
import Utilities

extension PublicProfileV1 {
    struct Analytics: AnalyticsReducer {
        var source: String = "public_profile_v1"

        // swiftlint:disable:next cyclomatic_complexity function_body_length
        func analytics(before: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .loadProfile:
                // `before.isMe` doesn't work before loading, but this
                // should always work as handles are equally unique
                if before.me.user.handle == before.handle {
                    track(
                        Event(
                            category: .profile,
                            actionName: .loadMyProfileStarted,
                            elementType: .handle,
                            elementId: before.handle
                        )
                    )
                } else {
                    track(
                        Event(
                            category: .profile,
                            actionName: .loadPublicProfileStarted,
                            elementType: .handle,
                            elementId: before.handle
                        )
                    )
                }

            case .followToggleTapped:
                if before.isFollowing {
                    track(
                        Event(
                            category: .profile,
                            actionName: .followTapped,
                            actionType: .tap,
                            elementType: .button,
                            elementId: before.handle
                        )
                    )
                } else {
                    track(
                        Event(
                            category: .profile,
                            actionName: .unfollowTapped,
                            actionType: .tap,
                            elementType: .button,
                            elementId: before.handle
                        )
                    )
                }

            case .followTapped(let recommendUser):
                if recommendUser.user.isFollowing {
                    track(
                        Event(
                            category: .profile,
                            actionName: .unfollowTapped,
                            actionType: .tap,
                            elementType: .button,
                            elementId: recommendUser.id,
                            xIndex: before.recommendedUsers.index(id: recommendUser.id),
                            context: "recommended_users_carousel"
                        )
                    )
                } else {
                    track(
                        Event(
                            category: .profile,
                            actionName: .followTapped,
                            actionType: .tap,
                            elementType: .button,
                            elementId: recommendUser.id,
                            xIndex: before.recommendedUsers.index(id: recommendUser.id),
                            context: "recommended_users_carousel"
                        )
                    )
                }

            case .hideRecommendedUserTapped(let recommendUser):
                track(
                    Event(
                        category: .profile,
                        actionName: .hideRecommendedUserTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: recommendUser.id,
                        xIndex: before.recommendedUsers.index(id: recommendUser.id),
                        context: "recommended_users_carousel"
                    )
                )

            case .moreTapped(let sectionType):
                switch sectionType {
                case .recommendedUsers:
                    track(
                        Event(
                            category: .profile,
                            actionName: .showMoreTapped,
                            actionType: .tap,
                            elementType: .button,
                            context: "recommended_users_carousel"
                        )
                    )

                case .hooks:
                    track(
                        Event(
                            category: .profile,
                            actionName: .showMoreHooksTapped,
                            actionType: .tap,
                            elementType: .button,
                            context: "profile_hooks_carousel"
                        )
                    )
                }

            case .shareTapped:
                track(
                    Event(
                        category: .profile,
                        actionName: .shareTapped,
                        actionType: .tap,
                        elementType: .button,
                        elementId: before.handle
                    )
                )

            case .playAllTapped:
                track(
                    Event(
                        category: .profile,
                        actionName: .playAllTapped,
                        actionType: .tap,
                        elementType: .button
                    )
                )

            case .notificationsTapped:
                track(
                    Event(
                        category: .profile,
                        actionName: .notificationsTapped,
                        actionType: .tap,
                        elementType: .toolbarButton
                    )
                )

            case .addPhoneNumberTapped:
                track(
                    Event(
                        category: .profile,
                        actionName: .addPhoneNumberBannerTapped,
                        actionType: .tap,
                        elementType: .banner
                    )
                )

            default:
                break
            }

            return .none
        }
    }
}

extension Notifications {
    struct Analytics: AnalyticsReducer {
        var source: String = "notifications"

        // swiftlint:disable:next cyclomatic_complexity function_body_length
        func analytics(before _: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .back:
                track(
                    Event(
                        category: .social,
                        actionName: .backTapped,
                        actionType: .tap,
                        elementType: .toolbarButton
                    )
                )

            case .setNotificationsRead:
                track(
                    Event(
                        category: .social,
                        actionName: .setNotificationsAsRead
                    )
                )

            case .inAppNotificationsList(.delegate(let delegateAction)):
                switch delegateAction {
                case .followTapped(let handle, let isFollowing):
                    track(
                        Event(
                            category: .inAppNotifications,
                            actionName: isFollowing ? .unfollowTapped : .followTapped,
                            actionType: .tap,
                            elementType: .button,
                            context: handle
                        )
                    )

                case .userTapped(let miniProfile):
                    track(
                        Event(
                            category: .inAppNotifications,
                            actionName: .profileTapped,
                            actionType: .tap,
                            elementType: .button,
                            context: miniProfile.handle
                        )
                    )

                case .clipOrPlaylistTapped(let clipOrPlaylist, _):
                    track(
                        Event(
                            category: .inAppNotifications,
                            actionName: .clipOrPlaylistTapped,
                            actionType: .tap,
                            elementType: .notification,
                            context: clipOrPlaylist.id
                        )
                    )

                case .redirectV2(let redirectType, _):
                    switch redirectType {
                    case .noRedirect:
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .noRedirectTriggered,
                                actionType: .tap,
                                elementType: .notification
                            )
                        )

                    case .toClip(let clipID, _):
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .redirectToClip,
                                actionType: .tap,
                                elementType: .notification,
                                context: clipID
                            )
                        )

                    case .toHook(let hookID, _):
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .redirectToHook,
                                actionType: .tap,
                                elementType: .notification,
                                context: hookID
                            )
                        )

                    case .toProfile(let handle):
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .redirectToProfile,
                                actionType: .tap,
                                elementType: .notification,
                                context: handle
                            )
                        )

                    case .toProfileList:
                        /* TODO: */
                        break

                    case .toPlaylist(let playlistID):
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .redirectToPlaylist,
                                actionType: .tap,
                                elementType: .notification,
                                context: playlistID
                            )
                        )

                    case .toExternalURL(let url):
                        track(
                            Event(
                                category: .inAppNotifications,
                                actionName: .redirectToURL,
                                actionType: .tap,
                                elementType: .notification,
                                context: url
                            )
                        )
                    }
                }

                return .none

            case .followTapped(let handle, let isFollowing):
                if isFollowing {
                    track(
                        Event(
                            category: .social,
                            actionName: .unfollowTapped,
                            actionType: .tap,
                            elementType: .button,
                            // no id available
                            elementId: handle
                        )
                    )
                } else {
                    track(
                        Event(
                            category: .social,
                            actionName: .followTapped,
                            actionType: .tap,
                            elementType: .button,
                            // no id available
                            elementId: handle
                        )
                    )
                }

            case .userTapped(let miniProfile):
                track(
                    Event(
                        category: .social,
                        actionName: .profileTapped,
                        actionType: .tap,
                        elementType: .profile,
                        // no id available
                        elementId: miniProfile.handle
                    )
                )

            case .clipOrPlaylistTapped(let miniClipOrPlaylist, _):
                track(
                    Event(
                        category: .social,
                        actionName: .clipOrPlaylistTapped,
                        actionType: .tap,
                        elementType: .clipOrPlaylist,
                        // no id available
                        elementId: miniClipOrPlaylist.id
                    )
                )

            default:
                break
            }

            return .none
        }
    }
}
