//
//  ARNKakaoNavi.swift
//  ARNKakaoNavi
//
//  Created by Suhan Moon on 2020/08/30.
//

import Foundation
import KakaoSDKCommon
import KakaoSDKNavi
import SafariServices

@objc(ARNKakaoNavi)
public class ARNKakaoNavi: NSObject {

    @objc
    static func requiresMainQueueSetup() -> Bool {
      return true
    }
    
    public override init() {
        var appKey: String? = Bundle.main.object(forInfoDictionaryKey: "KAKAO_APP_KEY") as? String
        KakaoSDKCommon.initSDK(appKey: appKey!)
    }
    
    @objc(share:options:viaList:resolver:rejector:)
    func share(_ location: [String: String], options: [String: Any], viaList: NSArray,
               resolver resolve: @escaping RCTPromiseResolveBlock,
               rejector reject: @escaping RCTPromiseRejectBlock) -> Void {
        
        let destination = NaviLocation(
            name: location["name"] as! String,
            x: location["x"] as! String,
            y: location["y"] as! String
        )
        
        var _viaList: [NaviLocation] = [];
        for object in viaList {
            if let object = object as? NSDictionary {
                let viaDest = NaviLocation(
                    name: object["name"] as! String,
                    x: object["x"] as! String,
                    y: object["y"] as! String
                )
                _viaList.append(viaDest)
            }
        }
        
        let _option: NaviOption = NaviOption(
            coordType: options["coordType"] == nil ? nil : CoordType.init(rawValue: options["coordType"] as! String),
            vehicleType: options["vehicleType"] == nil ? nil : VehicleType.init(rawValue: options["vehicleType"] as! Int),
            rpOption: options["rpOption"] == nil ? nil : RpOption.init(rawValue: options["rpOption"] as! Int),
            routeInfo: options["routeInfo"] == nil ? nil : options["routeInfo"] as! Bool,
            startX: options["startX"] == nil ? nil : options["startX"] as! String,
            startY: options["startY"] == nil ? nil : options["startY"] as! String,
            startAngle: options["startAngle"] == nil ? nil : options["startAngle"] as! Int,
            returnUri: options["returnUri"] == nil ? nil : URL(string: (options["returnUri"] as! String))
        )

        guard let shareUrl = NaviApi.shared.shareUrl(destination: destination, option: _option, viaList: _viaList) else {
            reject("ARNKakaoNavi", "", nil)
            return
        }

        resolve([
            "share_url": shareUrl.absoluteString,
        ])
        
    }
    
    @objc(navigate:options:viaList:resolver:rejector:)
    func navigate(_ location: NSDictionary,
                  options: NSDictionary,
                  viaList: NSArray,
                  resolver resolve: @escaping RCTPromiseResolveBlock,
                  rejector reject: @escaping RCTPromiseRejectBlock) -> Void {
        
        let destination = NaviLocation(
            name: location["name"] as! String,
            x: location["x"] as! String,
            y: location["y"] as! String
        )
        
        var _viaList: [NaviLocation] = [];
        for object in viaList {
            if let object = object as? NSDictionary {
                let viaDest = NaviLocation(
                    name: object["name"] as! String,
                    x: object["x"] as! String,
                    y: object["y"] as! String
                )
                _viaList.append(viaDest)
            }
        }
        
        let _option: NaviOption = NaviOption(
            coordType: options["coordType"] == nil ? nil : CoordType.init(rawValue: options["coordType"] as! String),
            vehicleType: options["vehicleType"] == nil ? nil : VehicleType.init(rawValue: options["vehicleType"] as! Int),
            rpOption: options["rpOption"] == nil ? nil : RpOption.init(rawValue: options["rpOption"] as! Int),
            routeInfo: options["routeInfo"] == nil ? nil : options["routeInfo"] as! Bool,
            startX: options["startX"] == nil ? nil : options["startX"] as! String,
            startY: options["startY"] == nil ? nil : options["startY"] as! String,
            startAngle: options["startAngle"] == nil ? nil : options["startAngle"] as! Int,
            returnUri: options["returnUri"] == nil ? nil : URL(string: (options["returnUri"] as! String))
        )

        guard let navigateUrl = NaviApi.shared.navigateUrl(destination: destination, option: _option, viaList: _viaList) else {
            reject("ARNKakaoNavi", "", nil)
            return
        }

        var url = NaviApi.shared.webNavigateUrl(destination: destination, option: _option, viaList: _viaList)!
        
        DispatchQueue.main.async {
            UIApplication.shared.open(navigateUrl, options: [:]) { success in
                resolve([
                    "success": success,
                    "web_navigate_url": url.absoluteString,
                ])
            }
        }
        
        
    }
    
}
