import UIKit
import AsyncDisplayKit
import Display
import TelegramCore
import SwiftSignalKit
import Postbox
import TelegramPresentationData
import TelegramUIPreferences
import AccountContext
import ShareController
import LegacyUI
import PeerInfoUI
import ShareItems
import ShareItemsImpl
import SettingsUI
import OpenSSLEncryptionProvider
import AppLock
import Intents
import MobileCoreServices
import OverlayStatusController
import PresentationDataUtils
import ChatImportUI
import ZipArchive
import ActivityIndicator
import DebugSettingsUI
import ManagedFile
import TelegramUIDeclareEncodables
import AnimationCache
import MultiAnimationRenderer
import TelegramUIDeclareEncodables
import TelegramAccountAuxiliaryMethods
import PeerSelectionController

private var installedSharedLogger = false

private func setupSharedLogger(rootPath: String, path: String) {
    if !installedSharedLogger {
        installedSharedLogger = true
        Logger.setSharedLogger(Logger(rootPath: rootPath, basePath: path))
    }
}

private enum ShareAuthorizationError {
    case unauthorized
}

private final class ShareControllerEnvironmentExtension: ShareControllerEnvironment {
    let presentationData: PresentationData
    var updatedPresentationData: Signal<PresentationData, NoError> {
        return .single(self.presentationData)
    }
    var isMainApp: Bool {
        return false
    }
    var energyUsageSettings: EnergyUsageSettings {
        return .default
    }
    
    var mediaManager: MediaManager? {
        return nil
    }
    
    var accounts: [ShareControllerAccountContextExtension] = []
    
    init(presentationData: PresentationData) {
        self.presentationData = presentationData
    }
    
    func setAccountUserInterfaceInUse(id: AccountRecordId) -> Disposable {
        if let account = self.accounts.first(where: { $0.accountId == id }) {
            let shouldKeepConnection = account.stateManager.network.shouldKeepConnection
            shouldKeepConnection.set(.single(true))
            return ActionDisposable {
                shouldKeepConnection.set(.single(false))
            }
        } else {
            return EmptyDisposable
        }
    }
    
    func donateSendMessageIntent(account: ShareControllerAccountContext, peerIds: [EnginePeer.Id]) {
    }
}

private final class ShareControllerAccountContextExtension: ShareControllerAccountContext {
    let accountId: AccountRecordId
    let accountPeerId: EnginePeer.Id
    let stateManager: AccountStateManager
    let animationCache: AnimationCache
    let animationRenderer: MultiAnimationRenderer
    let contentSettings: ContentSettings
    let appConfiguration: AppConfiguration
    
    init(
        accountId: AccountRecordId,
        stateManager: AccountStateManager,
        contentSettings: ContentSettings,
        appConfiguration: AppConfiguration
    ) {
        self.accountId = accountId
        self.accountPeerId = stateManager.accountPeerId
        self.stateManager = stateManager
        let cacheStorageBox = stateManager.postbox.mediaBox.cacheStorageBox
        self.animationCache = AnimationCacheImpl(basePath: stateManager.postbox.mediaBox.basePath + "/animation-cache", allocateTempFile: {
            return TempBox.shared.tempFile(fileName: "file").path
        }, updateStorageStats: { path, size in
            if let pathData = path.data(using: .utf8) {
                cacheStorageBox.update(id: pathData, size: size)
            }
        })
        self.animationRenderer = MultiAnimationRendererImpl()
        self.contentSettings = contentSettings
        self.appConfiguration = appConfiguration
    }
    
    func resolveInlineStickers(fileIds: [Int64]) -> Signal<[Int64: TelegramMediaFile], NoError> {
        return _internal_resolveInlineStickers(postbox: self.stateManager.postbox, network: self.stateManager.network, fileIds: fileIds)
    }
}

public struct ShareRootControllerInitializationData {
    public let appBundleId: String
    public let appBuildType: TelegramAppBuildType
    public let appGroupPath: String
    public let apiId: Int32
    public let apiHash: String
    public let languagesCategory: String
    public let encryptionParameters: (Data, Data)
    public let appVersion: String
    public let bundleData: Data?
    public let useBetaFeatures: Bool
    
    public init(appBundleId: String, appBuildType: TelegramAppBuildType, appGroupPath: String, apiId: Int32, apiHash: String, languagesCategory: String, encryptionParameters: (Data, Data), appVersion: String, bundleData: Data?, useBetaFeatures: Bool) {
        self.appBundleId = appBundleId
        self.appBuildType = appBuildType
        self.appGroupPath = appGroupPath
        self.apiId = apiId
        self.apiHash = apiHash
        self.languagesCategory = languagesCategory
        self.encryptionParameters = encryptionParameters
        self.appVersion = appVersion
        self.bundleData = bundleData
        self.useBetaFeatures = useBetaFeatures
    }
}

private func extractTextFileHeader(path: String) -> String? {
    guard let file = ManagedFile(queue: nil, path: path, mode: .read) else {
        return nil
    }
    guard let size = file.getSize() else {
        return nil
    }
    
    let limit: Int64 = 3000
    
    var data = file.readData(count: Int(min(size, limit)))
    let additionalCapacity = min(10, max(0, Int(size) - data.count))
    
    for alignment in 0 ... additionalCapacity {
        if alignment != 0 {
            data.append(file.readData(count: 1))
        }
        if let text = String(data: data, encoding: .utf8) {
            return text
        } else {
            continue
        }
    }
    return nil
}

public class ShareRootControllerImpl {
    private let initializationData: ShareRootControllerInitializationData
    private let getExtensionContext: () -> NSExtensionContext?
    
    private var mainWindow: Window1?
    private var currentShareController: ShareController?
    private var currentPasscodeController: ViewController?
    
    private let disposable = MetaDisposable()
    private var observer1: AnyObject?
    private var observer2: AnyObject?
    
    private weak var navigationController: NavigationController?
    
    public init(initializationData: ShareRootControllerInitializationData, getExtensionContext: @escaping () -> NSExtensionContext?) {
        self.initializationData = initializationData
        self.getExtensionContext = getExtensionContext
    }
    
    deinit {
        self.disposable.dispose()
        if let observer = self.observer1 {
            NotificationCenter.default.removeObserver(observer)
        }
        if let observer = self.observer2 {
            NotificationCenter.default.removeObserver(observer)
        }
    }
    
    public func loadView() {
        telegramUIDeclareEncodables()
    }
    
    public func viewWillAppear() {
    }
    
