#import <Foundation/Foundation.h>

NS_ASSUME_NONNULL_BEGIN

// Forward declaration to avoid circular dependency
@class ZSMClient;

/**
 * Enum representing various types of errors that can occur in the ZSM system.
 */
typedef NS_ENUM(NSInteger, ZSMErrorCode) {
    ZSMErrorCode_Error = 0,                             /**< General error. */
    ZSMErrorCode_NetworkFailure = 1,                    /**< Network failure occurred. */
    ZSMErrorCode_InvalidLogin = 2,                      /**< Invalid login attempt. */
    ZSMErrorCode_UnauthorizedUser = 3,                  /**< Unauthorized user access attempt. */

    // AUGMENTED: Added missing error codes to match Android platform
    ZSMErrorCode_OperationTimeout = 4,                  /**< Operation timed out. */
    ZSMErrorCode_InvalidServerResponse = 5,             /**< Received invalid response from server. */
    ZSMErrorCode_ServerUnreachable = 6,                 /**< Server is unreachable. */
    ZSMErrorCode_UserNotEnrolled = 7,                   /**< User is not enrolled in the system. */
    ZSMErrorCode_UserAlreadyEnrolled = 8,               /**< User is already enrolled in the system. */
    ZSMErrorCode_EnrollmentStateMismatch = 9,           /**< Local credentials missing but server has enrollment data. Call unenroll() then enroll(). */
    // END AUGMENTED

    //cryptographic errors
    ZSMErrorCode_BadCryptographicValue = 100,           /**< Bad cryptographic value encountered. */
    ZSMErrorCode_CryptographicFailure = 101,            /**< Cryptographic operation failed. */
    ZSMErrorCode_CryptographicKey = 102,                /**< Problem with cryptographic key. */
    ZSMErrorCode_SecureStorageUnavailable = 103,        /**< Secure storage is unavailable. */
    ZSMErrorCode_SecureStorageFailure = 104,            /**< Secure storage failure. */
    ZSMErrorCode_SecureStorageUnauthenticated = 105,    /**< Secure storage unauthenticated access attempt. */
    
    //registration related error codes
    ZSMErrorCode_RegistrationFailure = 200,             /**< User registration failed. */
    ZSMErrorCode_RegistrationIncomplete = 201,          /**< User registration incomplete. */
    
    //device error codes
    ZSMErrorCode_DeviceSuspended = 300,                 /**< Device is suspended. */
    ZSMErrorCode_DeviceDeactivated = 301,               /**< Device is deactivated. */
    ZSMErrorCode_AccountSuspended = 302,                /**< User account is suspended. */
    ZSMErrorCode_AccountDeactivated = 303,              /**< User account is deactivated. */
    
    // AUGMENTED: Native platform-specific errors (1000+ range) - SDK layer only, not from Rust
    // Ranges: 1000-1009 (keychain), 1010-1019 (biometric), 1020-1029 (config),
    //         1030-1039 (state), 1040-1049 (storage), 1050-1059 (serialization),
    //         1060-1069 (iOS-specific), 1070-1079 (Android-specific)

    // Keychain/KeyStore related issues (1000-1009, 6 slots reserved)
    ZSMErrorCode_InvalidKeychainSetup = 1000,           /**< Invalid keychain/keystore configuration. */
    ZSMErrorCode_DuplicateKeychainItem = 1001,          /**< Duplicated keychain/keystore item. */
    ZSMErrorCode_InvalidKeychainGroup = 1002,           /**< Invalid keychain access group or keystore alias. */
    ZSMErrorCode_InvalidSigningKeyReEnroll = 1003,      /**< Public key mismatch between client and server, re-enroll required. */
    // 1004-1009 reserved for future keychain errors

    // Biometric/Authentication errors (1010-1019, 5 slots reserved)
    ZSMErrorCode_BiometricLockout = 1010,               /**< Biometric authentication locked due to too many failed attempts. */
    ZSMErrorCode_BiometricNotAvailable = 1011,          /**< Biometric authentication not available on this device. */
    ZSMErrorCode_BiometricNotEnrolled = 1012,           /**< User has not enrolled biometric credentials on device. */
    ZSMErrorCode_BiometricCancelled = 1013,             /**< User cancelled biometric authentication prompt. */
    ZSMErrorCode_BiometricHardwareUnavailable = 1014,   /**< Biometric hardware unavailable or malfunctioning. */
    // 1015-1019 reserved for future biometric errors

    // Configuration errors (1020-1029, 5 slots reserved)
    ZSMErrorCode_InvalidConfig = 1020,                  /**< Required SDK configuration parameters missing or invalid. */
    ZSMErrorCode_MissingHostUrl = 1021,                 /**< Host URL not configured. */
    ZSMErrorCode_MissingApiKey = 1022,                  /**< API key not configured. */
    ZSMErrorCode_MissingApplicationId = 1023,           /**< Application ID not configured. */
    ZSMErrorCode_InvalidInstallationId = 1024,          /**< Installation ID corrupted or invalid. */
    // 1025-1029 reserved for future configuration errors

    // State management errors (1030-1039, 5 slots reserved)
    ZSMErrorCode_InvalidOperationState = 1030,          /**< Operation called in wrong sequence or state. */
    ZSMErrorCode_MissingStartResult = 1031,             /**< Finish method called without valid start result. */
    ZSMErrorCode_StartResultExpired = 1032,             /**< Start result has expired or is no longer valid. */
    ZSMErrorCode_ConcurrentOperation = 1033,            /**< Multiple operations attempted concurrently. */
    ZSMErrorCode_OperationCancelled = 1034,             /**< Operation was cancelled by the application. */
    ZSMErrorCode_ClientRegistryFailure = 1035, /**< Client registry lookup failed. State is corrupted—re-enrollment required. */
    // 1035-1039 reserved for future state management errors

    // Platform storage errors (1040-1049, 5 slots reserved)
    ZSMErrorCode_KeystoreInitializationFailed = 1040,   /**< Failed to initialize secure storage system. */
    ZSMErrorCode_KeyPermanentlyInvalidated = 1041,      /**< Key invalidated due to biometric enrollment change. */
    ZSMErrorCode_UserNotAuthenticated = 1042,           /**< User authentication required to access key. */
    ZSMErrorCode_HardwareNotBacked = 1043,              /**< Secure hardware not available on this device. */
    ZSMErrorCode_AttestationFailed = 1044,              /**< Key attestation verification failed. */
    // 1045-1049 reserved for future storage errors

    // Data serialization errors (1050-1059, 6 slots reserved)
    ZSMErrorCode_InvalidJsonFormat = 1050,              /**< Received malformed JSON data. */
    ZSMErrorCode_MissingRequiredField = 1051,           /**< Required field missing from response. */
    ZSMErrorCode_DataEncodingError = 1052,              /**< Failed to encode/decode data. */
    ZSMErrorCode_InvalidResponseFormat = 1053,          /**< Response format doesn't match expected structure. */
    // 1054-1059 reserved for future serialization errors

    // iOS-specific errors (1060-1069, 7 slots reserved)
    ZSMErrorCode_KeychainAccessDenied = 1060,           /**< App doesn't have permission to access keychain. */
    ZSMErrorCode_SecureEnclaveNotAvailable = 1061,      /**< Secure Enclave not available on this device. */
    ZSMErrorCode_LAContextError = 1062,                 /**< Local Authentication context error. */
    // 1063-1069 reserved for future iOS-specific errors

    // Android-specific errors (1070-1079, 7 slots reserved) - included for cross-platform consistency
    ZSMErrorCode_StrongBoxUnavailable = 1070,           /**< StrongBox KeyMaster not available (Android). */
    ZSMErrorCode_AndroidVersionUnsupported = 1071,      /**< Android API level too low for secure operations. */
    ZSMErrorCode_KeyguardNotSecure = 1072,              /**< Device lock screen not configured (Android). */
    // 1073-1079 reserved for future Android-specific errors
    // END AUGMENTED
    
    WEBAUTHN_ERROR = 500,                               /**< WebAuthn error. */
    WEBAUTHN_NO_CREDENTIALS = 501,                      /**< WebAuthn error, no credentials found. */
    WEBAUTHN_INVALID_CREDENTIALS = 502,                 /**< WebAuthn error, invalid credentials. */
    
    RELYING_PARTY_ERROR = 600,                          /**< Relying party error. */
    RELYING_PARTY_INVALID_RESPONSE = 601,               /**< Invalid response from relying party. */

    // AUGMENTED: Added missing error code to match Android platform
    RELYING_PARTY_MISSING_CONFIG = 602,                 /**< Missing required configuration for relying party. */
    // END AUGMENTED
};

