//
//  PadelClubApp.swift
//  PadelClub
//
//  Created by Laurent Morvillier on 02/02/2024.
//

import SwiftUI
import LeStorage
import TipKit

@main
struct PadelClubApp: App {
    let persistenceController = PersistenceController.shared
    @State private var navigationViewModel = NavigationViewModel()
    @StateObject var networkMonitor: NetworkMonitor = NetworkMonitor()
    @StateObject var dataStore = DataStore.shared
    @State private var registrationError: RegistrationError? = nil
    
    @UIApplicationDelegateAdaptor(AppDelegate.self) var appDelegate

    var presentError: Binding<Bool> {
        Binding {
            registrationError != nil
        } set: { value in
            if value == false {
                registrationError = nil
            }
        }
    }
    
    enum RegistrationError: LocalizedError {
        case badActivationLink
        case activationFailed
        
        var errorDescription: String? {
            switch self {
            case .badActivationLink:
                return "Le lien d'activation n'a pas fonctionné"
            case .activationFailed:
                return "L'activation de votre compte n'a pas fonctionné"
            }
        }
    }
    
    static var appVersion: String {
        let dictionary = Bundle.main.infoDictionary!
        let version = dictionary["CFBundleShortVersionString"] as! String
        let build = dictionary["CFBundleVersion"] as! String
        return "\(version) (\(build))"
    }

    var body: some Scene {
        WindowGroup {
            MainView()
                .alert(isPresented: presentError, error: registrationError) {
                    Button("Contactez-nous") {
                        _openMail()
                    }
                    Button("Annuler", role: .cancel) {
                        registrationError = nil
                    }
                }
                .onOpenURL { url in
#if targetEnvironment(simulator)
#else
                    _handleIncomingURL(url)
#endif
                }
                .environmentObject(networkMonitor)
                .environmentObject(dataStore)
                .environment(navigationViewModel)
                .accentColor(.master)
                .onAppear {
                    networkMonitor.checkConnection()
                    self._onAppear()
                }
                .task {
                    
                    //try? Tips.resetDatastore()

                    try? Tips.configure([
                        .displayFrequency(.immediate),
                        .datastoreLocation(.applicationDefault)
                    ])
                }
                .environment(\.managedObjectContext, persistenceController.localContainer.viewContext)
        }
    }
    
    private func _handleIncomingURL(_ url: URL) {
        // Parse the URL
        let pathComponents = url.pathComponents
        if url.scheme == "padelclub" && pathComponents.count > 3 && pathComponents[1] == "activate" {
            let uidb64 = pathComponents[2]
            let token = pathComponents[3]
            _activateUser(uidb64: uidb64, token: token)
            print(uidb64, token)
        } else {
            // Handle invalid URL case
            print("Handle invalid URL case")
            registrationError = .badActivationLink
        }
    }
    
    private func _activateUser(uidb64: String, token: String) {
        guard let url = URL(string: "https://\(URLs.activationHost.rawValue)/activate/\(uidb64)/\(token)/") else {
            registrationError = .activationFailed
            return
        }

        URLSession.shared.dataTask(with: url) { (data, response, error) in
            guard let data = data, let httpResponse = response as? HTTPURLResponse, httpResponse.statusCode == 200 else {
                print("activation error")
                print(error)
                registrationError = .activationFailed
                return
            }

            DispatchQueue.main.async {
                dataStore.appSettings.didRegisterAccount = true
                dataStore.appSettingsStorage.write()

                if navigationViewModel.selectedTab != .umpire {
                    navigationViewModel.selectedTab = .umpire
                }
                
                if navigationViewModel.umpirePath.isEmpty {
                    navigationViewModel.umpirePath.append(UmpireView.UmpireScreen.login)
                } else if navigationViewModel.umpirePath.last! != .login {
                    navigationViewModel.umpirePath.removeAll()
                    navigationViewModel.umpirePath.append(UmpireView.UmpireScreen.login)
                }
            }
        }.resume()
    }

    fileprivate func _onAppear() {
        let docURL = FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)[0]
        Logger.log("doc dir = \(docURL.absoluteString)")
        UserDefaults.standard.set(false, forKey: "_UIConstraintBasedLayoutLogUnsatisfiable")
        
//        AppDelegate.askPermissions()
        
    }
    
    
    private func _openMail(emailTo: String = "support@padelclub.app", subject: String = "Support Padel Club") {
        if let url = URL(string: "mailto:\(emailTo)?subject=\(subject)"), UIApplication.shared.canOpenURL(url) {
            UIApplication.shared.open(url, options: [:], completionHandler: nil)
        }
    }
}
