//
//  CredentialProviderViewController.swift
//  passAutoFillExtension
//
//  Created by Yishi Lin on 2018/9/24.
//  Copyright © 2018 Bob Sun. All rights reserved.
//

import AuthenticationServices
import passKit

class CredentialProviderViewController: ASCredentialProviderViewController {
    private lazy var passcodelock: PasscodeExtensionDisplay = { [unowned self] in
        PasscodeExtensionDisplay(extensionContext: extensionContext)
    }()

    private lazy var passwordsViewController: PasswordsViewController = (children.first as! UINavigationController).viewControllers.first as! PasswordsViewController

    private lazy var credentialProvider: CredentialProvider = { [unowned self] in
        CredentialProvider(viewController: self, extensionContext: extensionContext, afterDecryption: NotificationCenterDispatcher.showOTPNotification)
    }()

    private lazy var passwordsTableEntries = PasswordStore.shared.fetchPasswordEntityCoreData(withDir: false)
        .map(PasswordTableEntry.init)

    override func viewDidLoad() {
        super.viewDidLoad()
        passwordsViewController.dataSource = PasswordsTableDataSource(entries: passwordsTableEntries)
        passwordsViewController.selectionDelegate = self
        passwordsViewController.navigationItem.leftBarButtonItem = UIBarButtonItem(
            barButtonSystemItem: .cancel,
            target: self,
            action: #selector(cancel)
        )
    }

    override func prepareCredentialList(for serviceIdentifiers: [ASCredentialServiceIdentifier]) {
        passcodelock.presentPasscodeLockIfNeeded(self) {
            self.view.isHidden = true
        } after: { [unowned self] in
            view.isHidden = false
            credentialProvider.identifier = serviceIdentifiers.first
            let url = serviceIdentifiers.first
                .map(\.identifier)
                .flatMap(URL.init)
            passwordsViewController.navigationItem.prompt = url?.host
            passwordsViewController.showPasswordsWithSuggestion(matching: url?.host ?? "")
        }
    }

    override func provideCredentialWithoutUserInteraction(for credentialIdentity: ASPasswordCredentialIdentity) {
        credentialProvider.identifier = credentialIdentity.serviceIdentifier
        if !PasscodeLock.shared.hasPasscode, Defaults.isRememberPGPPassphraseOn {
            credentialProvider.credentials(for: credentialIdentity)
        } else {
            extensionContext.cancelRequest(withError: NSError(domain: ASExtensionErrorDomain, code: ASExtensionError.userInteractionRequired.rawValue))
        }
    }

    override func prepareInterfaceToProvideCredential(for credentialIdentity: ASPasswordCredentialIdentity) {
        passcodelock.presentPasscodeLockIfNeeded(self) {
            self.view.isHidden = true
        } after: { [unowned self] in
            credentialProvider.credentials(for: credentialIdentity)
        }
    }

    @objc
    private func cancel(_: AnyObject?) {
        extensionContext.cancelRequest(withError: NSError(domain: "PassExtension", code: 0))
    }
}

extension CredentialProviderViewController: PasswordSelectionDelegate {
    func selected(password: PasswordTableEntry) {
        credentialProvider.persistAndProvideCredentials(with: password.passwordEntity.path)
    }
}
