//
// Copyright © 2022 Nevis Security AG. All rights reserved.
//

import NevisMobileAuthentication

final class PinPolicyImpl: PinPolicy, Codable, Sendable {
	// MARK: Properties

	let operationId: String
	let minLength: Int
	let maxLength: Int

	// MARK: Properties

	enum Constants {
		static let minLength = 6
		static let maxLength = 6
	}

	// MARK: Initialization

	init(operationId: String, minLength: Int = Constants.minLength, maxLength: Int = Constants.maxLength) {
		self.operationId = operationId
		self.minLength = minLength
		self.maxLength = maxLength
	}

	// MARK: PinPolicy

	func validatePinForEnrollment(
		_ pin: String,
		onSuccess: @escaping @Sendable () -> (),
		onError: @escaping @Sendable (PinEnrollmentValidationError) -> ()
	) {
		Task {
			let operation: any UserInteractionOperation = await OperationCache.shared.read(by: operationId)
			let authenticator = await operation.findAuthenticator(aaid: AuthenticatorAaid.Pin)
			let state = PinValidateForEnrollmentState(
				authenticator: authenticator,
				onSuccess: onSuccess,
				onValidationError: onError
			)
			await OperationCache.shared.update(
				by: operationId,
				operation: operation.update(state: state)
			)

			let message = PinValidationMessage(
				operationId: operationId,
				pin: pin
			)
			EventEmitter.shared.dispatch(event: .pinValidateForEnrollment, message: message)
		}
	}

	func validatePinForPinChange(
		_ pin: String,
		onSuccess: @escaping @Sendable () -> (),
		onError: @escaping @Sendable (PinChangeValidationError) -> ()
	) {
		Task {
			let operation: PinChangeOperation = await OperationCache.shared.read(by: operationId)
			let state = PinValidateForPinChangeState(
				onSuccess: onSuccess,
				onValidationError: onError
			)
			await OperationCache.shared.update(
				by: operationId,
				operation: operation.update(state: state)
			)

			let message = PinValidationMessage(
				operationId: operationId,
				pin: pin
			)
			EventEmitter.shared.dispatch(event: .pinValidateForPinChange, message: message)
		}
	}
}
