@objc(TamaraSdk)
class TamaraSdk: NSObject {

  // @objc(multiply:withB:withResolver:withRejecter:)
  // func multiply(a: Float, b: Float, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
  //   resolve(a*b)
  // }

  @objc(initSdk:apiUrl:pushUrl:publishKey:notificationToken:isSandbox:withResolver:withRejecter:)
  func initSdk(token: String, apiUrl: String, pushUrl: String, publishKey: String, notificationToken: String, isSandbox: Bool, resolve:RCTPromiseResolveBlock,reject:RCTPromiseRejectBlock) -> Void {
    TamaraSDKPayment.shared.initialize(token: token, apiUrl: apiUrl, pushUrl: pushUrl, publishKey: publishKey, notificationToken: notificationToken, isSandbox: isSandbox)
  }


  @objc(createOrder:withDescription:withResolver:withRejecter:)
  func createOrder(orderReferenceId: String, description: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.createOrder(orderReferenceId: orderReferenceId, description: description)
  }

  @objc(setCountry:withCurrency:withResolver:withRejecter:)
  func setCountry(countryCode: String, currency: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setCountry(countryCode: countryCode, currency: currency)
  }

  @objc(setPaymentType:withResolver:withRejecter:)
  func setPaymentType(paymentType: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setPaymentType(paymentType: paymentType)
  }

  @objc(setPlatform:withResolver:withRejecter:)
  func setPlatform(platform: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setPlatform(platform: platform)
  }

  @objc(setInstalments:withResolver:withRejecter:)
  func setInstalments(instalments: Int, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setInstalments(instalments: instalments)
  }

  @objc(setLocale:withResolver:withRejecter:)
  func setLocale(locale: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setLocale(locale: locale)
  }

  @objc(setOrderNumber:withResolver:withRejecter:)
  func setOrderNumber(orderNumber: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setOrderNumber(orderNumber: orderNumber)
  }

  @objc(setExpiresInMinutes:withResolver:withRejecter:)
  func setExpiresInMinutes(expiresInMinutes: Int, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setExpiresInMinutes(expiresInMinutes: expiresInMinutes)
  }

  @objc(setRiskAssessment:withResolver:withRejecter:)
  func setRiskAssessment(jsonData: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock){
      let risk = TamaraSDKPayment.shared.setRiskAssessment(jsonData: jsonData)
      resolve(risk)
  }

  @objc(setAdditionalData:withResolver:withRejecter:)
  func setAdditionalData(jsonData: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.setAdditionalData(jsonData: jsonData)
  }

  @objc(addCustomFieldsAdditionalData:withResolver:withRejecter:)
  func addCustomFieldsAdditionalData(jsonData: String, resolve: RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) {
      TamaraSDKPayment.shared.addCustomFieldsAdditionalData(jsonData: jsonData)
  }

  @objc(setCustomerInfo:withLastName:withPhoneNumber:withEmail:withIsFirstOrder:withResolver:withRejecter:)
  func setCustomerInfo(
      firstName: String,
      lastName: String,
      phoneNumber: String,
      email: String,
      isFirstOrder: Bool,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setCustomerInfo(
          firstName: firstName,
          lastName: lastName,
          phoneNumber: phoneNumber,
          email: email,
          isFirstOrder: isFirstOrder
      )
  }

  @objc(addItem:withReferenceId:withSku:withType:withUnitPrice:withTax:withDiscount:withQuantity:withResolver:withRejecter:)
  func addItem(
      name: String,
      referenceId: String,
      sku: String,
      type: String,
      unitPrice: Double,
      tax: Double,
      discount: Double,
      quantity: Int,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.addItem(
          name: name,
          referenceId: referenceId,
          sku: sku,
          type: type,
          unitPrice: unitPrice,
          tax: tax,
          discount: discount,
          quantity: quantity
      )
  }

  @objc(setShippingAddress:withLastName:withPhoneNumber:withAddressLine1:withAddressLine2:withCountry:withRegion:withCity:withResolver:withRejecter:)
  func setShippingAddress(
      firstName: String,
      lastName: String,
      phoneNumber: String,
      addressLine1: String,
      addressLine2: String,
      country: String,
      region: String,
      city: String,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setShippingAddress(
          firstName: firstName,
          lastName: lastName,
          phoneNumber: phoneNumber,
          addressLine1: addressLine1,
          addressLine2: addressLine2,
          country: country,
          region: region,
          city: city
      )
  }

  @objc(setBillingAddress:withLastName:withPhoneNumber:withAddressLine1:withAddressLine2:withCountry:withRegion:withCity:withResolver:withRejecter:)
  func setBillingAddress(
      firstName: String,
      lastName: String,
      phoneNumber: String,
      addressLine1: String,
      addressLine2: String,
      country: String,
      region: String,
      city: String,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setBillingAddress(
          firstName: firstName,
          lastName: lastName,
          phoneNumber: phoneNumber,
          addressLine1: addressLine1,
          addressLine2: addressLine2,
          country: country,
          region: region,
          city: city
      )
  }

