//
//  SplashViewController.swift
//  NearbyStores
//
//  Created by DT Team on 5/19/18.
//  Copyright © 2018 Amine. All rights reserved.
//

import UIKit
import Alamofire
import Firebase
import CoreLocation
import AssistantKit

class SplashViewController: MyUIViewController, CLLocationManagerDelegate , ModulesManagerLoaderDelegate, LoginControllerDelegate{
 
   

    let locationManager = CLLocationManager()
    var currentLocation: CLLocationCoordinate2D? = nil
    
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        
        guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
        
        self.currentLocation = locValue
        Utils.printDebug("\(locations)")
        
    }
    
   
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
           
           guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
           self.currentLocation = locValue
           
           Utils.printDebug("locationManager \(CLLocationManager.authorizationStatus().rawValue)")
        
           if CLLocationManager.locationServicesEnabled() {
               
               switch CLLocationManager.authorizationStatus() {
                   
               
                   case .notDetermined, .restricted, .denied:
                       self.requestLocation()
                   case .authorizedAlways, .authorizedWhenInUse:
                       
                       self.requestLocation()
                       
                       DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
                           if Guest.isStored() == false {
                               self.guest_refresh(startMain: true)
                           }else{
                               self.guest_refresh(startMain: false)
                           }
                           
                       }
                       
                   default:
                       self.startApp()
                   }
               
           } else {
               
               if Constances.Global.GPS_REQUIRE_ENABLE{
                   self.enableGPS()
               }else {
                   self.requestLocation()
               }
               
           }
           
           
           
       }
    
    func requestLocation() {
        
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
        
    }
    
    
    @IBOutlet weak var app_icon_height: NSLayoutConstraint!
    @IBOutlet weak var app_icon_width: NSLayoutConstraint!
    @IBOutlet weak var splash_bg: UIImageView!
    @IBOutlet weak var animation_container: UIView!
    
    
    
    override func viewDidAppear(_ animated: Bool) {
        
        if stopExecute{
            return
        }
        
        if !Connectivity.isConnected() {
            self.showAlertInitError(title: "Opps - Connection error!".localized,msg: "\nCould't connect with server side!\n Please check your internet connection".localized,msgBnt: "Turn on".localized, clicked: {
                
                
                if let url = URL(string: UIApplication.openSettingsURLString) {
                    if UIApplication.shared.canOpenURL(url) {
                        if #available(iOS 10.0, *) {
                            UIApplication.shared.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
                        } else {
                            // Fallback on earlier versions
                        }
                    }
                }
                
            
                
                self.showAlertInitError(title: "Opps - Connection error!".localized,msg: "\nCould't connect with server side!\n Please check your internet connection".localized,msgBnt: "Refresh".localized, clicked: {
                    if Connectivity.isConnected() {
                        self.startApp()
                    }else{
                        self.viewDidAppear(true)
                    }
                })
                
            })
            //show alert
        }else{
            
            
            startApp()
            
            
        }
    }
    
    
    func setupBackgound()  {
     
    }

    
   
    override func viewDidLoad() {
        super.viewDidLoad()
        
      
        
        for familyName in UIFont.familyNames {
               print("FONT: \n-- \(familyName) \n")
               for fontName in UIFont.fontNames(forFamilyName: familyName) {
                   print(fontName)
               }
           }
       
        self.setupBackgound()
        self.requestLocation()
        self.requestLocation()
        self.getAllAppConfig()
        
        
        UIApplication.shared.statusBarView?.backgroundColor = Colors.darkColor
        
        app_icon_splash.isHidden = true

        
        if let language = Locale.current.languageCode{
            LocalData.setValue(key: "language", value: language)
        }else{
            LocalData.setValue(key: "language", value: "en")
        }
        
        
    }
    
    
    func startApp()  {
        
        
        //Setup location
        locationManager.delegate = self
        
        //remove caches
        self.initCache()
        
        //refresh FCM for push notification
        self.refreshFCM()
        
        //check user if is connected
        self.checkUserState()
        
        //check device version
        Utils.printDebug("Phone Inches => \(Device.screen)")
        Utils.printDebug("Phone Version => \(Device.version)")
        Utils.printDebug("Phone type => \(Device.type)")
        
        
        if Device.isPad{
            app_icon_width.constant = app_icon_width.constant+100
            app_icon_height.constant = app_icon_height.constant+100
        }
        
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
           // let animation = UIAnimation(view: self.app_icon_splash)
           // animation.zoomIn()
        }
        
        
        DispatchQueue.main.asyncAfter(deadline: .now() + 3.0) {
            
            if AppSetting.isInitialized() == false {
                //load token from server
                self.app_init()
            }else {
                //start next interface
                self.refreshFCM()
                
                if(Constances.Global.GPS_REQUIRE_ENABLE){
                    self.refreshLocationAndStartMain()
                }else{
                    
                    self.guest_refresh(startMain: false)
                    self.launchMainScreen()
                    //self.app_init()
                }
            }
        }
        
    }
    
    
    func refreshLocationAndStartMain() {
        
        
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
                
            case .notDetermined, .restricted, .denied:
                self.requestLocation()
            case .authorizedAlways, .authorizedWhenInUse:
                
                if Guest.isStored() {
                    self.launchMainScreen()
                }else{
                    self.guest_refresh(startMain: true)
                }
                
            }
            
        } else {
            
            if Constances.Global.GPS_REQUIRE_ENABLE{
                self.enableGPS()
            }else {
                self.requestLocation()
            }
            
        }
        
    }
    
    
    
    
    @IBOutlet weak var app_icon_splash: UIImageView!
    
    func startConnectionVC() {
        
        //stop updating location
        locationManager.stopUpdatingLocation()
        
        
        let sb = UIStoryboard(name: "Connection", bundle: nil)
        if let vc = sb.instantiateInitialViewController() {
            self.present(vc, animated: true, completion: nil)
        }
    }
    
    
    
    
    func launchMainScreen() {
        
        self.load_app_settings()
       
        
    }
    
    func startMainUI() {
        
        //stop updating location
        locationManager.stopUpdatingLocation()
       
        
        if !Session.isLogged(){
          
            startLoginView()
           
            return
        }

        
        startMainView()
        
    }
    
    func loginSuccess(controller: LoginViewController, user: User) {
        
        Session.createSession(user: user)
        
        controller.dismiss(animated: true)
        startMainView()
    }
    
    func loginFaild(controller: LoginViewController) {
        controller.dismiss(animated: true)
    }
    
    
    func startMainView(){
        
        let main = UINavigationController(rootViewController: MainViewController())
        main.modalPresentationStyle = .fullScreen
                          
        self.present(main, animated: true) {
            self.stopExecute = true
        }
    }
    
    func startLoginView(){
        
        let sb = UIStoryboard(name: "Login", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            let ms: LoginViewController = sb.instantiateViewController(withIdentifier: "loginVC") as! LoginViewController
            ms.modalPresentationStyle = .fullScreen
            
            ms.config.backHome = false
            ms.config.customToolbar = false
            
            ms.delegate = self
            self.present(ms, animated: true)
        }
        
    }
    
    
    func success(parser: ModulesParser, response: String) {
        
        if parser.success == 1{
            
            let list = parser.parse()
            Utils.printDebug("Modules: \(list[0])")
            
            list.saveAll()
            startMainUI()
            
            
            //adapt app config depend on modules states
            var newTabs: [String] = []
            
            for index in AppConfig.Tabs.Pages.enumerated(){
                if AppConfig.Tabs.Pages[index.offset] == AppConfig.Tabs.Tags.TAG_INBOX, ModuleManager.isEnabled(module: "messenger"){
                    newTabs.append(AppConfig.Tabs.Pages[index.offset])
                }else if AppConfig.Tabs.Pages[index.offset] == AppConfig.Tabs.Tags.TAG_GEO, ModuleManager.isEnabled(module: "store"){
                    newTabs.append(AppConfig.Tabs.Pages[index.offset])
                }else if AppConfig.Tabs.Pages[index.offset] == AppConfig.Tabs.Tags.TAG_ORDER, ModuleManager.isEnabled(module: "nsorder"){
                    newTabs.append(AppConfig.Tabs.Pages[index.offset])
                }else if AppConfig.Tabs.Pages[index.offset] == AppConfig.Tabs.Tags.TAG_MANAGED_ORDER, ModuleManager.isEnabled(module: "nsorder"){
                    newTabs.append(AppConfig.Tabs.Pages[index.offset])
                }
            }
            
             Utils.printDebug("Modules: \(newTabs)")
            
            
            AppConfig.Tabs.Pages = newTabs
            
           
        }else{
            
            Utils.printDebug("Modules: Loaded with exception")
            
        }
        
    }
       
    func error(error: Error?, response: String) {
        
        Utils.printDebug("Modules: Loaded & Launched with exception")
    
        startMainUI()
        
    }
    
    private var stopExecute = false;
    
    func app_init() {
        
        
        Utils.printDebug("Init started!")
        Utils.printDebug("Init started! \(Constances.Api.API_APP_INIT)")
        
        let api = MyApi()
        
        let headers = api.httpHeaders
        
        
        let params = [
            "Api-key-ios": AppConfig.Api.ios_api
        ]
        
        Utils.printDebug("Headers: \(headers)")
        
        AF.request(Constances.Api.API_APP_INIT,method: .post,parameters: params, headers: headers).responseJSON { response in
            
            if let error = response.error{
                Utils.printDebug("\(error)")
            }
            
            
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                
                Utils.printDebug("\(utf8Text)")
                
            }
            
            if let status = response.response?.statusCode {
                switch(status){
                case 201:
                    Utils.printDebug("Load success")
                case 500:
                    self.showError(status: 500)
                default:
                    
                    Utils.printDebug("error with response status: \(status)")
                }
            }
            
            Utils.printDebug("Init ended with data! ==> \(response.data!)")
            
            
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                
                
                if let jsonDataToVerify = utf8Text.data(using: String.Encoding.utf8)
                {
                    do {
                        _ = try JSONSerialization.jsonObject(with: jsonDataToVerify)
                        
                        Utils.printDebug("Init ended with json! ==> \(utf8Text)")
                        
                        let parser = Parser(content: utf8Text)
                        
                        if parser.success == 1 {
                            
                            let token = parser.json!["token"].stringValue
                            LocalData.setValue(key: "token", value: token)
                            
                            
                            if(Constances.Global.GPS_REQUIRE_ENABLE){
                                self.refreshFCM()
                                self.requestLocation()
                                self.refreshLocationAndStartMain()
                            }else{
                                self.guest_refresh(startMain: true)
                            }
                            
                        }else{
                            
                            self.locationManager.stopUpdatingLocation()
                            self.showAlertInitError(title: "Opps - Initialization error!".localized,msg: "\nCould't connect with server side!\n Please check API key".localized,msgBnt: "EXIT".localized, clicked: {
                                exit(0)
                            })
                            //show alert
                            
                            
                        }
                        
                        
                        
                    } catch {
                        
                        Utils.printDebug("Error deserializing JSON: \(error.localizedDescription)")
                        
                        self.showAlertInitError(title: "Opps - Initialization error!".localized,msg: "\nCould't connect with server side!\n Please check your network".localized,msgBnt: "EXIT".localized, clicked: {
                            exit(0)
                        })
                        
                        self.locationManager.stopUpdatingLocation()
                        
                    }
                    
                }else{
                    
                    self.refreshFCM()
                    self.requestLocation()
                    
                }
                
            }else{
                
                
            }
            
        }
        
        
    }
    
    
    func showError(status: Int)  {
        self.showAlertInitError(title: "Opps - Initialization error!",msg: "\nCould't connect with server side!\n error with response status: \(status)",msgBnt: "EXIT", clicked: {
            exit(0)
        })
    }
    
    
    
    func refreshFCM () {
        
      
    }
    
    
    
    func guest_refresh(startMain: Bool) {
        
       
        let token = LocalData.getValue(key: "firebase_fcm", defaultValue: "")
        if token != ""{
            self.guest_api_loader(token: token,startMain: startMain)
        }else{
            self.guest_api_loader(token: "NaN",startMain: startMain)
        }
        
        
    }
    
    
    
    func guest_api_loader(token: String,startMain: Bool){
        
        let api = MyApi()
        let headers = api.httpHeaders
        
        
        //Get current Location
        var lat = 0.0
        var lng = 0.0
        
        if let location = currentLocation {
            lat = location.latitude
            lng = location.longitude
        }
        
        
        let parameters = [
            "fcm_id": token,
            "sender_id": Token.getDeviceId(),
            "mac_adr": Token.getDeviceId(),
            "platform": "ios",
            "lat": String(lat),
            "lng":String(lng)
        ]
        
        
        Utils.printDebug("headers: \(headers)")
        Utils.printDebug("parameters: \(parameters)")
        
        
        AF.request(Constances.Api.API_USER_REGISTER_TOKEN,method: .post,parameters: parameters, headers: headers).responseJSON { response in
            
            
            if let error = response.error{
                Utils.printDebug("\(error)")
            }
            
            
            if let status = response.response?.statusCode {
                switch(status){
                case 201:
                    Utils.printDebug("Load success")
                case 500:
                    self.showError(status: 500)
                default:
                    Utils.printDebug("response with status: \(status)")
                    self.locationManager.stopUpdatingLocation()
                }
            }
            
            
            if let data = response.data, let utf8Text = String(data: data, encoding: .utf8) {
                
                Utils.printDebug("\(utf8Text)")
                
                let parser = GuestParser(content: utf8Text)
                
                if parser.success == 1 {
                    
                    let guests = parser.parse()
                    
                    if guests.count > 0 {
                        
                        Guest.saveGuest(guest: guests[0])
                        
                        if let g = Guest.getInstance() {
                            Utils.printDebug("Guest Instance ==> \(startMain) \(g)")
                        }
                        
                    }
                    
                    if startMain {
                        self.launchMainScreen()
                    }
                    
                    
                }else if parser.success == -1{
                    
                    if let errors = parser.errors{
                        
                        self.showAlertInitErrors(title: "Api error!".localized, content: errors, msgBnt: "EXIT")
                    }
                    
                }
                
            }else {
                
                if startMain {
                    self.launchMainScreen()
                }
                
                
            }
            
            
            
        }
        
    }
    
    
    
    
    
    
    func enableGPS()  {
        
        
        let alert = UIAlertController(
            title: "Enable GPS",
            message: "GPS access is restricted. In order to use tracking, please enable GPS in the Settigs app under Privacy, Location Services.",
            preferredStyle: UIAlertController.Style.alert
        )
        
        alert.addAction(UIAlertAction(title: "Go to Settings now".localized, style: UIAlertAction.Style.default, handler: { (alert: UIAlertAction!) in
            
            
            if !CLLocationManager.locationServicesEnabled() {
                
                if let url = URL(string: UIApplication.openSettingsURLString) {
                    if UIApplication.shared.canOpenURL(url) {
                        if #available(iOS 10.0, *) {
                            UIApplication.shared.open(url, options: convertToUIApplicationOpenExternalURLOptionsKeyDictionary([:]), completionHandler: nil)
                        } else {
                            // Fallback on earlier versions
                        }
                    }
                }
                
            } else {
                if let url = URL(string: UIApplication.openSettingsURLString) {
                    // If general location settings are enabled then open location settings for the app
                    UIApplication.shared.openURL(url)
                }
            }
            
        }))
        
        
        alert.addAction(UIAlertAction(title: "Open".localized, style: UIAlertAction.Style.default, handler: { (alert: UIAlertAction!) in
            
            self.startApp()
            
        }))
        
        self.present(alert, animated: true)
    }
    
    
    
    func initCache()  {
        
        //remove all stored messages
        Message.removeAll()
        MessengerCache.removeAll()
        OrderPayment.removeAll()
        Order.removeAll()
        
    }
    
    
    
    func checkUserState() {
        
        guard Session.isLogged() else { return }
        guard let session = Session.getInstance(), let user = session.user else { return }
        
        let api = UserLoader()
        
        let params = [
            "email":user.email,
            "userid":String(user.id),
            "username":user.username,
            "senderid":user.senderid,
            ]
        
        Utils.printDebug("\(params)")
        
        api.run(url: Constances.Api.API_USER_CHECK_CONNECTION, parameters: params) { (userParser) in
            
            guard let parser = userParser else{ return }
            
            Utils.printDebug("\(parser.success)")
            
            if parser.success == 1 {
                let users = parser.parse()
                if users.count == 0{
                    let _ = Session.logout()
                }else{
                    Utils.printDebug("\(users[0])")
                           
                    users[0].save()
                }
            }else if parser.success == -1 {
                let _ = Session.logout()
            }
            
        }
        
    }
    
    
    
    
    func load_app_settings(){
       
        let api = ModulesManagerLoader()
            var parameters = [
                   "moadules": ""
            ]
               
        if(Session.isLogged()){
                 
                   
        }
        
        api.delegate = self
        
        api.load(url: Constances.Api.API_GET_MODULES, parameters: parameters)
        
    }
    
    
    
    func getAllAppConfig() {


        //sync
        let parameters = [
            "test": ""
        ]


        let api = SimpleRequestApi()

        api.run(url: Constances.Api.API_GET_APP_CONFIG, parameters: parameters) { (parser) in

            if let result = parser?.result, parser?.success == 1 {

                let parser = SyncAppConfigParser(json: result)
                let list = parser.parse()
                list.saveAll()
                
            }

        }

    }
   
    
}

