//
//  AmeliaChat.swift
//  OneStoreRN
//
//  Created by Sanjay Kumar on 07/05/19.
//  Copyright © 2019 Facebook. All rights reserved.
//

import Foundation
import SafariServices

@objc(AmeliaChat)
class AmeliaChat : RCTEventEmitter, IPSAKChatSessionDelegate, IPSAKChatConversationDelegate {
  
  var chat : IPSAKChat?
  var globalCallback : (([Any]?) -> Void)?
  var domains: [IPSAKDomain]?
  var msgId: NSInteger = 0
  var authSystem: IPSAKAuthSystem?
  
  @objc
	func initialize(_ baseUrl:String, callback: @escaping RCTResponseSenderBlock)  {
	
    if let serverURL = URL(string: baseUrl) {
      let configuration = IPSAKConfiguration.init(url: serverURL)
      configuration.domainSelectionMode = .manual
      configuration.speechParams.enabled = false
      configuration.allowAllHosts  = true
      self.chat = IPSAKChat.init(configuration: configuration)
      self.chat?.sessionDelegate = self
      globalCallback = callback
      self.chat?.initialize()
    }
  }
	
	@objc
	func concatStr(_ string1:String,  secondString:String, resolver: RCTPromiseResolveBlock, rejecter:RCTPromiseRejectBlock) {
		//resolve([NSString stringWithFormat:@"%@ %@", string1, string2]);
		let appendString1 = "\(string1) \(secondString)"
		resolver(appendString1)
	}
  @objc
  func startConversation(_ callback: @escaping RCTResponseSenderBlock){
    globalCallback = callback
    self.chat?.startNewConversation()
  }
  
  @objc
  func selectDomain(_ withDomain: String, callback : @escaping RCTResponseSenderBlock) {
    globalCallback = callback
    if let selectedDomain = self.domains?.filter({ $0.code == withDomain }) {
      self.chat?.selectDomain(selectedDomain.first!)
    }
  }
  
  @objc
  func login(_ username: String, password: String, loginType:String, callback: @escaping RCTResponseSenderBlock) {
    var loginOptions = IPSAKLoginOptions()
    if (loginType == "internal") {
      loginOptions = IPSAKLoginOptions.init(username: username, password: password)
    }
    else {
      //let appDelegate = UIApplication.shared.delegate as! AppDelegate
      /*
       - (NSHTTPCookie *) createNewCookie: (NSString *) newSession{
       NSURL *url = [NSURL URLWithString:[NSUserDefaults standardUserDefaults].ips_host];
       NSMutableDictionary *propscook = [[NSMutableDictionary alloc] init];
       [propscook setObject:newSession forKey:NSHTTPCookieValue];
       [propscook setObject:@"amelia_s" forKey:NSHTTPCookieName];
       [propscook setObject:@"/Amelia" forKey:NSHTTPCookiePath];
       [propscook setObject:url.host forKey:NSHTTPCookieDomain];
       NSHTTPCookie *newcookie = [NSHTTPCookie cookieWithProperties:propscook];
       return newcookie;
       }
    */
      
      
      let cookieProperties: [HTTPCookiePropertyKey : Any] = [.name : "amelia_s",
															 .value : UserDefaults.standard.object(forKey: "cookieString")!,
                                                             .domain : "ipsoft-v3-amelia-playgroundus.ipsoft.com",
                                                             .path : "/Amelia",
      ]
      
      if let cookie = HTTPCookie(properties: cookieProperties) {
        loginOptions = IPSAKLoginOptions.init(authSystem: self.authSystem!, sessionCookie: cookie)
      }
    }
    globalCallback = callback
    self.chat?.login(loginOptions)
  }
  
  @objc
  func askAmelia(_ question: String) {
    self.chat?.conversationDelegate = self
    self.chat?.ask(question)
  }
  
