//
//  InAppAuthenticateView.swift
//  tb-mfa-lib-tests
//
//  Created by inwebo imac on 02/11/2021.
//

import SwiftUI
import TrustBuilderMfaLibSwift
import os.log

struct SealingView: View {
    @EnvironmentObject var buttonBlock: ButtonBlock
    @State private var tknAlias: String = ""
    @State private var sessionId: String = ""
    @State private var result: String = ""
    @State private var displayBio = false
    @State private var displaySecretCode = false
    @State private var secretCode : String = ""
    @State private var newSecretCode = false
    @State private var sealData: String = ""
    
    let pub = NotificationCenter.default.publisher(for: Notification.Name("tappedNotification"))
    
    private var useCaseHandler : TrustBuilderOperationHandler<Sealing, CredentialProvider>

    init() {
        self.useCaseHandler = TrustBuilderOperationHandler<Sealing, CredentialProvider>()
    }

    var body: some View {
        VStack {
            Text("Seal")
            TextField("tknAlias", text: $tknAlias).autocapitalization(.none)
            TextField("sessionId", text: $sessionId).autocapitalization(.none)
            UIUtils.ExecuteSealUseCaseView(displayBio:$displayBio, displaySecretCode:$displaySecretCode, SecretCode:$secretCode, SealData: $sealData, setup: setup, execute: execute).disabled(buttonBlock.buttonIsBlocked)
            Text(result)
                    .font(.footnote)
                    .foregroundColor(.red)
        }.onReceive(pub) { output in
            if let userInfo = output.userInfo, let scope = userInfo["scope"] as? String, scope == "SEAL" {
                tknAlias = userInfo["tknAlias"] as! String
                sessionId = userInfo["authSessionId"] as! String
            }
        }
                .buttonStyle(.bordered)
                .textFieldStyle(RoundedBorderTextFieldStyle())
    }
    
    func setup() {
        Task.init {
            defer { secretCode = "" } 
            do{
                let params = SealingParams(
                    tknAlias: tknAlias,
                    sessionId: sessionId
                )
                let sealing = try TrustBuilderMfaLibHolder.getLibInstance().startSealing(param: params)
                useCaseHandler.loadUseCase(useCase: sealing)
                let setup = await sealing.setup();
                if (setup.isError == true) {
                    result = UIUtils.formatResponse(response: setup)
                } else
                {
                    let setupResponse = setup.response!
                    sealData = String(decoding: setupResponse.content, as: UTF8.self)
                    let setupResultHandler = CredentialProviderHandler()
                    let resolvedCredentialProvider = setupResultHandler.resolveCredentialFromList(listCredProvider: setupResponse.credentialProviders)
                    useCaseHandler.setSetupResult(setupResult : resolvedCredentialProvider)
                    if (resolvedCredentialProvider.credType == CredTypeEnum.SECRET_CODE) {
                        displaySecretCode = true
                    } else if (resolvedCredentialProvider.credType == CredTypeEnum.BIO) {
                        displayBio = true
                    } else {
                        os_log("Invalid cred type: %@", log: .default, type: .error, resolvedCredentialProvider.credType as! CVarArg)
                    }
                }
            }catch{
                os_log("Task failed: %@", log: .default, type: .error, String(describing: error))
                result = String(describing: error)
            }
        }
    }

    func execute() {
        Task.init {
            buttonBlock.buttonIsBlocked = true
            defer { buttonBlock.buttonIsBlocked = false }
            defer { secretCode = "" }
            let credProvider : CredentialProvider = useCaseHandler.getSetupResult()
            let credValue = try await CredValueMake.make(tknAlias: tknAlias, credentialProvider: credProvider, secretCode: secretCode)
            let sealing = useCaseHandler.getUseCase()
            let execute = try await sealing.execute(input: credValue)
            result = UIUtils.formatResponse(response: execute)
        }
    }
}