/**
 * `ZSMError` is a class representing errors in the ZSM system.
 * It extends NSError to provide more specific error codes (see `ZSMErrorCode`).
 */
NS_SWIFT_SENDABLE // Immutable, and NSError must be Sendable because it conforms to Error in Swift
@interface ZSMError : NSError {
    NSString *_traceId;
    NSString *_message;
}

/**
 * Initialize a `ZSMError` with a specific error code.
 * @param code The `ZSMErrorCode` for the error.
 */
- (instancetype)initWithCode:(ZSMErrorCode)code NS_SWIFT_NAME(init(code:));

/**
 * Initialize a `ZSMError` with a specific error code and message.
 * @param code The `ZSMErrorCode` for the error.
 * @param traceId The `trace ID` for the error which matches the server, if applicable.
 * @param message A custom error message.
 */
- (instancetype)initWithCode:(ZSMErrorCode)code traceId:(nullable NSString*)traceId message:(nullable NSString*)message NS_SWIFT_NAME(init(code:traceId:message:));

/**
 * Convenient method to create a `ZSMError` with a specific error code.
 * @param code The `ZSMErrorCode` for the error.
 */
+ (instancetype)errorWithCode:(ZSMErrorCode)code NS_SWIFT_NAME(error(code:));

+ (instancetype)errorWithCode:(ZSMErrorCode)code message:(nullable NSString *)message NS_SWIFT_NAME(error(code:message:));

/**
 * Convenient method to create a `ZSMError` with a specific error code and message.
 * @param code The `ZSMErrorCode` for the error.
 * @param traceId The `trace ID` for the error which matches the server, if applicable.
 * @param message A custom error message.
 */
+ (instancetype)errorWithCode:(ZSMErrorCode)code traceId:(nullable NSString*)traceId message:(nullable NSString*)message NS_SWIFT_NAME(error(code:traceId:message:));

/**
 * Provides the `ZSMErrorCode` for the current error.
 */
@property (readonly, nonatomic) ZSMErrorCode skError;
@property (readonly, nonatomic) NSString *traceId;
@property (readonly, nonatomic) NSString *message;

@end

NS_ASSUME_NONNULL_END