// Helper function inserted by Swift 4.2 migrator.
fileprivate func convertToUIApplicationOpenExternalURLOptionsKeyDictionary(_ input: [String: Any]) -> [UIApplication.OpenExternalURLOptionsKey: Any] {
	return Dictionary(uniqueKeysWithValues: input.map { key, value in (UIApplication.OpenExternalURLOptionsKey(rawValue: key), value)})
}


extension UIView{
    
    func setGradientBackground() {
        
        DispatchQueue.main.asyncAfter(deadline: .now()) {
            let grad = CAGradientLayer()
              grad.colors = [
                 Colors.color1.cgColor, // top color
                 Colors.color2.cgColor // bottom color
             ]

             grad.startPoint = CGPoint(x: 0.0, y: 0.8);
             grad.endPoint = CGPoint(x: 1.0, y: 0.8);
             
             grad.frame = self.bounds
            
             self.autoresizingMask = [.flexibleWidth, .flexibleHeight]
             self.layer.insertSublayer(grad, at: 0)
        }
   
    }
}

extension UIButton{
    
    func setCustomButtonStyleMain(){
        self.roundCorners(corners: [.topLeft, .topRight], radius: 20)
        self.setGradientBackground()
        self.tintColor = .white
        self.setTitleColor(.white, for: .normal)
        self.setTitleColor(.gray, for: .selected)
        self.layoutIfNeeded()
    }
    
