//
// 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!"
					)
				)
		}
	}
}
