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

import UIKit
import SwiftIcons
import SwiftEventBus
import UserNotifications
import AssistantKit
import CoreLocation
import RealmSwift
import BadgeSwift
import FirebaseDatabase
import FirebaseAuth
import CoreLocation


class MyUITabBarController : UITabBarController {
    
    struct ViewControllerConfig {
        var toolbar: Bool = true
        var backHome: Bool = true
    }
    
    var config: ViewControllerConfig = ViewControllerConfig()
    
    override func viewDidLoad() {
        InComingDataParser.openViewEventBus(controller: self)
    }
    
    
}


class MyUICollectionViewController: UICollectionViewController {
    override func viewDidLoad() {
        InComingDataParser.openViewEventBus(controller: self)
        if #available(iOS 13.0, *) {
            overrideUserInterfaceStyle = .light
        }
    }
}

class MyUIViewController: UIViewController {
    
    struct ViewControllerConfig {
           var customToolbar: Bool = true
           var backHome: Bool = true
           var custom_title: String? = nil
       }
       
    var config: ViewControllerConfig = ViewControllerConfig()

    
    override func viewDidLoad() {
        InComingDataParser.openViewEventBus(controller: self)
        if #available(iOS 13.0, *) {
            overrideUserInterfaceStyle = .light
        }
    }
}


class MainViewController: MyUIViewController, MenuBarDelegate, CLLocationManagerDelegate, LoginControllerDelegate {
    
    
    func loginSuccess(controller: LoginViewController, user: User) {
        
        Session.createSession(user: user)
        count_notifications()
        controller.dismiss(animated: true)
        
        SwiftEventBus.post("on_refresh",sender: true)
        
    }
    
    func loginFaild(controller: LoginViewController) {
         controller.dismiss(animated: true)
    }
    
    
    
    
    let locationManager = CLLocationManager()
    var currentLocation: CLLocationCoordinate2D? = nil
    
    
    private var nbr_location_requests = 0
     func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
           
           guard let locValue: CLLocationCoordinate2D = manager.location?.coordinate else { return }
           
      
        
        if currentLocation != nil{
            
            let coordinate0 = CLLocation(latitude:   locValue.latitude, longitude: locValue.longitude)
            let coordinate1 = CLLocation(latitude: self.currentLocation!.latitude, longitude: self.currentLocation!.longitude)
            
            let distanceInMeters = coordinate0.distance(from: coordinate1) // result is in meters
            
            Utils.printDebug("\(locValue) - \(distanceInMeters)")
        
            if(distanceInMeters == 0){
                return
            }
           
        }
        
        
           self.currentLocation = locValue
            