    public func viewWillDisappear() {
        self.disposable.dispose()
    }
    
    public func viewDidLayoutSubviews(view: UIView, traitCollection: UITraitCollection) {
        if self.mainWindow == nil {
            let mainWindow = Window1(hostView: childWindowHostView(parent: view), statusBarHost: nil)
            mainWindow.hostView.eventView.backgroundColor = UIColor.clear
            mainWindow.hostView.eventView.isHidden = false
            self.mainWindow = mainWindow
            
            let bounds = view.bounds
            
            view.addSubview(mainWindow.hostView.containerView)
            mainWindow.hostView.containerView.frame = bounds
            
            let rootPath = rootPathForBasePath(self.initializationData.appGroupPath)
            performAppGroupUpgrades(appGroupPath: self.initializationData.appGroupPath, rootPath: rootPath)
            
            TempBox.initializeShared(basePath: rootPath, processType: "share", launchSpecificId: Int64.random(in: Int64.min ... Int64.max))
            
            let logsPath = rootPath + "/logs/share-logs"
            let _ = try? FileManager.default.createDirectory(atPath: logsPath, withIntermediateDirectories: true, attributes: nil)
            
            setupSharedLogger(rootPath: rootPath, path: logsPath)
            
            let applicationBindings = TelegramApplicationBindings(isMainApp: false, appBundleId: self.initializationData.appBundleId, appBuildType: self.initializationData.appBuildType, containerPath: self.initializationData.appGroupPath, appSpecificScheme: "tg", openUrl: { _ in
            }, openUniversalUrl: { _, completion in
                completion.completion(false)
                return
            }, canOpenUrl: { _ in
                return false
            }, getTopWindow: {
                return nil
            }, displayNotification: { _ in
                
            }, applicationInForeground: .single(false), applicationIsActive: .single(false), clearMessageNotifications: { _ in
            }, pushIdleTimerExtension: {
                return EmptyDisposable
            }, openSettings: {
            }, openAppStorePage: {
            }, openSubscriptions: {
            }, registerForNotifications: { _ in }, requestSiriAuthorization: { _ in }, siriAuthorization: { return .notDetermined }, getWindowHost: {
                return nil
            }, presentNativeController: { _ in
            }, dismissNativeController: {
            }, getAvailableAlternateIcons: {
                return []
            }, getAlternateIconName: {
                return nil
            }, requestSetAlternateIconName: { _, f in
                f(false)
            }, forceOrientation: { _ in
            })
            
            let accountManager = AccountManager<TelegramAccountManagerTypes>(basePath: rootPath + "/accounts-metadata", isTemporary: true, isReadOnly: false, useCaches: false, removeDatabaseOnError: false)
            initializeAccountManagement()
            
            var initialPresentationDataAndSettings: InitialPresentationDataAndSettings?
            let semaphore = DispatchSemaphore(value: 0)
            let systemUserInterfaceStyle: WindowUserInterfaceStyle
            if #available(iOSApplicationExtension 12.0, iOS 12.0, *) {
                systemUserInterfaceStyle = WindowUserInterfaceStyle(style: traitCollection.userInterfaceStyle)
            } else {
                systemUserInterfaceStyle = .light
            }
            let _ = currentPresentationDataAndSettings(accountManager: accountManager, systemUserInterfaceStyle: systemUserInterfaceStyle).start(next: { value in
                initialPresentationDataAndSettings = value
                semaphore.signal()
            })
            semaphore.wait()
            
            let presentationDataPromise = Promise<PresentationData>()
            
            let appLockContext = AppLockContextImpl(rootPath: rootPath, window: nil, rootController: nil, applicationBindings: applicationBindings, accountManager: accountManager, presentationDataSignal: presentationDataPromise.get(), lockIconInitialFrame: {
                return nil
            })
            let presentationData = initialPresentationDataAndSettings!.presentationData
            presentationDataPromise.set(.single(presentationData))
            
            var immediatePeerId: PeerId?
            if #available(iOS 13.2, *), let sendMessageIntent = self.getExtensionContext()?.intent as? INSendMessageIntent {
                if let contact = sendMessageIntent.recipients?.first, let handle = contact.customIdentifier, handle.hasPrefix("tg") {
                    let string = handle.suffix(from: handle.index(handle.startIndex, offsetBy: 2))
                    if let peerId = Int64(string) {
                        immediatePeerId = PeerId(peerId)
                    }
                }
            }
            
            /*let account: Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> = internalContext.sharedContext.accountManager.transaction { transaction -> (SharedAccountContextImpl, LoggingSettings) in
                return (internalContext.sharedContext, transaction.getSharedData(SharedDataKeys.loggingSettings)?.get(LoggingSettings.self) ?? LoggingSettings.defaultSettings)
            }
            |> castError(ShareAuthorizationError.self)
            |> mapToSignal { sharedContext, loggingSettings -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in
                Logger.shared.logToFile = loggingSettings.logToFile
                Logger.shared.logToConsole = loggingSettings.logToConsole
                
                Logger.shared.redactSensitiveData = loggingSettings.redactSensitiveData
                
                return combineLatest(sharedContext.activeAccountsWithInfo, accountManager.transaction { transaction -> (Set<AccountRecordId>, PeerId?) in
                    let accountRecords = Set(transaction.getRecords().map { record in
                        return record.id
                    })
                    let intentsSettings = transaction.getSharedData(ApplicationSpecificSharedDataKeys.intentsSettings)?.get(IntentsSettings.self) ?? IntentsSettings.defaultSettings
                    return (accountRecords, intentsSettings.account)
                })
                |> castError(ShareAuthorizationError.self)
                |> take(1)
                |> mapToSignal { primaryAndAccounts, validAccountIdsAndIntentsAccountId -> Signal<(SharedAccountContextImpl, Account, [AccountWithInfo]), ShareAuthorizationError> in
                    var (maybePrimary, accounts) = primaryAndAccounts
                    let (validAccountIds, intentsAccountId) = validAccountIdsAndIntentsAccountId
                    for i in (0 ..< accounts.count).reversed() {
                        if !validAccountIds.contains(accounts[i].account.id) {
                            accounts.remove(at: i)
                        }
                    }
                    
                    if let _ = immediatePeerId, let intentsAccountId = intentsAccountId {
                        for account in accounts {
                            if account.peer.id == intentsAccountId {
                                maybePrimary = account.account.id
                            }
                        }
                    }
                    
                    guard let primary = maybePrimary, validAccountIds.contains(primary) else {
                        return .fail(.unauthorized)
                    }
                    
                    guard let info = accounts.first(where: { $0.account.id == primary }) else {
                        return .fail(.unauthorized)
                    }
                    
                    return .single((sharedContext, info.account, Array(accounts)))
                }
            }
            |> take(1)*/
            
