import AnalyticsClient
import ComposableArchitecture

extension AppDelegateReducer {
    struct Analytics: AnalyticsReducer {
        var source: String = "app_delegate"

        // swiftlint:disable:next cyclomatic_complexity
        func analytics(before _: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .didFinishLaunching:
                track(Event(category: .general, actionName: .didFinishLaunching))
                return .none

            case .didRegisterForRemoteNotifications(let result):
                switch result {
                case .success(let tokenData):
                    track(
                        Event(
                            category: .general,
                            actionName: .remoteNotificationsRegistrationSucceeded,
                            elementId: tokenData.toString()
                        )
                    )

                case .failure(let error):
                    track(
                        Event(
                            category: .general,
                            actionName: .remoteNotificationsRegistrationFailed,
                            context: error.localizedDescription
                        )
                    )
                }
                return .none

            case .internal(.notificationsAuthorizationStatusResponse(let status)):
                let statusString = switch status {
                case .notDetermined: "not_determined"
                case .denied: "denied"
                case .authorized: "authorized"
                case .provisional: "provisional"
                case .ephemeral: "ephemeral"
                default: ""
                }
                track(
                    Event(
                        category: .general,
                        actionName: .notificationsPermissionsStatus,
                        elementType: .status,
                        context: statusString
                    )
                )
                return .none

            case .internal(.notificationsRequestAuthorization):
                track(
                    Event(
                        category: .general,
                        actionName: .notificationsPermissionsRequested,
                        elementType: .alert
                    )
                )
                return .none

            case .internal(.notificationsAuthorizationResponse(.success(let granted))):
                if granted {
                    track(
                        Event(
                            category: .general,
                            actionName: .notificationsPermissionsAllowed,
                            elementType: .alert
                        )
                    )
                } else {
                    track(
                        Event(
                            category: .general,
                            actionName: .notificationsPermissionsDenied,
                            elementType: .alert
                        )
                    )
                }
                return .none

            case .internal(.notificationsAuthorizationResponse(.failure(let error))):
                track(
                    Event(
                        category: .general,
                        actionName: .notificationsPermissionsError,
                        elementType: .alert,
                        context: error.localizedDescription
                    )
                )
                return .none

            default:
                break
            }

            return .none
        }
    }
}

extension AppCoordinator {
    struct Analytics: AnalyticsReducer {
        let source = "app_coordinator"

        func analytics(before _: State, after _: State, action: Action) -> Effect<Action> {
            switch action {
            case .internal(.attAuthorizationStatus(let status)):
                let response: String = switch status {
                case .authorized: "authorized"
                case .denied: "denied"
                case .notDetermined: "notDetermined"
                case .restricted: "restricted"
                @unknown default: "unknown"
                }

                @Dependency(\.attClient) var attClient
                let idfa = attClient.idfa()
                track(
                    Event(
                        category: .general,
                        actionName: .attPromptResponse,
                        elementType: .alert,
                        elementId: idfa?.uuidString,
                        context: response
                    )
                )
                return .none

            default:
                break
            }

            return .none
        }
    }
}
