// Copyright © 2022 Olo Inc. All rights reserved.
// This software is made available under the Olo Pay SDK License (See LICENSE.md file)
//
//  ErrorHandling.swift
//  OlopaysdkReactNative
//
//  Created by Justin Anderson on 3/30/23.
//  Copyright © 2023 Facebook. All rights reserved.
//

import Foundation
import OloPaySDK

func rejectError(error: Error, reject: RCTPromiseRejectBlock, defaultMessage: String = "Unexpected error occurred") {
    guard let opError = error as? OPError else {
        reject(ErrorCodes.GeneralError, getErrorMessage(error: error, defaultMessage: defaultMessage), nil)
        return
    }
    
    rejectError(error: opError, reject: reject)
}

func rejectError(error: OPError, reject: RCTPromiseRejectBlock, defaultMessage: String = "Unexpected error occurred") {
    let errorCode = getErrorCode(for: error)
    let errorMessage = getErrorMessage(error: error, defaultMessage: defaultMessage)
    
    reject(errorCode, errorMessage, nil)
}

private func getErrorMessage(error: Error, defaultMessage: String) -> String {
    return error.localizedDescription.isEmpty ? defaultMessage : error.localizedDescription
}

private func getErrorCode(for errorType: OPCardErrorType) -> String {
    switch errorType {
    case .invalidNumber:
        return ErrorCodes.InvalidNumber
    case .invalidExpMonth:
        return ErrorCodes.InvalidExpiration
    case .invalidExpYear:
        return ErrorCodes.InvalidExpiration
    case .invalidCvv:
        return ErrorCodes.InvalidCvv
    case .invalidZip:
        return ErrorCodes.InvalidPostalCode
    case .expiredCard:
        return ErrorCodes.ExpiredCard
    case .cardDeclined:
        return ErrorCodes.CardDeclined
    case .processingError:
        return ErrorCodes.ProcessingError
    case .unknownCardError:
        return ErrorCodes.UnknownCard
    }
}

private func getErrorCode(for error: OPError) -> String {
    switch error.errorType {
    case .connectionError:
        return ErrorCodes.Connection
    case .invalidRequestError:
        return ErrorCodes.InvalidRequest
    case .apiError:
        return ErrorCodes.ApiError
    case .cardError:
        return getErrorCode(for: error.cardErrorType!)
    case .cancellationError:
        return ErrorCodes.Cancellation
    case .authenticationError:
        return ErrorCodes.Authentication
    case .generalError:
        return ErrorCodes.GeneralError
    case .applePayContextError:
        return ErrorCodes.GeneralError //This should never happen
    }
}
