//
//  RiotAppApp.swift
//  RiotApp
//
//  Created by Jake MacMullin on 4/11/21.
//

import SwiftUI
import Firebase
#if targetEnvironment(simulator)
#else
import FirebaseMessaging
import FirebaseAuth
import FirebaseFirestore
#endif
import GoogleMobileAds

@main
struct RiotAppApp: App {
    @UIApplicationDelegateAdaptor private var appDelegate: AppDelegate
    @StateObject var contentService = ContentService(authRepository: RiotKit.standard,
                                                     contentRepository: RiotKit.standard,
                                                     preferencesRepository: UserDefaultsPreferencesRepository.standard)
    
    @StateObject var userService = UserService(authRepository: RiotKit.standard,
                                               commentRepository: RiotKit.standard,
                                               notificationRepository: DefaultNotificationRepository.standard,
                                               preferencesRepository: UserDefaultsPreferencesRepository.standard,
                                               bookmarksRepository: FirebaseBookmarksRepository.standard)
    
    @StateObject var analyticsService = AnalyticsService(repository: FirebaseAnalyticsRepository())
    @StateObject var eventsService = EventsService.standard
    
    init() {
        FirebaseApp.configure()
        #if targetEnvironment(simulator)
        GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers = [ GADSimulatorID ]
        #else
        GADMobileAds.sharedInstance().start(completionHandler: nil)
        GADMobileAds.sharedInstance().requestConfiguration.testDeviceIdentifiers =
            [ "a3422e026cd2522dc9d677e72f8e0cd7", "891e8fff71267a1ba03791cea0e19329" ]
        Messaging.messaging().delegate = appDelegate
        #endif
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .environmentObject(contentService)
                .environmentObject(userService)
                .environmentObject(analyticsService)
                .environmentObject(eventsService)
                .onAppear {
                    setInterfaceDefaults()
                    
                    Task {
                        await userService.signInWithStoredToken()
                    }
                }
                .accentColor(ColorName.tint.color)
        }
    }
    
    private func setInterfaceDefaults() {
        UIBarButtonItem.appearance().setTitleTextAttributes([.font: TextStyle.headline.uiFont], for: .normal)
        UIBarItem.appearance().setTitleTextAttributes([.font: TextStyle.headline.uiFont], for: .normal)
        UINavigationBar.appearance().titleTextAttributes = [.font: TextStyle.headline.uiFont]
        UINavigationBar.appearance().largeTitleTextAttributes = [.font: TextStyle.largeTitle.uiFont]
        
        UITableView.appearance().backgroundColor = ColorName.background.uiColor
        UITableView.appearance().backgroundView?.backgroundColor = ColorName.background.uiColor
        UICollectionView.appearance().backgroundColor = ColorName.background.uiColor
        
        UISegmentedControl.appearance().setTitleTextAttributes(
            [
                .font: TextStyle.subheadline.uiFont,
                .foregroundColor: ColorName.text.uiColor
            ], for: .selected)
        
        UISegmentedControl.appearance().setTitleTextAttributes(
            [
                .font: TextStyle.subheadline.uiFont,
                .foregroundColor: ColorName.text.uiColor
            ], for: .normal)
        
        UITextView.appearance().backgroundColor = .clear
    }
}

#if targetEnvironment(simulator)
class AppDelegate: NSObject, UIApplicationDelegate {
}
#else
class AppDelegate: NSObject, UIApplicationDelegate, MessagingDelegate {
    func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool {
        application.registerForRemoteNotifications()
        return true
    }
    
    func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
        Messaging.messaging().apnsToken = deviceToken
    }
    
    func messaging(_ messaging: Messaging, didReceiveRegistrationToken fcmToken: String?) {
        guard let token = fcmToken else { return }
        
        print(token)
        
#if targetEnvironment(simulator)
#else
        Task {
            do {
                let authResponse = try await Auth.auth().signInAnonymously()
                let user = authResponse.user
                let db = Firestore.firestore()
                let userDocumentRef = db.collection("users").document(user.uid)
                
                let _ = try await userDocumentRef.setData([
                    "fcm": token
                ], merge: true)
            } catch {
                print("Unable to send token to firebase")
            }
        }
#endif
    }
}
#endif