            let environment = ShareControllerEnvironmentExtension(presentationData: presentationData)
            let initializationData = self.initializationData
            
            let accountData: Signal<(ShareControllerEnvironment, ShareControllerAccountContext, [ShareControllerSwitchableAccount]), NoError> = accountManager.accountRecords()
            |> take(1)
            |> mapToSignal { view -> Signal<(ShareControllerEnvironment, ShareControllerAccountContext, [ShareControllerSwitchableAccount]), NoError> in
                var signals: [Signal<(AccountRecordId, AccountStateManager, Peer)?, NoError>] = []
                for record in view.records {
                    if record.attributes.contains(where: { attribute in
                        if case .loggedOut = attribute {
                            return true
                        } else {
                            return false
                        }
                    }) {
                        continue
                    }
                    
                    let networkArguments = NetworkInitializationArguments(
                        apiId: initializationData.apiId,
                        apiHash: initializationData.apiHash,
                        languagesCategory: initializationData.languagesCategory,
                        appVersion: initializationData.appVersion,
                        voipMaxLayer: 0,
                        voipVersions: [],
                        appData: .single(nil),
                        autolockDeadine: .single(nil),
                        encryptionProvider: OpenSSLEncryptionProvider(),
                        deviceModelName: nil,
                        useBetaFeatures: initializationData.useBetaFeatures,
                        isICloudEnabled: false
                    )
                    
                    signals.append(standaloneStateManager(
                        accountManager: accountManager,
                        networkArguments: networkArguments,
                        id: record.id,
                        encryptionParameters: ValueBoxEncryptionParameters(
                            forceEncryptionIfNoSet: false,
                            key: ValueBoxEncryptionParameters.Key(data: initializationData.encryptionParameters.0)!,
                            salt: ValueBoxEncryptionParameters.Salt(data: initializationData.encryptionParameters.1)!
                        ),
                        rootPath: rootPath,
                        auxiliaryMethods: makeTelegramAccountAuxiliaryMethods(uploadInBackground: nil)
                    )
                    |> mapToSignal { result -> Signal<(AccountRecordId, AccountStateManager, Peer)?, NoError> in
                        if let result {
                            return result.postbox.transaction { transaction -> (AccountRecordId, AccountStateManager, Peer)? in
                                guard let peer = transaction.getPeer(result.accountPeerId) else {
                                    return nil
                                }
                                
                                return (record.id, result, peer)
                            }
                        } else {
                            return .single(nil)
                        }
                    })
                }
                return combineLatest(signals)
                |> mapToSignal { stateManagers -> Signal<(ShareControllerEnvironment, ShareControllerAccountContext, [ShareControllerSwitchableAccount]), NoError> in
                    var allAccounts: [ShareControllerSwitchableAccount] = []
                    for data in stateManagers {
                        guard let (id, stateManager, peer) = data else {
                            continue
                        }
                        //TODO:content settings
                        allAccounts.append(ShareControllerSwitchableAccount(
                            account: ShareControllerAccountContextExtension(
                                accountId: id,
                                stateManager: stateManager,
                                contentSettings: .default,
                                appConfiguration: .defaultValue
                            ),
                            peer: peer
                        ))
                    }
                    
                    guard let currentAccount = allAccounts.first(where: { $0.account.accountId == view.currentRecord?.id }) else {
                        return .never()
                    }
                    
                    return .single((environment, currentAccount.account, allAccounts))
                }
            }
            