  @objc
  func openSafariWithURL(_ url: String) {
	DispatchQueue.main.async {
		guard let url = URL.init(string: url) else { return  }
		if #available(iOS 9.0, *) {
			let safariVC = SFSafariViewController.init(url: url)
			let navVC = UINavigationController.init(rootViewController: safariVC)
			UIApplication.shared.keyWindow?.rootViewController?.present(navVC, animated: true, completion: nil)
		}
	}
  }
	
	func gotoNativeStoryBoard() {
		
	}
	
	/*- (void)goToReactNative {
	[self.window.rootViewController dismissViewControllerAnimated:TRUE completion:nil];
	}
	
	- (void)goNativeStoryboard {
	NSURL *url = [[NSURL alloc]initWithString:self.urlString];
	SFSafariViewController *safariVC = [[SFSafariViewController alloc]initWithURL:url];
	UINavigationController *navVC = [[UINavigationController alloc]initWithRootViewController:safariVC];
	[self.window.rootViewController presentViewController:navVC animated:true completion:nil];
	}*/
  
  // Mark - <IPSAKChatSessionDelegate>
  
  func chatInitialized(_ chat: IPSAKChat, with appConfig: IPSAKAppConfig) {
    //globalCallback!([appConfig.allowAnonymous])
    self.chat?.stepUp()
  }
  
  func chat(_ chat: IPSAKChat, domainSelectionRequired domains: [IPSAKDomain]) {
    self.domains = domains
    let domainDict = NSMutableDictionary.init()
    for domain in domains {
      domainDict.setObject([
		"id": domain.domainId,
		"name": domain.name!,
		"code": domain.code!,
		"localeDisplayName": domain.localeDisplayName!,
        "localeLanguageTag": domain.localeLanguageTag!,
		"requireLogin": domain.requireLogin,
		"hidden": domain.hidden
        ], forKey: domain.code as NSString)
    }
    globalCallback!([domainDict]);
  }
  
  func chatConversationStart(_ chat: IPSAKChat) {
    let passValues = [
      "conversationId": chat.conversationId,
      "domainName": chat.domain?.name,
      "username": chat.user?.name,
      "sessionId": chat.sessionId
    ]
    globalCallback!([passValues] )
  }
  
  func chat(_ chat: IPSAKChat, conversationFailWithError error: Error) {
    print(error.localizedDescription)
  }
  
  func chat(_ chat: IPSAKChat, loginRequiredWith authSystems: [IPSAKAuthSystem]) {
    if (authSystems[0].loginPath == "/login") {
        globalCallback!(["initializeSuccess","internal",authSystems[0].loginPath!])
		
    } else {
          //external  flow... show sFsafaricontroller.
        let authDict = [
          "identifier":  authSystems[0].identifier,
          "loginPath": authSystems[0].loginPath,
        ]
      self.authSystem = authSystems[0]
        globalCallback!(["initializeSuccess","external",authSystems[0].loginPath!] )
    }
  }
  
  func chat(_ chat: IPSAKChat, languageChangeFrom prevLanguageCode: String, to languageCode: String) {
  }
  
  // Returns an array of your named events
  override func supportedEvents() -> [String]! {
    return ["outboundTextMessage","onInputEnabledChanged"]
  }
  
  func chatLoginSuccess(_ chat: IPSAKChat) {
   // globalCallback = nil
    //globalCallback!([chat.user?.name])
    //self.sendEvent(withName: "loginResponse", body: chat.user?.name)
  }
  
  func chat(_ chat: IPSAKChat, loginFailWithError error: Error) {
    print(error.localizedDescription)
  }
  //run in main thread true
  @objc
  override static func requiresMainQueueSetup() -> Bool {
    return true
  }
  
  //Mark - IPSAKChatConversationDelegate
  func chat(_ chat: IPSAKChat, didReceiveAmeliaReadyMessage message: IPSAKMessage) {
    print("Amelia Ready  :- >", message.messageTypeString as Any)
  }
  
  func chat(_ chat: IPSAKChat, inputEnabled enabled: Bool) {
    print("Is Amelia Ready for  Message:-> ", enabled)
	let jsonObject: [String: Any] = [
		"enabled": enabled
	]
     self.sendEvent(withName: "onInputEnabledChanged", body: jsonObject)
  }
  
  func chat(_ chat: IPSAKChat, didReceive message: IPSAKMessage) {
    print("Message :->", message.messageText , "DidReceive message type :-> " , message.messageTypeString)
    if (message.messageType == .outboundText) {
      if let message = message.messageText {
		let messageObject: [String: Any] = [
			"message": message,
			"sender": "amelia"
		]
        self.sendEvent(withName: "outboundTextMessage", body: messageObject)
      }
    }
  }
  func chat(_ chat: IPSAKChat, didReceiveFinalErrorMessage message: IPSAKMessage) {
    print("error :-> ",message.messageText ?? " ")
  }
}