  @objc(setCurrency:withResolver:withRejecter:)
  func setCurrency(
      newCurrency: String,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setCurrency(newCurrency: newCurrency)
  }

  @objc(setShippingAmount:withResolver:withRejecter:)
  func setShippingAmount(
      amount: Double,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setShippingAmount(amount: amount)
  }

  @objc(setDiscount:withName:withResolver:withRejecter:)
  func setDiscount(
      amount: Double,
      name: String,
      resolve: RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.setDiscount(amount: amount, name: name)
  }

  @objc(paymentOrder:withRejecter:)
  func paymentOrder(
      resolve: @escaping RCTPromiseResolveBlock,
      reject: RCTPromiseRejectBlock
  ) {
      TamaraSDKPayment.shared.startPayment() { result in
          switch result {
          case let .success(response):
              resolve(response.convertToJson())
          case let .failure(error):
              resolve("payment_order_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(clearItem)
  func clearItem() {
      TamaraSDKPayment.shared.clearItem()
  }

  @objc(authoriseOrder:withResolver:withRejecter:)
  func authoriseOrder(orderId: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.authoriseOrder(orderId: orderId) { result in
          switch result {
          case let .success(data):
              resolve(data.convertToJson())
          case let .failure(error):
              resolve("authorise_order_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(refunds:jsonData:withResolver:withRejecter:)
  func refunds(orderId: String, jsonData: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.refunds(orderId: orderId, jsonData: jsonData) { result in
          switch result {
          case let .success(data):
              resolve(data.convertToJson())
          case let .failure(error):
              resolve("refunds_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(orderDetail:withResolver:withRejecter:)
  func orderDetail(orderId: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.orderDetail(orderId: orderId) { result in
          switch result {
          case let .success(response):
              resolve(response.convertToJson())
          case let .failure(error):
              resolve("order_detail_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(capturePayment:withResolver:withRejecter:)
  func capturePayment(jsonData: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.capturePayment(jsonData: jsonData) { result in
          switch result {
          case let .success(response):
              resolve(response.convertToJson())
          case let .failure(error):
              resolve("capture_payment_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(cancelOrder:jsonData:withResolver:withRejecter:)
  func cancelOrder(orderId: String, jsonData: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.orderDetail(orderId: orderId) { result in
          switch result {
          case let .success(response):
              TamaraSDKPayment.shared.cancelOrder(orderId: orderId, jsonData: CancelOrder(discountAmount: nil, items: Array(), shippingAmount: nil, taxAmount: nil, totalAmount: response.totalAmount!).convertToJson()) { result in
                  switch result {
                  case let .success(data):
                      resolve(data.convertToJson())
                  case let .failure(error):
                      resolve("cancel_order_error: \(error.localizedDescription)")
                  }
              }
          case let .failure(error):
              resolve("cancel_order_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(updateOrderReference:orderReferenceId:withResolver:withRejecter:)
  func updateOrderReference(orderId: String, orderReferenceId: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.updateOrderReference(orderId: orderId, orderReferenceId: orderReferenceId) { result in
          switch result {
          case let .success(data):
              resolve(data.convertToJson())
          case let .failure(error):
              resolve("update_order_reference_error: \(error.localizedDescription)")
          }
      }
  }

  @objc(renderCartPage:country:publicKey:amount:withResolver:withRejecter:)
  func renderCartPage(language: String, country: String, publicKey: String, amount: Double, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.renderWidgetCartPage(language: language, country: country, publicKey: publicKey, amount: amount){ response, error, code in
            if let response = response as? NSDictionary {
                switch code {
                case 200:
                    if let theJSONData = try? JSONSerialization.data(
                        withJSONObject: response,
                        options: []) {
                        let data = WidgetProperties(jsonData: theJSONData)
                        resolve(data.convertToJson())
                    }
                default:
                    resolve(response.allValues)
                }
            }
       }
  }

  @objc(renderProduct:country:publicKey:amount:withResolver:withRejecter:)
  func renderProduct(language: String, country: String, publicKey: String, amount: Double, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.renderWidgetProduct(language: language, country: country, publicKey: publicKey, amount: amount){ response, error, code in
          if let response = response as? NSDictionary {
              switch code {
              case 200:
                  if let theJSONData = try? JSONSerialization.data(
                      withJSONObject: response,
                      options: []) {
                      let data = WidgetProperties(jsonData: theJSONData)
                      resolve(data.convertToJson())
                  }
              default:
                  resolve(response.allValues)
              }
          }
      }
  }

  @objc(checkPaymentOptions:withResolver:withRejecter:)
  func checkPaymentOptions(jsonData: String, resolve: @escaping RCTPromiseResolveBlock, reject: RCTPromiseRejectBlock) -> Void {
      TamaraSDKPayment.shared.checkPaymentOptions(jsonData: jsonData) { result in
          switch result {
          case let .success(response):
              resolve(response.convertToJson())
          case let .failure(error):
              resolve("payment_options_error: \(error.localizedDescription)")
          }
      }
  }
}