           if let guest = Guest.getInstance(), let cl = self.currentLocation {
               
              
                let realm = try! Realm()
                try! realm.write {
                    
                    guest.lat = cl.latitude
                    guest.lng = cl.longitude
                    realm.add(guest,update: .all)
                    
                }
             
              
            
                //update user position in the firebase realtime
                self.update_user_position()
               self.nbr_location_requests = self.nbr_location_requests+1
           }
           
       }
    
    
    
    func locationManager(_ manager: CLLocationManager, didChangeAuthorization status: CLAuthorizationStatus) {
        
        
        if CLLocationManager.locationServicesEnabled() {
            switch CLLocationManager.authorizationStatus() {
            case .notDetermined, .restricted, .denied:
                self.requestLocation()
            case .authorizedAlways, .authorizedWhenInUse:
                self.requestLocation()
            }
        }
        
    }
    
    func requestLocation() {
        
        locationManager.delegate = self
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.requestWhenInUseAuthorization()
        locationManager.startUpdatingLocation()
    
        
    }
    
   
  
    
    private func setTitleForIndex(index: Int) {
        if let titleLabel = navigationItem.titleView as? UILabel {
            
            titleLabel.text = "\(AppConfig.Tabs.Pages[index].localized.capitalizingFirstLetter())"
            
        }
    }
    
    let topBarTitle: EdgeLabel = {
        
        let titleLabel = EdgeLabel()
        
        titleLabel.text = "Home".localized
        titleLabel.textColor = UIColor.white
        titleLabel.font = UIFont.systemFont(ofSize: 20)
        
        return titleLabel
        
    }()
    
    var ref: DatabaseReference!
    
    func setup_firebase_database() {
    
        ref = Database.database().reference()
        
        if let sess = Session.getInstance(), let user = sess.user, let guest = Guest.getInstance(){
            self.ref.child("users").child("user-\(user.id)").setValue(["lat": guest.lat,"lng": guest.lng])
        }
        
    
    }
    
    
    func update_user_position()  {
        
        if let sess = Session.getInstance(), let user = sess.user, let guest = Guest.getInstance(){
            self.ref.child("users").child("user-\(user.id)").setValue(["lat": guest.lat,"lng": guest.lng])
        }
        
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
    
        
        UIApplication.shared.applicationIconBadgeNumber = 0
        
        
        //update location
        self.locationManager.delegate = self
        self.requestLocation()
        self.setup_firebase_database()
        
       
        MainViewController.mInstance = self
        
        navigationController?.navigationBar.isTranslucent = true
        navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default)
        navigationController?.navigationBar.shadowImage = UIImage()
        navigationController?.navigationBar.tintColor = AppDesignUtils.defaultModeColor(dark: .white, light: .black)
        

    
        let rect = CGRect(x: 0, y: 0, width: view.frame.width - 32, height: view.frame.height)
        topBarTitle.frame = rect
        topBarTitle.textColor = AppDesignUtils.defaultModeColor(dark: .white, light: .black)
        topBarTitle.initDefaultFont(size: 17)
        
        topBarTitle.leftTextInset = 5
        topBarTitle.rightTextInset = 5
        
    
        navigationItem.titleView = topBarTitle
    
    
        UIApplication.shared.statusBarView?.backgroundColor = Colors.darkColor
        
        setupMenuBar()
        
        setupMainViewContainer()
        
        setupNavBarButtons()
        
        busEventsListiner()
        
        updateInboxBadge(count: Messenger.nbrMessagesNotSeen)
        
        //get notifications count from server
        count_notifications()
        
        
        
        view.backgroundColor = .white
        
    }
    
    
    func busEventsListiner() {
      
        
        SwiftEventBus.onMainThread(self, name: "on_main_refresh") { result in
            
            if let _ = result?.object{
            
                self.settingsLauncher.load()
              
            }
            
        }
        
        SwiftEventBus.onMainThread(self, name: "on_badge_refresh") { result in
            
            if let _ = result?.object{
                
                self.updateInboxBadge(count: Messenger.nbrMessagesNotSeen)
                
            }
            
        }
        
        
        SwiftEventBus.onMainThread(self, name: "on_main_redirect") { result in
            
            if let index = result?.object{
                
                let indexPath = IndexPath(item: index as! Int, section: 0)
                
                self.setTitleForIndex(index: index as! Int)
                self.activePage(index: index as! Int)
                self.menuBar.collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
                self.menuBar.collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .left)

            }
            
        }
        
        SwiftEventBus.onMainThread(self, name: "on_receive_message") { result in
            
            if let object = result?.object{
                
                
                if Session.isLogged() {
                    
                    let message: Message = object as! Message
                    message.save()
                    
                    guard MessengerViewController.isAppear == false else {
                        Messenger.nbrMessagesNotSeen = 0
                        self.updateInboxBadge(count: Messenger.nbrMessagesNotSeen)
                        return
                    }
                    
                    Messenger.nbrMessagesNotSeen += 1
                    
                    self.updateInboxBadge(count: Messenger.nbrMessagesNotSeen)
                    
                    if Messenger.nbrMessagesNotSeen == 1 {
                        
                        NotificationManager.push(
                            title: "New Message".localized,
                            subtitle: message.message,
                            identifier: InComingDataParser.tag_new_message
                        )
                        
                    }else if Messenger.nbrMessagesNotSeen > 1 &&  Messenger.nbrMessagesNotSeen < 3 {
                        
                        NotificationManager.push(
                            title: AppConfig.APP_NAME,
                            subtitle: "You have %@ messages".localized.format(arguments: String(Messenger.nbrMessagesNotSeen)),
                            identifier: InComingDataParser.tag_new_message
                        )
                        
                    }
                    
                }
                
            
                
            }
            
            
            
        }
        
        
        SwiftEventBus.onMainThread(self, name: "decrease_notifications_badge") { result in
            
            guard let b = self.notifBarButtonItem else {
                return
            }
            
            let button: BadgeButton = b.customView as! BadgeButton
            
            if(button.notification>0){
                self.updateNotificationBadge(count: button.notification-1)
            }else{
                self.updateNotificationBadge(count: 0)
            }
            
        }
        
        SwiftEventBus.onMainThread(self, name: "increase_notifications_badge") { result in
            
            guard let b = self.notifBarButtonItem else {
                return
            }
            
            let button: BadgeButton = b.customView as! BadgeButton
            
            if(button.notification>0){
                self.updateNotificationBadge(count: button.notification+1)
            }else{
                self.updateNotificationBadge(count: 0)
            }
            
        }
        
        
        SwiftEventBus.onMainThread(self, name: "set_active_page") { result in
            
            Utils.printDebug("\(result!.object)")
            
            let page = result!.object as! String
            
            let size = AppConfig.Tabs.Pages.count-1
            for index in 0...size{
                if(page == AppConfig.Tabs.Pages[index]){

                    let indexPath = IndexPath(item: index as! Int, section: 0)
                    
                    self.menuBar.collectionView.scrollToItem(at: indexPath, at: .left, animated: true)
                    self.menuBar.collectionView.selectItem(at: indexPath, animated: true, scrollPosition: .left)
                    
                    self.activePage(index: index)
                }
            }
            
            
        }
        
    }
    

    
    static var isAppear = false
    override func viewWillDisappear(_ animated: Bool) {
        MainViewController.isAppear = false
    }
    
    
    override func viewWillAppear(_ animated: Bool) {
         MainViewController.isAppear = true
    }
    
    

    var moreBarButtonItem: UIBarButtonItem? = nil
    var notifBarButtonItem: UIBarButtonItem? = nil
    
    func setupNavBarButtons() {
        
        let color = AppDesignUtils.defaultModeColor(dark: .white, light: .black)
        
    
        //setup more icon btn
        let moreIcon = UIImage.init(icon: .linearIcons(.list), size: CGSize(width: 30, height: 30), textColor: color)
        moreBarButtonItem = UIBarButtonItem(image: moreIcon, style: .plain, target: self, action: #selector(handleMore))
        
        
        //setup notification icon btn
        let button = BadgeButton()
        button.setIcon(icon: .linearIcons(.alarm), iconSize: 24, color: color, forState: .normal)
        button.setupBadge().refreshBadge(count: 0)
        button.addTarget(self, action: #selector(didOnTapNotification), for: .touchUpInside)
        notifBarButtonItem = UIBarButtonItem(customView: button)
        
    
        navigationItem.rightBarButtonItems = []
        
        
        if let btn = moreBarButtonItem{
            navigationItem.rightBarButtonItems?.append(btn)
        }
        
        if let btn = notifBarButtonItem{
            navigationItem.rightBarButtonItems?.append(btn)
        }
       
        
        
    
    }
    
    static var count_notifications = 0
    
    func updateNotificationBadge(count: Int) {
    
        guard let b = notifBarButtonItem else {
            return
        }
        
        let button: BadgeButton = b.customView as! BadgeButton
        button.refreshBadge(count: count)
        
    }
    
    @objc func didOnTapNotification() {
        
        
        self.startNotificationListVC()
        
        /*if(Session.isLogged()){
            self.startNotificationListVC()
        }else{
        
            let sb = UIStoryboard(name: "Login", bundle: nil)
            if sb.instantiateInitialViewController() != nil {
                let ms: LoginViewController = sb.instantiateViewController(withIdentifier: "loginVC") as! LoginViewController
                ms.delegate = self
                navigationController?.present(ms, animated: true)
            }
        }*/
        
    }
    
    func setupInboxBadge() {
        
    }
    
    
    func updateInboxBadge(count: Int) {
        
        let size = AppConfig.Tabs.Pages.count-1
        for index in 0...size{
            if AppConfig.Tabs.Pages[index] == AppConfig.Tabs.Tags.TAG_INBOX{
                let indexPath = IndexPath(item: index, section: 0)
                
                let current = IndexPath(item: self.currentPage, section: 0)
                menuBar.refreshBadge(at: indexPath, count: count,current: current)
            
            }
        }
    }
    
    
    lazy var settingsLauncher: SettingsLauncher = {
        let launcher = SettingsLauncher()
        launcher.mainController = self
        return launcher
    }()
    
    @objc func handleMore() {
        settingsLauncher.showSettings()
    }
    
    
    func showControllerForSetting(setting: Setting) {
        
        if setting.id == MenuIDList.LOGOUT{
            
            if Session.logout() {
                
                self.settingsLauncher.load()
                
                let sb = UIStoryboard(name: "Login", bundle: nil)
                if sb.instantiateInitialViewController() != nil {
                    let ms: LoginViewController = sb.instantiateViewController(withIdentifier: "loginVC") as! LoginViewController
                    ms.delegate = self
                    
                    ms.config.backHome = false
                    ms.config.customToolbar = false
                    
                    ms.modalPresentationStyle = .fullScreen
                    self.present(ms, animated: true)
                    return
                }
            }
            
        }else if setting.id == MenuIDList.CHAT_LOGIN{
            if Session.isLogged() == false {
                if let vc = MainViewController.mInstance {
                    vc.startLoginVC()
                }
            }
        }else if setting.id == MenuIDList.PAYMENT{
            if Session.isLogged() == true {
                if let vc = MainViewController.mInstance {
                    vc.starDP_vc()
                }
            }
        }else if setting.id == MenuIDList.WALLET{
            
            if Session.isLogged() {
                startWalletVC()
            }else{
                startLoginVC()
            }
            
        }else if setting.id == MenuIDList.EDIT_PROFILE {
            
            if Session.isLogged(){
                startEditProfileVC()
            }
            
        }else if setting.id == MenuIDList.ABOUT {
            
             startAboutVC()
            
        }else if setting.id == MenuIDList.SETTING {
            
            self.startSettingVC()
            
        }
        
    }
    
    func startWalletVC() {
        
        let sb = UIStoryboard(name: "MyWallet", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            let ms: MyWalletController = sb.instantiateViewController(withIdentifier: "walletVC") as! MyWalletController
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    
    //avaliable in 14+
    func setupMainViewContainer() {
       
        
        let container = UIView()
        container.frame = view.bounds
        container.backgroundColor = Colors.bg_gray_100
        view.addSubview(container)
        
        container.translatesAutoresizingMaskIntoConstraints = false
        
        let constraints = [
            container.topAnchor.constraint(equalTo: menuBar.bottomAnchor),
            container.leadingAnchor.constraint(equalTo: view.leadingAnchor),
            container.bottomAnchor.constraint(equalTo: view.bottomAnchor),
            container.trailingAnchor.constraint(equalTo: view.trailingAnchor)
        ]
        
        view.addConstraints(constraints)
    
        
        let size = AppConfig.Tabs.Pages.count-1
        for index in 0...size{
             
            if(AppConfig.Tabs.Pages[index] == AppConfig.Tabs.Tags.TAG_ORDER){
                
                let list = ListOrderCell()
                list.frame = container.bounds
                container.addSubview(list)
                view.addConstraintsWithFormat(format: "H:|[v0]|", views: list)
                view.addConstraintsWithFormat(format: "V:|[v0]|", views: list)
            
                list.__req_list = ListOrderCell.Request.nearby
                list.__req_delivery_status = OrderDeliveryStatus.PENDING
                list.__req_order_status = OrderStatus.CONFIRMED
                list.__req_limit = 1
                list.__req_except = LocalData.getValue(key: "declined_orders",defaultValue: "")
                
                list.setupViews()
                list.viewController = self
                
                list.isHidden = true
              
                list_views[AppConfig.Tabs.Tags.TAG_ORDER] = list
                
            }else if(AppConfig.Tabs.Pages[index] == AppConfig.Tabs.Tags.TAG_MANAGED_ORDER){
                
                let list = ListOrderCell()
                list.frame = container.bounds
                container.addSubview(list)
                view.addConstraintsWithFormat(format: "H:|[v0]|", views: list)
                view.addConstraintsWithFormat(format: "V:|[v0]|", views: list)
            
                list.__req_list = ListOrderCell.Request.recent
                list.__req_delivery_status = OrderDeliveryStatus.ALL
                list.__req_order_status = OrderStatus.ALL
                
                if let sess = Session.getInstance(), let user = sess.user{
                    list.__req_delivery_id = user.id
                }
               
                list.setupViews()
                list.viewController = self
               
                list.isHidden = true
              
                list_views[AppConfig.Tabs.Tags.TAG_MANAGED_ORDER] = list
                
            }else if(AppConfig.Tabs.Pages[index] == AppConfig.Tabs.Tags.TAG_INBOX){
                
                let list = ListDiscussionView()
                list.frame = container.bounds
                container.addSubview(list)
                view.addConstraintsWithFormat(format: "H:|[v0]|", views: list)
                view.addConstraintsWithFormat(format: "V:|[v0]|", views: list)
            
                list.setupViews()
                list.viewController = self
                
                list.isHidden = true
               
                list_views[AppConfig.Tabs.Tags.TAG_INBOX] = list
                
            }
            
        }
        
       activePage(index: 0)
        
    }
    
    func reloadMain(_ index: Int?) {
        if index != nil{
            view.removeFromSuperview()
        }
    }
    
    var currentPage = 0
    private func activePage(index: Int) {
        
        for (_,v) in list_views{
            v.isHidden = true
        }
        
        let tab = AppConfig.Tabs.Pages[index]
        list_views[tab]?.isHidden = false
    
        if(!list_views[tab]!.isFetched){
            list_views[tab]?.fetch(request: BaseView.Request.nearby)
        }
        
        currentPage = index
    }
    
    var list_views: [String: BaseView] = [:]
    
    
    lazy var menuBar: MenuBar = {
        let mb = MenuBar()
        return mb
    }()
    
    private func setupMenuBar(){
          
        if AppConfig.Tabs.Pages.count > 1 {
            
            let bgViw = UIView()
            bgViw.backgroundColor = .clear
            
            
            view.addSubview(bgViw)
            
            view.addConstraintsWithFormat(format: "H:|[v0]|", views: bgViw)
            view.addConstraintsWithFormat(format: "V:[v0(50)]", views: bgViw)
            
            menuBar.delegate = self
            
            view.addSubview(menuBar)
            
          
            view.addConstraintsWithFormat(format: "H:|[v0]|",views: menuBar)
            view.addConstraintsWithFormat(format: "V:[v0(50)]", views: menuBar)
    
            menuBar.topAnchor.constraint(equalTo: topLayoutGuide.bottomAnchor).isActive = true
            
        }else{
            menuBar.isHidden = true
        }
       
    }
    
    
    
    func scrollToMenuIndex(index menuIndex: Int) {
        
        setTitleForIndex(index: menuIndex)
        activePage(index: menuIndex)
        
    }
    
   
   
    static var mInstance: MainViewController? = nil
    
    func startLoginVC() {
        
        let sb = UIStoryboard(name: "Login", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: LoginViewController = sb.instantiateViewController(withIdentifier: "loginVC") as! LoginViewController
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    
    func starDP_vc() {
        
        let sb = UIStoryboard(name: "DeliveryProfile", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: DeliveryProfileController = sb.instantiateViewController(withIdentifier: "dp_vc") as! DeliveryProfileController
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    
    func startSignUpVC() {
        
        let sb = UIStoryboard(name: "SignUp", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: SignUpViewController = sb.instantiateViewController(withIdentifier: "signupVC") as! SignUpViewController
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    func startEditProfileVC() {
        
        let sb = UIStoryboard(name: "EditProfile", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: EditProfileViewController = sb.instantiateViewController(withIdentifier: "editprofileVC") as! EditProfileViewController
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    
    func startMessenger(client_id: Int,discussion_id: Int) {
        
        let sb = UIStoryboard(name: "Messenger", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: MessengerViewController = sb.instantiateViewController(withIdentifier: "messengerVC") as! MessengerViewController
            ms.client_id = client_id
            ms.discussionId = discussion_id
            
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    func startMessenger(client_id: Int) {
        
        let sb = UIStoryboard(name: "Messenger", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: MessengerViewController = sb.instantiateViewController(withIdentifier: "messengerVC") as! MessengerViewController
            ms.client_id = client_id
           
            navigationController?.present(ms, animated: true)
        }
        
    }
    

    
    func startStoreDetailVC(store_id: Int) {
        
        let sb = UIStoryboard(name: "StoreDetail", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: StoreDetailViewController = sb.instantiateViewController(withIdentifier: "storedetailVC") as! StoreDetailViewController
            ms.storeId = store_id
            
            navigationController?.present(ms, animated: true)
        }
        
    }

    
 
    
    
    func startAboutVC() {
        
        let sb = UIStoryboard(name: "About", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: AboutViewController = sb.instantiateViewController(withIdentifier: "aboutVC") as! AboutViewController
    
            navigationController?.present(ms, animated: true)
        }
        
    }
    
    
    func startSettingVC() {
        
        let sb = UIStoryboard(name: "Settings", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            let ms: SettingsViewController = sb.instantiateViewController(withIdentifier: "settingsVC") as! SettingsViewController
            navigationController?.pushViewController(ms, animated: true)
        }
        
    }
    
    
    func startNotificationListVC() {
        
        let sb = UIStoryboard(name: "Notification", bundle: nil)
        if sb.instantiateInitialViewController() != nil {
            
            let ms: NotificationViewController = sb.instantiateViewController(withIdentifier: "notificationVC") as! NotificationViewController
            
            navigationController?.present(ms, animated: true)
        }
        
    }
    

    
    func error(error: Error?, response: String) {
        
    }
    
    
    func count_notifications(){
    
    
        let api = SimpleRequestApi()
        var parameters = [
            "status": "\(0)"
        ]
        
        if(Session.isLogged()){
            if let sess = Session.getInstance(), let user = sess.user{
            
                parameters["user_id"] = "\(user.id)"
                
                if let guest = Guest.getInstance(){
                    parameters["guest_id"] = "\(guest.id)"
                }
                
                
            }
        }else if let guest = Guest.getInstance(){
            parameters["auth_type"] = "guest"
            parameters["auth_id"] = "\(guest.id)"
        }
        
        
         Utils.printDebug("count_notifications===>parameters===> \(parameters)")
        
        api.run(url: Constances.Api.API_GET_NOTIFICATIONS_COUNT, parameters: parameters) { (parser) in
        
            if(parser?.success == 1){
                
                Utils.printDebug("\(parser)")
                
                
                
                if let count = parser?.result?.intValue{
                    self.updateNotificationBadge(count: count)
                }
               
            }
            
        }
        
        
    }
    
}





    
    
    
    
    
    
    
    