            let applicationInterface: Signal<(ShareControllerEnvironment, ShareControllerAccountContext, PostboxAccessChallengeData, [ShareControllerSwitchableAccount]), ShareAuthorizationError> = accountData
            |> castError(ShareAuthorizationError.self)
            |> mapToSignal { data -> Signal<(ShareControllerEnvironment, ShareControllerAccountContext, PostboxAccessChallengeData, [ShareControllerSwitchableAccount]), ShareAuthorizationError> in
                let (environment, context, otherAccounts) = data
                
                let limitsConfigurationAndContentSettings = TelegramEngine.EngineData(postbox: context.stateManager.postbox).get(
                    TelegramEngine.EngineData.Item.Configuration.Limits(),
                    TelegramEngine.EngineData.Item.Configuration.ContentSettings(),
                    TelegramEngine.EngineData.Item.Configuration.App()
                )
                
                return combineLatest(accountManager.sharedData(keys: [ApplicationSpecificSharedDataKeys.presentationPasscodeSettings]), limitsConfigurationAndContentSettings, accountManager.accessChallengeData())
                |> take(1)
                |> deliverOnMainQueue
                |> castError(ShareAuthorizationError.self)
                |> map { sharedData, limitsConfigurationAndContentSettings, data -> (ShareControllerEnvironment, ShareControllerAccountContext, PostboxAccessChallengeData, [ShareControllerSwitchableAccount]) in
                    updateLegacyLocalization(strings: environment.presentationData.strings)
                    
                    return (environment, context, data.data, otherAccounts)
                }
            }
            |> deliverOnMainQueue
            |> afterNext { [weak self] environment, context, accessChallengeData, otherAccounts in
                (environment as? ShareControllerEnvironmentExtension)?.accounts = otherAccounts.compactMap { $0.account as? ShareControllerAccountContextExtension }
                
                initializeLegacyComponents(application: nil, currentSizeClassGetter: { return .compact }, currentHorizontalClassGetter: { return .compact }, documentsPath: "", currentApplicationBounds: { return CGRect() }, canOpenUrl: { _ in return false}, openUrl: { _ in })
                
                let displayShare: () -> Void = {
                    var cancelImpl: (() -> Void)?
                    let _ = cancelImpl
                    
                    let beginShare: () -> Void = {
                        let requestUserInteraction: ([UnpreparedShareItemContent]) -> Signal<[PreparedShareItemContent], NoError> = { content in
                            return Signal { [weak self] subscriber in
                                switch content[0] {
                                    case let .contact(data):
                                        #if !DEBUG
                                        //qwefqwfqwefw
                                        #endif
                                        let _ = data
                                        let _ = self
                                        /*let controller = deviceContactInfoController(context: context, subject: .filter(peer: nil, contactId: nil, contactData: data, completion: { peer, contactData in
                                            let phone = contactData.basicData.phoneNumbers[0].value
                                            if let vCardData = contactData.serializedVCard() {
                                                subscriber.putNext([.media(.media(.standalone(media: TelegramMediaContact(firstName: contactData.basicData.firstName, lastName: contactData.basicData.lastName, phoneNumber: phone, peerId: nil, vCardData: vCardData))))])
                                            }
                                            subscriber.putCompletion()
                                        }), completed: nil, cancelled: {
                                            cancelImpl?()
                                        })
                                        
                                        if let strongSelf = self, let window = strongSelf.mainWindow {
                                            controller.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
                                            window.present(controller, on: .root)
                                        }*/
                                        break
                                }
                                return EmptyDisposable
                            } |> runOn(Queue.mainQueue())
                        }
                        
                        let sentItems: ([PeerId], [PeerId: Int64], [PreparedShareItemContent], ShareControllerAccountContext, Bool, String) -> Signal<ShareControllerExternalStatus, NoError> = { peerIds, threadIds, contents, account, silently, additionalText in
                            let sentItems = sentShareItems(accountPeerId: account.accountPeerId, postbox: account.stateManager.postbox, network: account.stateManager.network, stateManager: account.stateManager, auxiliaryMethods: makeTelegramAccountAuxiliaryMethods(uploadInBackground: nil), to: peerIds, threadIds: threadIds, items: contents, silently: silently, additionalText: additionalText)
                            |> `catch` { _ -> Signal<
                                Float, NoError> in
                                return .complete()
                            }
                            return sentItems
                            |> map { value -> ShareControllerExternalStatus in
                                return .progress(value)
                            }
                            |> then(.single(.done))
                        }
                                            
                        let shareController = ShareController(environment: environment, currentContext: context, subject: .fromExternal({ peerIds, threadIds, additionalText, account, silently in
                            if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, !inputItems.isEmpty, !peerIds.isEmpty {
                                let rawSignals = TGItemProviderSignals.itemSignals(forInputItems: inputItems)!
                                return preparedShareItems(postbox: account.stateManager.postbox, network: account.stateManager.network, to: peerIds[0], dataItems: rawSignals)
                                |> map(Optional.init)
                                |> `catch` { error -> Signal<PreparedShareItems?, ShareControllerError> in
                                    switch error {
                                        case .generic:
                                            return .single(nil)
                                        case let .fileTooBig(size):
                                            return .fail(.fileTooBig(size))
                                    }
                                }
                                |> mapToSignal { state -> Signal<ShareControllerExternalStatus, ShareControllerError> in
                                    guard let state = state else {
                                        return .single(.done)
                                    }
                                    switch state {
                                    case let .preparing(long):
                                        return .single(.preparing(long))
                                    case let .progress(value):
                                        return .single(.progress(value))
                                    case let .userInteractionRequired(value):
                                        return requestUserInteraction(value)
                                        |> castError(ShareControllerError.self)
                                        |> mapToSignal { contents -> Signal<ShareControllerExternalStatus, ShareControllerError> in
                                            return sentItems(peerIds, threadIds, contents, account, silently, additionalText)
                                            |> castError(ShareControllerError.self)
                                        }
                                    case let .done(contents):
                                        return sentItems(peerIds, threadIds, contents, account, silently, additionalText)
                                        |> castError(ShareControllerError.self)
                                    }
                                }
                            } else {
                                return .single(.done)
                            }
                        }), fromForeignApp: true, externalShare: false, switchableAccounts: otherAccounts, immediatePeerId: immediatePeerId)
                        shareController.presentationArguments = ViewControllerPresentationArguments(presentationAnimation: .modalSheet)
                        shareController.dismissed = { _ in
                            //inForeground.set(false)
                            self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                        }
                        /*shareController.debugAction = {
                            guard let strongSelf = self else {
                                return
                            }
                            let presentationData = environment.presentationData
                            let navigationController = NavigationController(mode: .single, theme: NavigationControllerTheme(presentationTheme: presentationData.theme))
                            strongSelf.navigationController = navigationController
                            navigationController.viewControllers = [debugController(sharedContext: context.sharedContext, context: context)]
                            strongSelf.mainWindow?.present(navigationController, on: .root)
                        }*/
                        
                        cancelImpl = { [weak shareController] in
                            shareController?.dismiss(completion: { [weak self] in
                                //inForeground.set(false)
                                self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                            })
                        }
                        
                        if let strongSelf = self {
                            if let currentShareController = strongSelf.currentShareController {
                                currentShareController.dismiss()
                            }
                            if let navigationController = strongSelf.navigationController {
                                navigationController.dismiss(animated: false)
                            }
                            strongSelf.currentShareController = shareController
                            strongSelf.mainWindow?.present(shareController, on: .root)
                        }
                          
                        //TODO
                        //context.account.resetStateManagement()
                    }
                    
                    if !"".isEmpty {/* if let strongSelf = self, let inputItems = strongSelf.getExtensionContext()?.inputItems, inputItems.count == 1, let item = inputItems[0] as? NSExtensionItem, let attachments = item.attachments {
                        for attachment in attachments {
                            if attachment.hasItemConformingToTypeIdentifier(kUTTypeFileURL as String) {
                                attachment.loadItem(forTypeIdentifier: kUTTypeFileURL as String, completionHandler: { result, error in
                                    Queue.mainQueue().async {
                                        guard let url = result as? URL, url.isFileURL else {
                                            beginShare()
                                            return
                                        }
                                        guard let fileName = url.pathComponents.last else {
                                            beginShare()
                                            return
                                        }
                                        let fileExtension = (fileName as NSString).pathExtension
                                        
                                        var archivePathValue: String?
                                        var otherEntries: [(SSZipEntry, String, TelegramEngine.HistoryImport.MediaType)] = []
                                        var mainFile: TempBoxFile?
                                        
                                        let appConfiguration = context.appConfiguration
                                        
                                        /*
                                         history_import_filters: {
                                             "zip": {
                                                 "main_file_patterns": [
                                                     "_chat\\.txt",
                                                     "KakaoTalkChats\\.txt",
                                                     "Talk_.*?\\.txt"
                                                 ]
                                             },
                                             "txt": {
                                                 "patterns": [
                                                     "^\\[LINE\\]"
                                                 ]
                                             }
                                         }
                                         */
                                        
                                        if fileExtension.lowercased() == "zip" {
                                            let archivePath = url.path
                                            archivePathValue = archivePath
                                            
                                            guard let entries = SSZipArchive.getEntriesForFile(atPath: archivePath) else {
                                                beginShare()
                                                return
                                            }
                                            
                                            var mainFileNameExpressions: [String] = [
                                                "_chat\\.txt",
                                                "KakaoTalkChats\\.txt",
                                                "Talk_.*?\\.txt",
                                            ]
                                            
                                            if let data = appConfiguration.data, let dict = data["history_import_filters"] as? [String: Any] {
                                                if let zip = dict["zip"] as? [String: Any] {
                                                    if let patterns = zip["main_file_patterns"] as? [String] {
                                                        mainFileNameExpressions = patterns
                                                    }
                                                }
                                            }
                                            
                                            let mainFileNames: [NSRegularExpression] = mainFileNameExpressions.compactMap { string -> NSRegularExpression? in
                                                return try? NSRegularExpression(pattern: string)
                                            }
                                            
                                            var maybeMainFileName: String?
                                            mainFileLoop: for entry in entries {
                                                let entryFileName = entry.path.replacingOccurrences(of: "/", with: "_").replacingOccurrences(of: "..", with: "_")
                                                let fullRange = NSRange(entryFileName.startIndex ..< entryFileName.endIndex, in: entryFileName)
                                                for expression in mainFileNames {
                                                    if expression.firstMatch(in: entryFileName, options: [], range: fullRange) != nil {
                                                        maybeMainFileName = entryFileName
                                                        break mainFileLoop
                                                    }
                                                }
                                            }
                                            
                                            guard let mainFileName = maybeMainFileName else {
                                                beginShare()
                                                return
                                            }
                                            
                                            let photoRegex = try! NSRegularExpression(pattern: ".*?\\.jpg")
                                            let videoRegex = try! NSRegularExpression(pattern: "[\\d]+-VIDEO-.*?\\.mp4")
                                            let stickerRegex = try! NSRegularExpression(pattern: "[\\d]+-STICKER-.*?\\.webp")
                                            let voiceRegex = try! NSRegularExpression(pattern: "[\\d]+-AUDIO-.*?\\.opus")
                                            
                                            do {
                                                for entry in entries {
                                                    let entryPath = entry.path.replacingOccurrences(of: "/", with: "_").replacingOccurrences(of: "..", with: "_")
                                                    if entryPath.isEmpty {
                                                        continue
                                                    }
                                                    let tempFile = TempBox.shared.tempFile(fileName: entryPath)
                                                    if entryPath == mainFileName {
                                                        if SSZipArchive.extractFileFromArchive(atPath: archivePath, filePath: entry.path, toPath: tempFile.path) {
                                                            mainFile = tempFile
                                                        }
                                                    } else {
                                                        let entryFileName = (entryPath as NSString).lastPathComponent
                                                        if !entryFileName.isEmpty {
                                                            let mediaType: TelegramEngine.HistoryImport.MediaType
                                                            let fullRange = NSRange(entryFileName.startIndex ..< entryFileName.endIndex, in: entryFileName)
                                                            if photoRegex.firstMatch(in: entryFileName, options: [], range: fullRange) != nil {
                                                                mediaType = .photo
                                                            } else if videoRegex.firstMatch(in: entryFileName, options: [], range: fullRange) != nil {
                                                                mediaType = .video
                                                            } else if stickerRegex.firstMatch(in: entryFileName, options: [], range: fullRange) != nil {
                                                                mediaType = .sticker
                                                            } else if voiceRegex.firstMatch(in: entryFileName, options: [], range: fullRange) != nil {
                                                                mediaType = .voice
                                                            } else {
                                                                mediaType = .file
                                                            }
                                                            otherEntries.append((entry, entryFileName, mediaType))
                                                        }
                                                    }
                                                }
                                            }
                                        } else if fileExtension.lowercased() == "txt" {
                                            var fileScanExpressions: [String] = [
                                                "^\\[LINE\\]",
                                            ]
                                            
                                            if let data = appConfiguration.data, let dict = data["history_import_filters"] as? [String: Any] {
                                                if let zip = dict["txt"] as? [String: Any] {
                                                    if let patterns = zip["patterns"] as? [String] {
                                                        fileScanExpressions = patterns
                                                    }
                                                }
                                            }
                                            
                                            let filePatterns: [NSRegularExpression] = fileScanExpressions.compactMap { string -> NSRegularExpression? in
                                                return try? NSRegularExpression(pattern: string)
                                            }
                                            
                                            if let mainFileTextHeader = extractTextFileHeader(path: url.path) {
                                                let fullRange = NSRange(mainFileTextHeader.startIndex ..< mainFileTextHeader.endIndex, in: mainFileTextHeader)
                                                var foundMatch = false
                                                for pattern in filePatterns {
                                                    if pattern.firstMatch(in: mainFileTextHeader, options: [], range: fullRange) != nil {
                                                        foundMatch = true
                                                        break
                                                    }
                                                }
                                                if !foundMatch {
                                                    beginShare()
                                                    return
                                                }
                                            } else {
                                                beginShare()
                                                return
                                            }
                                            
                                            let tempFile = TempBox.shared.tempFile(fileName: "History.txt")
                                            if let _ = try? FileManager.default.copyItem(atPath: url.path, toPath: tempFile.path) {
                                                mainFile = tempFile
                                            } else {
                                                beginShare()
                                                return
                                            }
                                        }
                                        
                                        if let mainFile = mainFile, let mainFileHeader = extractTextFileHeader(path :mainFile.path) {
                                            final class TempController: ViewController {
                                                override public var _presentedInModal: Bool {
                                                    get {
                                                        return true
                                                    } set(value) {
                                                    }
                                                }
                                                
                                                private let activityIndicator: ActivityIndicator
                                                
                                                init(environment: ShareControllerEnvironment) {
                                                    let presentationData = environment.presentationData
                                                    
                                                    self.activityIndicator = ActivityIndicator(type: .custom(presentationData.theme.list.itemAccentColor, 22.0, 1.0, false))
                                                    
                                                    super.init(navigationBarPresentationData: NavigationBarPresentationData(presentationData: presentationData))
                                                    
                                                    self.title = presentationData.strings.ChatImport_Title
                                                    self.navigationItem.setLeftBarButton(UIBarButtonItem(title: presentationData.strings.Common_Cancel, style: .plain, target: self, action: #selector(self.cancelPressed)), animated: false)
                                                }
                                                
                                                required public init(coder aDecoder: NSCoder) {
                                                    fatalError("init(coder:) has not been implemented")
                                                }
                                                
                                                @objc private func cancelPressed() {
                                                    //self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                }
                                                
                                                override func displayNodeDidLoad() {
                                                    super.displayNodeDidLoad()
                                                    
                                                    self.displayNode.addSubnode(self.activityIndicator)
                                                }
                                                
                                                override func containerLayoutUpdated(_ layout: ContainerViewLayout, transition: ContainedViewLayoutTransition) {
                                                    super.containerLayoutUpdated(layout, transition: transition)
                                                    
                                                    let indicatorSize = self.activityIndicator.measure(CGSize(width: 100.0, height: 100.0))
                                                    let navigationHeight = self.navigationLayout(layout: layout).navigationFrame.maxY
                                                    transition.updateFrame(node: self.activityIndicator, frame: CGRect(origin: CGPoint(x: floor((layout.size.width - indicatorSize.width) / 2.0), y: navigationHeight + floor((layout.size.height - navigationHeight - indicatorSize.height) / 2.0)), size: indicatorSize))
                                                }
                                            }
                                            
                                            let presentationData = environment.presentationData
                                            let navigationController = NavigationController(mode: .single, theme: NavigationControllerTheme(presentationTheme: presentationData.theme))
                                            strongSelf.navigationController = navigationController
                                            navigationController.viewControllers = [TempController(environment: environment)]
                                            strongSelf.mainWindow?.present(navigationController, on: .root)
                                            
                                            let _ = (TelegramEngine.HistoryImport(postbox: context.stateManager.postbox, network: context.stateManager.network).getInfo(header: mainFileHeader)
                                            |> deliverOnMainQueue).start(next: { parseInfo in
                                                switch parseInfo {
                                                case let .group(groupTitle):
                                                    var attemptSelectionImpl: ((EnginePeer) -> Void)?
                                                    var createNewGroupImpl: (() -> Void)?
                                                    let controller = PeerSelectionControllerImpl(PeerSelectionControllerParams(context: context, filter: [.onlyGroups, .onlyManageable, .excludeDisabled, .doNotSearchMessages], hasContactSelector: false, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }, createNewGroup: {
                                                        createNewGroupImpl?()
                                                    }, pretendPresentedInModal: true, selectForumThreads: false))
                                                    
                                                    controller.customDismiss = {
                                                        //inForeground.set(false)
                                                        self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                    }
                                                    
                                                    controller.peerSelected = { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }
                                                    
                                                    controller.navigationPresentation = .default
                                                    
                                                    let beginWithPeer: (PeerId) -> Void = { peerId in
                                                        navigationController.view.endEditing(true)
                                                        navigationController.pushViewController(ChatImportActivityScreen(context: context, cancel: {
                                                            //inForeground.set(false)
                                                            self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                        }, peerId: peerId, archivePath: archivePathValue, mainEntry: mainFile, otherEntries: otherEntries))
                                                    }
                                                    
                                                    attemptSelectionImpl = { peer in
                                                        var errorText: String?
                                                        if case let .channel(channel) = peer {
                                                            if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
                                                            } else {
                                                                errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                            }
                                                        } else if case let .legacyGroup(group) = peer {
                                                            switch group.role {
                                                            case .creator:
                                                                break
                                                            default:
                                                                errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                            }
                                                        } else {
                                                            errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
                                                        }
                                                        
                                                        if let errorText = errorText {
                                                            let presentationData = environment.presentationData
                                                            let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                            })])
                                                            strongSelf.mainWindow?.present(controller, on: .root)
                                                        } else {
                                                            controller.inProgress = true
                                                            let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id)
                                                            |> deliverOnMainQueue).start(next: { result in
                                                                controller.inProgress = false
                                                                
                                                                let presentationData = environment.presentationData
                                                                
                                                                var errorText: String?
                                                                if case let .channel(channel) = peer {
                                                                    if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
                                                                    } else {
                                                                        errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                                    }
                                                                } else if case let .legacyGroup(group) = peer {
                                                                    switch group.role {
                                                                    case .creator:
                                                                        break
                                                                    default:
                                                                        errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                                    }
                                                                } else if case .user = peer {
                                                                } else {
                                                                    errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
                                                                }
                                                                
                                                                if let errorText = errorText {
                                                                    let presentationData = environment.presentationData
                                                                    let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                                    })])
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                } else {
                                                                    let presentationData = environment.presentationData
                                                                    let text: String
                                                                    switch result {
                                                                    case .allowed:
                                                                        if let groupTitle = groupTitle {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).string
                                                                        } else {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).string
                                                                        }
                                                                    case let .alert(textValue):
                                                                        text = textValue
                                                                    }
                                                                    let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                                    }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
                                                                        beginWithPeer(peer.id)
                                                                    })], parseMarkdown: true)
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                }
                                                            }, error: { error in
                                                                controller.inProgress = false
                                                                
                                                                let presentationData = environment.presentationData
                                                                let errorText: String
                                                                switch error {
                                                                case .generic:
                                                                    errorText = presentationData.strings.Login_UnknownError
                                                                case .chatAdminRequired:
                                                                    errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
                                                                case .invalidChatType:
                                                                    errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
                                                                case .userBlocked:
                                                                    errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
                                                                case .limitExceeded:
                                                                    errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
                                                                case .notMutualContact:
                                                                    errorText = presentationData.strings.ChatImport_UserErrorNotMutual
                                                                }
                                                                let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                                })])
                                                                strongSelf.mainWindow?.present(controller, on: .root)
                                                            })
                                                        }
                                                    }
                                                    
                                                    createNewGroupImpl = {
                                                        let presentationData = environment.presentationData
                                                        let resolvedGroupTitle: String
                                                        if let groupTitle = groupTitle {
                                                            resolvedGroupTitle = groupTitle
                                                        } else {
                                                            resolvedGroupTitle = "Group"
                                                        }
                                                        let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_CreateGroupAlertTitle, text: presentationData.strings.ChatImport_CreateGroupAlertText(resolvedGroupTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_CreateGroupAlertImportAction, action: {
                                                            var signal: Signal<PeerId?, NoError> = _internal_createSupergroup(postbox: context.stateManager.postbox, network: context.stateManager.network, stateManager: context.stateManager, title: resolvedGroupTitle, description: nil, username: nil, isForum: false, isForHistoryImport: true)
                                                            |> map(Optional.init)
                                                            |> `catch` { _ -> Signal<PeerId?, NoError> in
                                                                return .single(nil)
                                                            }
                                                            
                                                            let presentationData = context.sharedContext.currentPresentationData.with { $0 }
                                                            let progressSignal = Signal<Never, NoError> { subscriber in
                                                                let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
                                                                if let strongSelf = self {
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                }
                                                                return ActionDisposable { [weak controller] in
                                                                    Queue.mainQueue().async() {
                                                                        controller?.dismiss()
                                                                    }
                                                                }
                                                            }
                                                            |> runOn(Queue.mainQueue())
                                                            |> delay(0.15, queue: Queue.mainQueue())
                                                            let progressDisposable = progressSignal.start()
                                                            
                                                            signal = signal
                                                            |> afterDisposed {
                                                                Queue.mainQueue().async {
                                                                    progressDisposable.dispose()
                                                                }
                                                            }
                                                            let _ = (signal
                                                            |> deliverOnMainQueue).start(next: { peerId in
                                                                if let peerId = peerId {
                                                                    beginWithPeer(peerId)
                                                                } else {
                                                                }
                                                            })
                                                        }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                        })], actionLayout: .vertical, parseMarkdown: true)
                                                        strongSelf.mainWindow?.present(controller, on: .root)
                                                    }
                                                    
                                                    navigationController.viewControllers = [controller]
                                                case let .privateChat(title):
                                                    let presentationData = environment.presentationData
                                                    
                                                    var attemptSelectionImpl: ((EnginePeer) -> Void)?
                                                    let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.onlyPrivateChats, .excludeDisabled, .doNotSearchMessages, .excludeSecretChats], hasChatListSelector: false, hasContactSelector: true, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }, pretendPresentedInModal: true, selectForumThreads: true))
                                                    
                                                    controller.customDismiss = {
                                                        //inForeground.set(false)
                                                        self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                    }
                                                    
                                                    controller.peerSelected = { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }
                                                    
                                                    controller.navigationPresentation = .default
                                                    
                                                    let beginWithPeer: (PeerId) -> Void = { peerId in
                                                        navigationController.view.endEditing(true)
                                                        navigationController.pushViewController(ChatImportActivityScreen(context: context, cancel: {
                                                            //inForeground.set(false)
                                                            self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                        }, peerId: peerId, archivePath: archivePathValue, mainEntry: mainFile, otherEntries: otherEntries))
                                                    }
                                                    
                                                    attemptSelectionImpl = { [weak controller] peer in
                                                        controller?.inProgress = true
                                                        let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id)
                                                        |> deliverOnMainQueue).start(next: { result in
                                                            controller?.inProgress = false
                                                            
                                                            let presentationData = environment.presentationData
                                                            let text: String
                                                            switch result {
                                                            case .allowed:
                                                                if let title = title {
                                                                    text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
                                                                } else {
                                                                    text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
                                                                }
                                                            case let .alert(textValue):
                                                                text = textValue
                                                            }
                                                            let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                            }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
                                                                beginWithPeer(peer.id)
                                                            })], parseMarkdown: true)
                                                            strongSelf.mainWindow?.present(controller, on: .root)
                                                        }, error: { error in
                                                            controller?.inProgress = false
                                                            
                                                            let presentationData = environment.presentationData
                                                            let errorText: String
                                                            switch error {
                                                            case .generic:
                                                                errorText = presentationData.strings.Login_UnknownError
                                                            case .chatAdminRequired:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
                                                            case .invalidChatType:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
                                                            case .userBlocked:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
                                                            case .limitExceeded:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
                                                            case .notMutualContact:
                                                                errorText = presentationData.strings.ChatImport_UserErrorNotMutual
                                                            }
                                                            let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                            })])
                                                            strongSelf.mainWindow?.present(controller, on: .root)
                                                        })
                                                    }
                                                    
                                                    navigationController.viewControllers = [controller]
                                                case let .unknown(peerTitle):
                                                    var attemptSelectionImpl: ((EnginePeer) -> Void)?
                                                    var createNewGroupImpl: (() -> Void)?
                                                    let controller = context.sharedContext.makePeerSelectionController(PeerSelectionControllerParams(context: context, filter: [.excludeDisabled, .doNotSearchMessages], hasContactSelector: true, hasGlobalSearch: false, title: presentationData.strings.ChatImport_Title, attemptSelection: { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }, createNewGroup: {
                                                        createNewGroupImpl?()
                                                    }, pretendPresentedInModal: true, selectForumThreads: true))
                                                    
                                                    controller.customDismiss = {
                                                        //inForeground.set(false)
                                                        self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                    }
                                                    
                                                    controller.peerSelected = { peer, _ in
                                                        attemptSelectionImpl?(peer)
                                                    }
                                                    
                                                    controller.navigationPresentation = .default
                                                    
                                                    let beginWithPeer: (EnginePeer.Id) -> Void = { peerId in
                                                        navigationController.view.endEditing(true)
                                                        navigationController.pushViewController(ChatImportActivityScreen(context: context, cancel: {
                                                            //inForeground.set(false)
                                                            self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                                                        }, peerId: peerId, archivePath: archivePathValue, mainEntry: mainFile, otherEntries: otherEntries))
                                                    }
                                                    
                                                    attemptSelectionImpl = { [weak controller] peer in
                                                        controller?.inProgress = true
                                                        let _ = (context.engine.historyImport.checkPeerImport(peerId: peer.id)
                                                        |> deliverOnMainQueue).start(next: { result in
                                                            controller?.inProgress = false
                                                            
                                                            let presentationData = environment.presentationData
                                                            
                                                            var errorText: String?
                                                            if case let .channel(channel) = peer {
                                                                if channel.hasPermission(.changeInfo), (channel.flags.contains(.isCreator) || channel.adminRights != nil) {
                                                                } else {
                                                                    errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                                }
                                                            } else if case let .legacyGroup(group) = peer {
                                                                switch group.role {
                                                                case .creator:
                                                                    break
                                                                default:
                                                                    errorText = presentationData.strings.ChatImport_SelectionErrorNotAdmin
                                                                }
                                                            } else if case .user = peer {
                                                            } else {
                                                                errorText = presentationData.strings.ChatImport_SelectionErrorGroupGeneric
                                                            }
                                                            
                                                            if let errorText = errorText {
                                                                let presentationData = environment.presentationData
                                                                let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                                })])
                                                                strongSelf.mainWindow?.present(controller, on: .root)
                                                            } else {
                                                                let presentationData = environment.presentationData
                                                                if case .user = peer {
                                                                    let text: String
                                                                    switch result {
                                                                    case .allowed:
                                                                        if let title = peerTitle {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationUserWithTitle(title, peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
                                                                        } else {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationUserWithoutTitle(peer.displayTitle(strings: presentationData.strings, displayOrder: presentationData.nameDisplayOrder)).string
                                                                        }
                                                                    case let .alert(textValue):
                                                                        text = textValue
                                                                    }
                                                                    let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                                    }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
                                                                        beginWithPeer(peer.id)
                                                                    })], parseMarkdown: true)
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                } else {
                                                                    let text: String
                                                                    switch result {
                                                                    case .allowed:
                                                                        if let groupTitle = peerTitle {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithTitle(groupTitle, peer.debugDisplayTitle).string
                                                                        } else {
                                                                            text = presentationData.strings.ChatImport_SelectionConfirmationGroupWithoutTitle(peer.debugDisplayTitle).string
                                                                        }
                                                                    case let .alert(textValue):
                                                                        text = textValue
                                                                    }
                                                                    let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_SelectionConfirmationAlertTitle, text: text, actions: [TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                                    }), TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_SelectionConfirmationAlertImportAction, action: {
                                                                        beginWithPeer(peer.id)
                                                                    })], parseMarkdown: true)
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                }
                                                            }
                                                        }, error: { error in
                                                            controller?.inProgress = false
                                                            
                                                            let presentationData = environment.presentationData
                                                            let errorText: String
                                                            switch error {
                                                            case .generic:
                                                                errorText = presentationData.strings.Login_UnknownError
                                                            case .chatAdminRequired:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorNotAdmin
                                                            case .invalidChatType:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorInvalidChatType
                                                            case .userBlocked:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorUserBlocked
                                                            case .limitExceeded:
                                                                errorText = presentationData.strings.ChatImportActivity_ErrorLimitExceeded
                                                            case .notMutualContact:
                                                                errorText = presentationData.strings.ChatImport_UserErrorNotMutual
                                                            }
                                                            let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: nil, text: errorText, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                                                            })])
                                                            strongSelf.mainWindow?.present(controller, on: .root)
                                                        })
                                                    }
                                                    
                                                    createNewGroupImpl = {
                                                        let presentationData = environment.presentationData
                                                        let resolvedGroupTitle: String
                                                        if let groupTitle = peerTitle {
                                                            resolvedGroupTitle = groupTitle
                                                        } else {
                                                            resolvedGroupTitle = "Group"
                                                        }
                                                        let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.ChatImport_CreateGroupAlertTitle, text: presentationData.strings.ChatImport_CreateGroupAlertText(resolvedGroupTitle).string, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.ChatImport_CreateGroupAlertImportAction, action: {
                                                            var signal: Signal<PeerId?, NoError> = _internal_createSupergroup(postbox: context.stateManager.postbox, network: context.stateManager.network, stateManager: context.stateManager, title: resolvedGroupTitle, description: nil, username: nil, isForum: false, isForHistoryImport: true)
                                                            |> map(Optional.init)
                                                            |> `catch` { _ -> Signal<PeerId?, NoError> in
                                                                return .single(nil)
                                                            }
                                                            
                                                            let presentationData = context.sharedContext.currentPresentationData.with { $0 }
                                                            let progressSignal = Signal<Never, NoError> { subscriber in
                                                                let controller = OverlayStatusController(theme: presentationData.theme, type: .loading(cancelled: nil))
                                                                if let strongSelf = self {
                                                                    strongSelf.mainWindow?.present(controller, on: .root)
                                                                }
                                                                return ActionDisposable { [weak controller] in
                                                                    Queue.mainQueue().async() {
                                                                        controller?.dismiss()
                                                                    }
                                                                }
                                                            }
                                                            |> runOn(Queue.mainQueue())
                                                            |> delay(0.15, queue: Queue.mainQueue())
                                                            let progressDisposable = progressSignal.start()
                                                            
                                                            signal = signal
                                                            |> afterDisposed {
                                                                Queue.mainQueue().async {
                                                                    progressDisposable.dispose()
                                                                }
                                                            }
                                                            let _ = (signal
                                                            |> deliverOnMainQueue).start(next: { peerId in
                                                                if let peerId = peerId {
                                                                    beginWithPeer(peerId)
                                                                } else {
                                                                }
                                                            })
                                                        }), TextAlertAction(type: .genericAction, title: presentationData.strings.Common_Cancel, action: {
                                                        })], actionLayout: .vertical, parseMarkdown: true)
                                                        strongSelf.mainWindow?.present(controller, on: .root)
                                                    }
                                                    
                                                    navigationController.viewControllers = [controller]
                                                }
                                            }, error: { _ in
                                                beginShare()
                                            })
                                        } else {
                                            beginShare()
                                            return
                                        }
                                    }
                                })
                                return
                            }
                        }
                        beginShare()*/
                    } else {
                        beginShare()
                    }
                }
                
                let modalPresentation: Bool
                if #available(iOSApplicationExtension 13.0, iOS 13.0, *) {
                    modalPresentation = true
                } else {
                    modalPresentation = false
                }
                
                let _ = passcodeEntryController(
                    accountManager: accountManager,
                    applicationBindings: applicationBindings,
                    presentationData: environment.presentationData,
                    updatedPresentationData: .single(environment.presentationData),
                    statusBarHost: nil,
                    appLockContext: appLockContext,
                    animateIn: true,
                    modalPresentation: modalPresentation,
                    completion: { value in
                        if value {
                            displayShare()
                        } else {
                            Queue.mainQueue().after(0.5, {
                                //inForeground.set(false)
                                self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                            })
                        }
                    }
                ).start(next: { controller in
                    guard let strongSelf = self, let controller = controller else {
                        return
                    }
                    
                    if let currentPasscodeController = strongSelf.currentPasscodeController {
                        currentPasscodeController.dismiss()
                    }
                    strongSelf.currentPasscodeController = controller
                    strongSelf.mainWindow?.present(controller, on: .root)
                })
            }
            
            self.disposable.set(applicationInterface.start(next: { _, _, _, _ in }, error: { [weak self] error in
                guard let strongSelf = self else {
                    return
                }
                let presentationData = environment.presentationData
                let controller = standardTextAlertController(theme: AlertControllerTheme(presentationData: presentationData), title: presentationData.strings.Share_AuthTitle, text: presentationData.strings.Share_AuthDescription, actions: [TextAlertAction(type: .defaultAction, title: presentationData.strings.Common_OK, action: {
                    //inForeground.set(false)
                    self?.getExtensionContext()?.completeRequest(returningItems: nil, completionHandler: nil)
                })])
                strongSelf.mainWindow?.present(controller, on: .root)
            }, completed: {}))
        }
    }
}