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

import NevisMobileAuthentication

struct TypedPromptOptions: Decodable, Sendable {
	// MARK: Properties

	let wrapped: PromptOptions

	// MARK: Initialization

	init(wrapped: PromptOptions) {
		self.wrapped = wrapped
	}

	// MARK: Coding Keys

	enum PromptOptionsType: String {
		case biometric = "BiometricPromptOptions"
		case devicePasscode = "DevicePasscodePromptOptions"
		case fingerprint = "FingerprintPromptOptions"
	}

	enum CodingKeys: CodingKey {
		case description
		case fallbackButtonText
		case cancelButtonText
	}

	// MARK: Decodable

	init(from decoder: Decoder) throws {
		let container = try decoder.container(keyedBy: TypedCodingKeys.self)
		let type = try container.decode(String.self, forKey: .type)
		let dataContainer = try container.nestedContainer(keyedBy: CodingKeys.self, forKey: .data)
		switch type {
		case PromptOptionsType.biometric.rawValue,
		     PromptOptionsType.fingerprint.rawValue:
			let reason = try dataContainer.decodeIfPresent(String.self, forKey: .description)
			let fallbackButtonTitle = try dataContainer.decodeIfPresent(String.self, forKey: .fallbackButtonText)
			let cancelButtonTitle = try dataContainer.decodeIfPresent(String.self, forKey: .cancelButtonText)
			self.wrapped = BiometricPromptOptions(reason: reason,
			                                      fallbackButtonTitle: fallbackButtonTitle,
			                                      cancelButtonTitle: cancelButtonTitle)
		case PromptOptionsType.devicePasscode.rawValue:
			let reason = try dataContainer.decodeIfPresent(String.self, forKey: .description)
			self.wrapped = DevicePasscodePromptOptions(reason: reason)
		default:
			throw DecodingError.dataCorrupted(
				DecodingError.Context(
					codingPath: container.codingPath,
					debugDescription: "Failed to decode prompt options!"
				)
			)
		}
	}
}