    func setCustomButtonStyleRounded(){
        self.roundedCorners(radius: 10)
        self.setGradientBackground()
        self.tintColor = .white
        self.setTitleColor(.white, for: .normal)
        self.setTitleColor(.gray, for: .selected)
        self.layoutIfNeeded()
    }
    
    func setCustomButtonStyleDefault(){
        self.setGradientBackground()
        self.tintColor = .white
        self.setTitleColor(.white, for: .normal)
        self.setTitleColor(.gray, for: .selected)
        self.layoutIfNeeded()
    }
    
    
    func setCustomButtonControlStyle(){
    
        self.setTitleColor(Colors.primaryColor, for: .normal)
        self.setTitleColor(.gray, for: .selected)
        self.backgroundColor = .clear
        self.roundedCorners(radius: 20)
        self.layer.borderWidth = 1
        self.layer.borderColor = Colors.primaryColor.cgColor
        self.layoutIfNeeded()
        
    }
    
    func setCustomButtonControlStyle(active: Bool){
    
        if active{
            
            self.setTitleColor(.white, for: .normal)
            self.setTitleColor(.gray, for: .selected)
            self.backgroundColor = Colors.primaryColor
            self.roundedCorners(radius: 20)
            self.layer.borderWidth = 0
            self.layer.borderColor = Colors.primaryColor.cgColor
            
            
        }else{
            self.setTitleColor(Colors.primaryColor, for: .normal)
            self.setTitleColor(.gray, for: .selected)
            self.backgroundColor = .clear
            self.roundedCorners(radius: 20)
            self.layer.borderWidth = 1
            self.layer.borderColor = Colors.primaryColor.cgColor
            
        }
       
    }
    
   
 
    
}
