//
//  ChatUserListVC.swift
//  WoWonder
//
//  Created by UnikaApp on 12/10/22.
//  Copyright © 2022 ScriptSun. All rights reserved.
//

import UIKit
import Async
import Alamofire
import SwiftEventBus
import WowonderMessengerSDK
import GoogleMobileAds
import FBAudienceNetwork
import Toast_Swift
import CoreData
import SDWebImage
import DropDown

class ChatUserListVC: BaseVC {
    
    enum ListType {
        case CHATS
        case GROUP
        case ARCHIVE
    }
    
    // MARK: - IBOutlet
    
    @IBOutlet weak var searchButton: UIButton!
    @IBOutlet weak var moreButton: UIButton!
    @IBOutlet weak var findFriendButton: UIButton!
    @IBOutlet weak var containerView: UIView!
    @IBOutlet weak var chatsView: UIView!
    @IBOutlet weak var chatsLabel: UILabel!
    @IBOutlet weak var chatsContentView: UIView!
    @IBOutlet weak var chatsTableView: UITableView!
    @IBOutlet weak var chatsEmptyView: UIView!
    @IBOutlet weak var groupView: UIView!
    @IBOutlet weak var groupLabel: UILabel!
    @IBOutlet weak var groupContentView: UIView!
    @IBOutlet weak var groupTableView: UITableView!
    @IBOutlet weak var groupEmptyView: UIView!
    @IBOutlet weak var archiveView: UIView!
    @IBOutlet weak var archiveLabel: UILabel!
    @IBOutlet weak var archiveContentView: UIView!
    @IBOutlet weak var archiveTableView: UITableView!
    @IBOutlet weak var archiveEmptyView: UIView!
    
    // MARK: - Properties
    
    var listType: ListType = .CHATS
    private let dropDown = DropDown()
    private var dropDownDataSource = [
        "Request",
        "Broadcast"
    ]
    private var fetchSatus: Bool? = true
    private var requestsGroup = DispatchGroup()
    var groupfetchSatus: Bool = true
    var groupChatRequestArray = [GroupRequestModel.GroupChatRequest]()
    var saveDataArray: [Chats] = []
    var groupsArray: [GroupData] = []
    var groupChats: [GroupChat] = []
    var groupApiData: GroupData?
    var archiveChats: [Chats] = []
    let socketHelper = SocketHelper.shared
    let notificationBuilder = LocalNotificationBuilder.shared
    var backgroundTask: UIBackgroundTaskIdentifier = .invalid
    
    // MARK: - View Life Cycles
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        
        self.initialConfig()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        
        switch self.listType {
        case .CHATS:
            self.fetchChatsData()
        case .GROUP:
            self.fetchGroupChatData()
        case .ARCHIVE:
            self.getArchivedChats()
        }
    }
    
    // MARK: - Selectors
    
    // Seacrh Button Action
    @IBAction func searchButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        if let newVC = R.storyboard.dashboard.searchRandomVC() {
            self.navigationController?.pushViewController(newVC, animated: true)
        }
    }
    
    // More Button Action
    @IBAction func moreButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.dropDown.show()
    }
    
    // Find Friend Button Action
    @IBAction func findFriendButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        if let newVC = R.storyboard.dashboard.findFriendsViewController() {
            newVC.findFriendFilterModel.distance = "0"
            self.navigationController?.pushViewController(newVC, animated: true)
        }
    }
    
    // Chats Button Action
    @IBAction func chatsButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.listType = .CHATS
        self.setUpUI(listType: self.listType)
        self.fetchChatsData()
    }
    
    // Group Button Action
    @IBAction func groupButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.listType = .GROUP
        self.setUpUI(listType: self.listType)
        self.fetchGroupChatData()
    }
    
    // Archive Button Action
    @IBAction func archiveButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.listType = .ARCHIVE
        self.setUpUI(listType: self.listType)
        self.getArchivedChats()
    }
    
    // Chats Refresh
    @objc func chatsRefresh() {
        self.saveDataArray = []
        self.fetchChatsData()
    }
    
    // Handle Chats List Long Tap
    @objc func handleChatsListLongTap(sender: UILongPressGestureRecognizer) {
        let objSender = sender.location(in: self.chatsTableView)
        let indexPath = self.chatsTableView.indexPathForRow(at: objSender)
        if let indexPath = indexPath {
            if let user = self.saveDataArray[indexPath.row].getFirstChatUser()?.user {
                if let newVC = R.storyboard.dashboard.chatUserListBottomVC() {
                    newVC.modalPresentationStyle = .custom
                    newVC.transitioningDelegate = self
                    newVC.delegate = self
                    newVC.indexPath = indexPath
                    newVC.user = user
                    self.present(newVC, animated: true)
                }
            }
        }
    }
    
    // Handle Chats List Long Tap
    @objc func handleArchiveChatsListLongTap(sender: UILongPressGestureRecognizer) {
        let objSender = sender.location(in: self.archiveTableView)
        let indexPath = self.archiveTableView.indexPathForRow(at: objSender)
        if let indexPath = indexPath {
            if let user = self.archiveChats[indexPath.row].getFirstChatUser()?.user {
                if let newVC = R.storyboard.dashboard.chatUserListBottomVC() {
                    newVC.modalPresentationStyle = .custom
                    newVC.transitioningDelegate = self
                    newVC.delegate = self
                    newVC.indexPath = indexPath
                    newVC.user = user
                    self.present(newVC, animated: true)
                }
            }
        }
    }
    
    // Group Refresh
    @objc func groupRefresh() {
        self.groupChats = []
        self.fetchGroupChatData()
    }
    
    // Handle Group List Long Tap
    @objc func handleGroupListLongTap(sender: UILongPressGestureRecognizer) {
        let objSender = sender.location(in: self.groupTableView)
        let indexPath = self.groupTableView.indexPathForRow(at: objSender)
        if indexPath != nil {
            if let newVC = R.storyboard.dashboard.groupListBottomViewController() {
                newVC.modalPresentationStyle = .custom
                newVC.transitioningDelegate = self
                newVC.delegate = self
                newVC.indexPath = indexPath ?? IndexPath()
                newVC.groupData = self.groupChats[indexPath?.row ?? 0]
                self.present(newVC, animated: true)
            }
        }
    }
    
    // MARK: - Helper Functions
    
    // Initial Config
    func initialConfig() {
        SwiftEventBus.onMainThread(self, name: "ForwardMessage") { notification in
            if let user_id = notification?.object as? String {
                var chatModel: Chats?
                for chat in self.saveDataArray {
                    if chat.getChatUsers().first?.user?.user_id == user_id {
                        chatModel = chat
                        break
                    }
                }
                if let chats = chatModel {
                    let newVC = R.storyboard.chat.chatViewController()
                    newVC?.chatModel = chats
                    newVC?.recipientID = user_id
                    self.navigationController?.pushViewController(newVC!, animated: false)
                }
            }
        }
        self.setUpTableView()
        self.setUpUI(listType: self.listType)
        self.setupDropDown()
        self.callApiInBackground()
        self.getSocketResponse()
        self.notificationBuilder.setActions().setCategory()
        let chatsLongPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleChatsListLongTap))
        self.chatsTableView.addGestureRecognizer(chatsLongPressRecognizer)
        let groupLongPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleGroupListLongTap))
        self.groupTableView.addGestureRecognizer(groupLongPressRecognizer)
        let archiveChatsLongPressRecognizer = UILongPressGestureRecognizer(target: self, action: #selector(handleArchiveChatsListLongTap))
        self.archiveTableView.addGestureRecognizer(archiveChatsLongPressRecognizer)
    }
    
    // SetUp TableView
    func setUpTableView() {
        self.chatsTableView.delegate = self
        self.chatsTableView.dataSource = self
        self.chatsTableView.register(UINib(resource: R.nib.userListChatCell), forCellReuseIdentifier: R.reuseIdentifier.userListChatCell.identifier)
        self.chatsTableView.refreshControl = UIRefreshControl()
        self.chatsTableView.refreshControl?.addTarget(self, action: #selector(self.chatsRefresh), for: .valueChanged)
        
        self.groupTableView.delegate = self
        self.groupTableView.dataSource = self
        self.groupTableView.register(UINib(resource: R.nib.userListChatCell), forCellReuseIdentifier: R.reuseIdentifier.userListChatCell.identifier)
        self.groupTableView.refreshControl = UIRefreshControl()
        self.groupTableView.refreshControl?.addTarget(self, action: #selector(self.groupRefresh), for: .valueChanged)
        
        self.archiveTableView.delegate = self
        self.archiveTableView.dataSource = self
        self.archiveTableView.register(UINib(resource: R.nib.userListChatCell), forCellReuseIdentifier: R.reuseIdentifier.userListChatCell.identifier)
    }
    
    // SetUp Chats View
    private func setUpUI(listType: ListType) {
        switch listType {
        case .CHATS:
            self.chatsContentView.isHidden = false
            self.groupContentView.isHidden = true
            self.archiveContentView.isHidden = true
            self.chatsView.backgroundColor = .accent
            self.chatsLabel.textColor = .gnt_white
            self.groupView.backgroundColor = UIColor.clear
            self.groupLabel.textColor = .text_color_in_between
            self.archiveView.backgroundColor = UIColor.clear
            self.archiveLabel.textColor = .text_color_in_between
        case .GROUP:
            self.chatsContentView.isHidden = true
            self.groupContentView.isHidden = false
            self.archiveContentView.isHidden = true
            self.chatsView.backgroundColor = UIColor.clear
            self.chatsLabel.textColor = .text_color_in_between
            self.groupView.backgroundColor = .accent
            self.groupLabel.textColor = .gnt_white
            self.archiveView.backgroundColor = UIColor.clear
            self.archiveLabel.textColor = .text_color_in_between
        case .ARCHIVE:
            self.chatsContentView.isHidden = true
            self.groupContentView.isHidden = true
            self.archiveContentView.isHidden = false
            self.chatsView.backgroundColor = UIColor.clear
            self.chatsLabel.textColor = .text_color_in_between
            self.groupView.backgroundColor = UIColor.clear
            self.groupLabel.textColor = .text_color_in_between
            self.archiveView.backgroundColor = .accent
            self.archiveLabel.textColor = .gnt_white
        }
    }
    
    private func setupDropDown() {
        self.dropDown.dataSource = self.dropDownDataSource
        self.dropDown.anchorView = self.moreButton
        self.dropDown.width = 160
        self.dropDown.bottomOffset = CGPoint(x: -124, y: 34)
        self.dropDown.direction = .bottom
        self.dropDown.sizeToFit()
        self.dropDown.selectionAction = { [unowned self] (index: Int, item: String) in
            if item == "Request" {
                if let newVC = R.storyboard.dashboard.requestViewController() {
                    self.navigationController?.pushViewController(newVC, animated: true)
                }
            }
            if item == "Broadcast" {
                if let newVC = R.storyboard.broadcast.broadcastVC() {
                    self.navigationController?.pushViewController(newVC, animated: true)
                }
            }
            self.dropDown.deselectRow(at: index)
            self.view.endEditing(true)
            self.dropDown.hide()
        }
    }
    
    func callApiInBackground() {
        // Start a background task to perform your task
        self.backgroundTask = UIApplication.shared.beginBackgroundTask {
            // Clean up or finish the background task
            UIApplication.shared.endBackgroundTask(self.backgroundTask)
            self.backgroundTask = .invalid
        }
        
        // Schedule your task
        Timer.scheduledTimer(withTimeInterval: 3, repeats: true) { _ in
            // Perform your task here
            self.getUserList { _ in }
            // Check if the background time is low and end the task if necessary
            if UIApplication.shared.backgroundTimeRemaining < 10 {
                UIApplication.shared.endBackgroundTask(self.backgroundTask)
                self.backgroundTask = .invalid
            }
        }
    }
    
    func getSocketResponse() {
        self.socketHelper.on_new_video_call { data in
            let result = data.first as? [String: Any]
            let notification_data = result?["notification_data"] as? [String: Any]
            if AppInstance.instance.userId == (notification_data?["to_id"] as? String) ?? "" {
                self.getUserList { _ in }
            }
        }
    }
    
    func fetchGroupChatData() {
        let appDelegate = (UIApplication.shared.delegate) as? AppDelegate
        let context = appDelegate?.persistentContainer.viewContext
        let groupChats = GroupChat.getChats()
        if !groupChats.isEmpty {
            self.groupChats = groupChats
            for group in self.groupChats {
                if group.mute?.archive == "yes" {
                    if let index = self.groupChats.firstIndex(of: group) {
                        self.groupChats.remove(at: index)
                    }
                }
            }
            self.groupChats = self.groupChats.sorted(by: { group1, group2 in
                (group1.mute?.pin ?? "") > (group2.mute?.pin ?? "")
            })
            self.groupTableView.reloadData()
            if self.groupChats.count == 0 {
                self.groupEmptyView.isHidden = false
            } else {
                self.groupEmptyView.isHidden = true
            }
            self.getGroupChatDataList { [weak self] response in
                guard let self = self else { return }
                guard let list = response.data else {
                    self.groupTableView.reloadData()
                    return
                }
                for group in list {
                    if let groupChat = GroupChat.getGroupChatByGroupID(group.group_id ?? "") {
                        groupChat.updateGroupChat(group)
                    } else {
                        let localGroupChat = GroupChat(group: group)
                        localGroupChat.save()
                    }
                }
                for group in GroupChat.getChats() {
                    if !list.contains(where: { groupData in
                        groupData.chat_id == group.chat_id
                    }) {
                        context?.delete(group)
                        do {
                            try context?.save()
                        } catch {
                            print("failed so save data after deleting object")
                        }
                    }
                }
                self.groupChats = GroupChat.getChats()
                for group in self.groupChats {
                    if group.mute?.archive == "yes" {
                        if let index = self.groupChats.firstIndex(of: group) {
                            self.groupChats.remove(at: index)
                        }
                    }
                }
                self.groupChats = self.groupChats.sorted(by: { group1, group2 in
                    (group1.mute?.pin ?? "") > (group2.mute?.pin ?? "")
                })
                self.groupTableView.refreshControl?.endRefreshing()
                self.groupTableView.reloadData()
                if self.groupChats.count == 0 {
                    self.groupEmptyView.isHidden = false
                } else {
                    self.groupEmptyView.isHidden = true
                }
            }
        } else {
            self.groupChats = []
            self.getGroupChatDataList { model in
                Async.main {
                    self.dismissProgressDialog {
                        guard let data = model.data else {
                            self.groupTableView.reloadData()
                            return
                        }
                        for group in data {
                            if let groupChat = GroupChat.getGroupChatByGroupID(group.group_id ?? "") {
                                self.groupChats.append(groupChat)
                            } else {
                                let localGroupChat = GroupChat(group: group)
                                localGroupChat.save()
                                self.groupChats.append(localGroupChat)
                            }
                        }
                        for group in self.groupChats {
                            if group.mute?.archive == "yes" {
                                if let index = self.groupChats.firstIndex(of: group) {
                                    self.groupChats.remove(at: index)
                                }
                            }
                        }
                        self.groupChats = self.groupChats.sorted(by: { group1, group2 in
                            (group1.mute?.pin ?? "") > (group2.mute?.pin ?? "")
                        })
                        self.groupTableView.reloadData()
                        self.groupTableView.refreshControl?.endRefreshing()
                        if self.groupChats.count == 0 {
                            self.groupEmptyView.isHidden = false
                        } else {
                            self.groupEmptyView.isHidden = true
                        }
                    }
                }
            }
        }
    }
    
    func fetchChatsData() {
        let appDelegate = (UIApplication.shared.delegate) as? AppDelegate
        let context = appDelegate?.persistentContainer.viewContext
        let chats = Chats.getChats()
        if !chats.isEmpty {
            self.saveDataArray = chats
            for user in self.saveDataArray {
                if let object = user.getChatUsers().first?.user {
                    if object.user_mute?.archive == "yes" {
                        if let index = self.saveDataArray.firstIndex(of: user) {
                            self.saveDataArray.remove(at: index)
                        }
                    }
                }
            }
            self.saveDataArray = self.saveDataArray.sorted(by: { chat1, chat2 in
                (chat1.getFirstChatUser()?.user?.user_mute?.pin ?? "") > (chat2.getFirstChatUser()?.user?.user_mute?.pin ?? "")
            })
            self.chatsTableView.reloadData()
            if self.saveDataArray.count == 0 {
                self.chatsEmptyView.isHidden = false
            } else{
                self.chatsEmptyView.isHidden = true
            }
            self.getUserList { [weak self] (response) in
                guard let self = self else { return }
                guard let list = response.data else {
                    self.chatsTableView.reloadData()
                    return
                }
                for user in list {
                    if let chatUser = ChatUsers.getChatUserByUserID(user.user_id ?? "") {
                        chatUser.updateUser(user)
                    } else {
                        let localChat = Chats(user: user)
                        localChat.save()
                    }
                }
                for chat in Chats.getChats() {
                    if !list.contains(where: { userData in
                        userData.chat_id?.stringValue == chat.chat_id
                    }) {
                        context?.delete(chat)
                        do {
                            try context?.save()
                        } catch {
                            print("failed so save data after deleting object")
                        }
                    }
                }
                self.saveDataArray = Chats.getChats()
                for user in self.saveDataArray {
                    if let object = user.getChatUsers().first?.user {
                        if object.user_mute?.archive == "yes" {
                            if let index = self.saveDataArray.firstIndex(of: user) {
                                self.saveDataArray.remove(at: index)
                            }
                        }
                    }
                }
                self.saveDataArray = self.saveDataArray.sorted(by: { chat1, chat2 in
                    (chat1.getFirstChatUser()?.user?.user_mute?.pin ?? "") > (chat2.getFirstChatUser()?.user?.user_mute?.pin ?? "")
                })
                self.chatsTableView.refreshControl?.endRefreshing()
                self.chatsTableView.reloadData()
                if self.saveDataArray.count == 0 {
                    self.chatsEmptyView.isHidden = false
                } else{
                    self.chatsEmptyView.isHidden = true
                }
            }
        } else {
            self.saveDataArray = []
            self.getUserList { model in
                Async.main {
                    self.dismissProgressDialog {
                        guard let data = model.data else {
                            self.chatsTableView.reloadData()
                            return
                        }
                        for item in data {
                            if let chat = Chats.getChatByUserID(item.user_id ?? "") {
                                self.saveDataArray.append(chat)
                            } else {
                                let chat = Chats(user: item)
                                chat.save()
                                self.saveDataArray.append(chat)
                            }
                        }
                        for user in self.saveDataArray {
                            if let object = user.getChatUsers().first?.user {
                                if object.user_mute?.archive == "yes" {
                                    if let index = self.saveDataArray.firstIndex(of: user) {
                                        self.saveDataArray.remove(at: index)
                                    }
                                }
                            }
                        }
                        self.saveDataArray = self.saveDataArray.sorted(by: { chat1, chat2 in
                            (chat1.getFirstChatUser()?.user?.user_mute?.pin ?? "") > (chat2.getFirstChatUser()?.user?.user_mute?.pin ?? "")
                        })
                        self.chatsTableView.reloadData()
                        self.chatsTableView.refreshControl?.endRefreshing()
                        if self.saveDataArray.count == 0 {
                            self.chatsEmptyView.isHidden = false
                        } else{
                            self.chatsEmptyView.isHidden = true
                        }
                    }
                }
            }
        }
    }
    
    func getArchiveList(list: [UserData]) {
        self.archiveChats = []
        for item in list {
            if item.chat_type == "user" {
                if let chat = Chats.getChatByID(chat_id: item.chat_id?.stringValue ?? "") {
                    if let chatUser = chat.getChatUsers().first, chatUser.user?.user_id == item.user_id {
                        chatUser.updateUser(item)
                    }
                    self.archiveChats.append(chat)
                } else {
                    let chat = Chats(user: item)
                    chat.save()
                    self.archiveChats.append(chat)
                }
            }
        }
        self.archiveTableView.reloadData()
        if self.archiveChats.count == 0 {
            self.archiveEmptyView.isHidden = false
            self.archiveTableView.isHidden = true
        } else {
            self.archiveEmptyView.isHidden = true
            self.archiveTableView.isHidden = false
        }
    }
    
    // MARK: GetUserList
    func getUserList(_ completion: @escaping (UserModelResponse) -> Void) {
        let userID = AppInstance.instance._userId
        if fetchSatus! {
            fetchSatus = false
        }
        Async.background {
            self.requestsGroup.enter()
            GetUserListManager.instance.getUserList(user_id: userID, session_Token: AppInstance.instance._sessionId) { (success, sessionError, serverError, error) in
                if success != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            if let success = success {
                                completion(success)
                                if let navVC = (appDelegate.window?.rootViewController as? UINavigationController) {
                                    if success.agora_call == true {
                                        if success.audio_call == true {
                                            if let newVC = R.storyboard.call.incomingCallVC() {
                                                newVC.callProvider = .agora
                                                newVC.callType = .audio
                                                newVC.callData = success.audio_call_user?.userCallValue
                                                if !navVC.viewControllers.contains(where: { $0 is IncomingCallVC }) {
                                                    navVC.pushViewController(newVC, animated: true)
                                                } else {
                                                    print("Already Presented")
                                                }
                                            }
                                            self.notificationBuilder.setContent(callType: "audio", callProvider: "agora", data: success.audio_call_user?.userCallValue).build(notificationIdentifier: success.audio_call_user?.userCallValue?.data?.id ?? "")
                                        }
                                        if success.video_call == true {
                                            if let newVC = R.storyboard.call.incomingCallVC() {
                                                newVC.callProvider = .agora
                                                newVC.callType = .video
                                                newVC.callData = success.video_call_user?.userCallValue
                                                if !navVC.viewControllers.contains(where: { $0 is IncomingCallVC }) {
                                                    navVC.pushViewController(newVC, animated: true)
                                                } else {
                                                    print("Already Presented")
                                                }
                                            }
                                            self.notificationBuilder.setContent(callType: "video", callProvider: "agora", data: success.video_call_user?.userCallValue).build(notificationIdentifier: success.video_call_user?.userCallValue?.data?.id ?? "")
                                        }
                                    } else {
                                        if success.audio_call == true {
                                            if let newVC = R.storyboard.call.incomingCallVC() {
                                                newVC.callProvider = .twilio
                                                newVC.callType = .audio
                                                newVC.callData = success.audio_call_user?.userCallValue
                                                if !navVC.viewControllers.contains(where: { $0 is IncomingCallVC }) {
                                                    navVC.pushViewController(newVC, animated: true)
                                                } else {
                                                    print("Already Presented")
                                                }
                                            }
                                            self.notificationBuilder.setContent(callType: "audio", callProvider: "twilio", data: success.audio_call_user?.userCallValue).build(notificationIdentifier: success.audio_call_user?.userCallValue?.data?.id ?? "")
                                        }
                                        if success.video_call == true {
                                            if let newVC = R.storyboard.call.incomingCallVC() {
                                                newVC.callProvider = .twilio
                                                newVC.callType = .video
                                                newVC.callData = success.video_call_user?.userCallValue
                                                if !navVC.viewControllers.contains(where: { $0 is IncomingCallVC }) {
                                                    navVC.pushViewController(newVC, animated: true)
                                                } else {
                                                    print("Already Presented")
                                                }
                                            }
                                            self.notificationBuilder.setContent(callType: "video", callProvider: "twilio", data: success.video_call_user?.userCallValue).build(notificationIdentifier: success.video_call_user?.userCallValue?.data?.id ?? "")
                                        }
                                    }
                                }
                                self.requestsGroup.leave()
                            }
                        }
                    }
                } else if sessionError != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            self.view.makeToast(sessionError?.errors?.error_text)
                            self.requestsGroup.leave()
                        }
                    }
                } else if serverError != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            self.view.makeToast(serverError?.errors?.error_text)
                            self.requestsGroup.leave()
                        }
                    }
                } else {
                    Async.main {
                        self.dismissProgressDialog {
                            self.view.makeToast(error?.localizedDescription)
                            self.requestsGroup.leave()
                        }
                    }
                }
            }
        }
    }
    
    func getArchivedChats() {
        if Connectivity.isConnectedToNetwork() {
            Async.background {
                ArchivedManager.instance.getArchivedChats(session_Token: AppInstance.instance._sessionId) { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                self.getArchiveList(list: success?.data ?? [])
                            }
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                self.view.makeToast(sessionError?.errors?.error_text)
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                self.view.makeToast(serverError?.errors?.error_text)
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                self.view.makeToast(error?.localizedDescription)
                            }
                        }
                    }
                }
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
}

//MARK: - UITableViewDelegate & DataSource Method's
extension ChatUserListVC: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        switch tableView {
        case self.chatsTableView:
            return saveDataArray.count
        case self.groupTableView:
            return self.groupChats.count
        case self.archiveTableView:
            return self.archiveChats.count
        default:
            return 0
        }
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        switch tableView {
        case self.chatsTableView:
            let cell = chatsTableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.userListChatCell.identifier) as! UserListChatCell
            if self.saveDataArray.count != 0 {
                self.setChatUserListData(cell: cell, indexPath: indexPath)
            }
            return cell
        case self.groupTableView:
            let cell = groupTableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.userListChatCell.identifier) as! UserListChatCell
            if self.groupChats.count != 0 {
                self.setGroupChatData(cell: cell, indexPath: indexPath)
            }
            return cell
        case self.archiveTableView:
            let cell = archiveTableView.dequeueReusableCell(withIdentifier: R.reuseIdentifier.userListChatCell.identifier) as! UserListChatCell
            if self.archiveChats.count != 0 {
                self.archiveDataset(cell: cell, indexPath: indexPath)
            }
            return cell
        default:
            return UITableViewCell()
        }
    }
    
    func chatIsAllowed(user_data: Users?) -> Bool {
        if (user_data?.message_privacy == "2") {
            return false
        } else if (user_data?.message_privacy == "1") {
            if (user_data?.is_following == "1") {
                return true
            } else {
                return false
            }
        } else if (user_data?.message_privacy == "0") {
            return true
        }
        return true
    }
    
    func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        
        switch tableView {
        case self.chatsTableView:
            let model = self.saveDataArray[indexPath.row]
            guard let object = model.getChatUsers().first else { return }
            if !self.chatIsAllowed(user_data: object.user) {
                self.view.makeToast("Sorry, chatting with this user is not allowed at this time")
                return
            }
            AppInstance.instance.addCount = AppInstance.instance.addCount! + 1
            let newVC = R.storyboard.chat.chatViewController()
            newVC?.recipientID = object.user_id ?? ""
            newVC?.chatModel = model
            self.navigationController?.pushViewController(newVC!, animated: true)
        case self.groupTableView:
            self.groupTableView.deselectRow(at: indexPath, animated: true)
            let objectGroups = self.groupChats[indexPath.row]
            let groupcahatVC = ChatGroupViewController.initialize(from: .group)
            groupcahatVC.groupData = objectGroups
            self.navigationController?.pushViewController(groupcahatVC, animated: true)
        case self.archiveTableView:
            let model = self.archiveChats[indexPath.row]
            guard let object = model.getChatUsers().first else { return }
            if !self.chatIsAllowed(user_data: object.user) {
                self.view.makeToast("Sorry, chatting with this user is not allowed at this time")
                return
            }
            AppInstance.instance.addCount = AppInstance.instance.addCount! + 1
            let newVC = R.storyboard.chat.chatViewController()
            newVC?.recipientID = object.user_id ?? ""
            newVC?.chatModel = model
            self.navigationController?.pushViewController(newVC!, animated: true)
        default:
            break
        }
    }
    
    // UserListChatDatSave
    func setChatUserListData(cell: UserListChatCell, indexPath: IndexPath) {
        if saveDataArray.isEmpty {
            cell.showAnimation()
        }
        cell.hideAnimation()
        let objarray = saveDataArray[indexPath.row]
        guard let object = objarray.getChatUsers().first?.user else { return }
        let url = URL(string: object.avatar_url ?? "")
        let indicator = SDWebImageActivityIndicator.medium
        cell.userImageView.sd_imageIndicator = indicator
        DispatchQueue.global(qos: .userInteractive).async {
            cell.userImageView.sd_setImage(with: url, placeholderImage: UIImage(named: "ic_No_images"))
        }
        cell.timeLabel.text = object.chat_time?.getLastSeenString(replace: true)
        cell.countView.isHidden = false
        cell.onlineImageView.isHidden = false
        cell.countLabel.text = object.message_count
        cell.userNameLabel.text = objarray._name
        let user = objarray.getFirstChatUser()?.user
        let lastMessageType = user?.last_message?.type ?? ""
        let lastMessageText = user?.last_message?._text ?? ""
        let lastMessageTime = user?.last_message?._time ?? ""
        cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaRegularOtf.name, size: cell.lastMessageLabel.font.pointSize)
        cell.lastSeenImage.isHidden = true
        if object.message_count == "0" {
            cell.countLabel.isHidden = true
            cell.countView.isHidden = true
        } else if object.message_count == "1" {
            cell.countLabel.isHidden = false
            cell.countView.isHidden = false
            cell.countView.backgroundColor = UIColor(hex: "C83747")
            cell.countLabel.text = object.message_count ?? ""
            cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaBoldOtf.name, size: cell.lastMessageLabel.font.pointSize)
        } else {
            cell.countLabel.isHidden = false
            cell.countView.isHidden = false
            cell.countView.backgroundColor = UIColor(hex: "C83747")
            cell.lastMessageLabel.font = cell.lastMessageLabel.font.bold
            cell.countLabel.text = object.message_count ?? ""
            cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaBoldOtf.name, size: cell.lastMessageLabel.font.pointSize)
        }
        cell.lastMessageIcon.isHidden = false
        switch lastMessageType {
        case "left_text":
            let lat = Double(user?.last_message?.lat ?? "0.0") ?? 0.0
            let long = Double(user?.last_message?.lng ?? "0.0") ?? 0.0
            if lat > 0.0 || long > 0.0 {
                cell.lastMessageLabel.text = "Location"
                cell.lastMessageIcon.image = R.image.icon_search_location_vector()
            } else {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            }
        case "right_text":
            let lat = Double(user?.last_message?.lat ?? "0.0") ?? 0.0
            let long = Double(user?.last_message?.lng ?? "0.0") ?? 0.0
            if lat > 0.0 || long > 0.0 {
                cell.lastMessageLabel.text = "Location"
                cell.lastMessageIcon.image = R.image.icon_search_location_vector()
            } else {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            }
        case "right_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "right_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "right_gif":
            cell.lastMessageLabel.text = "Gif"
            cell.lastMessageIcon.image = R.image.icon_gif_vector()
        case "left_gif":
            cell.lastMessageLabel.text = "Gif"
            cell.lastMessageIcon.image = R.image.icon_gif_vector()
        case "left_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "right_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "left_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "right_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "left_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image =  R.image.icon_radios_vector()
        case "right_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image = R.image.icon_radios_vector()
        case "left_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        case "right_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        default:
            break
        }
        if object.last_seen_status == "off" {
            cell.onlineImageView.isHidden = true
            cell.statusView.isHidden = true
        } else {
            if object.show_last_seen == "1" {
                cell.onlineImageView.isHidden = false
                cell.onlineImageView.tintColor = UIColor.green
                cell.statusView.isHidden = false
            } else{
                cell.onlineImageView.isHidden = false
                cell.onlineImageView.tintColor = UIColor.gray
                cell.statusView.isHidden = false
            }
        }
        if object.user_mute?.pin == "yes" {
            cell.pinMessage.isHidden = false
        } else {
            cell.pinMessage.isHidden = true
        }
        if object.user_mute?.notify == "no" {
            cell.muteImageView.isHidden = false
        } else {
            cell.muteImageView.isHidden = true
        }
    }
    
    // Set Group Chat Data
    func setGroupChatData(cell: UserListChatCell, indexPath: IndexPath) {
        var type = ""
        var lastMessageText = ""
        var lastMessageTime = ""
        cell.hideAnimation()
        let objectGroups = self.groupChats[indexPath.row]
        let url = URL(string: objectGroups.avatar ?? "")
        let indicator = SDWebImageActivityIndicator.medium
        cell.userImageView.sd_imageIndicator = indicator
        DispatchQueue.global(qos: .userInteractive).async {
            cell.userImageView.sd_setImage(with: url, placeholderImage: UIImage(named: ""))
        }
        cell.timeLabel.text = objectGroups.chat_time?.getLastSeenString(replace: true)
        cell.onlineImageView.isHidden = true
        cell.userNameLabel.text = objectGroups.group_name
        cell.statusView.isHidden = true
        lastMessageText = objectGroups.last_message?.text ?? ""
        lastMessageTime = objectGroups.last_message?.time ?? ""
        type = objectGroups.last_message?.type ?? ""
        cell.lastMessageIcon.isHidden = false
        switch type {
        case "left_text":
            if objectGroups.last_message?.stickers == nil || objectGroups.last_message?.stickers == "" {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            } else {
                cell.lastMessageLabel.text = "Gif"
                cell.lastMessageIcon.image = R.image.icon_gif_vector()
            }
        case "right_text":
            if objectGroups.last_message?.stickers == nil || objectGroups.last_message?.stickers == "" {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            } else {
                cell.lastMessageLabel.text = "Gif"
                cell.lastMessageIcon.image = R.image.icon_gif_vector()
            }
        case "left_map":
            cell.lastMessageLabel.text = "Location"
            cell.lastMessageIcon.image = R.image.icon_search_location_vector()
        case "right_map":
            cell.lastMessageLabel.text = "Location"
            cell.lastMessageIcon.image = R.image.icon_search_location_vector()
        case "right_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "right_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "left_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "right_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "left_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "right_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "left_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image =  R.image.icon_radios_vector()
        case "right_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image = R.image.icon_radios_vector()
        case "left_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        case "right_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        default:
            break
        }
        if objectGroups.mute?.pin == "yes" {
            cell.pinMessage.isHidden = false
        } else {
            cell.pinMessage.isHidden = true
        }
        if objectGroups.mute?.notify == "no" {
            cell.muteImageView.isHidden = false
        } else {
            cell.muteImageView.isHidden = true
        }
    }
    
    func archiveDataset(cell: UserListChatCell, indexPath: IndexPath) {
        if archiveChats.isEmpty {
            cell.showAnimation()
        }
        cell.hideAnimation()
        let objarray = self.archiveChats[indexPath.row]
        guard let object = objarray.getChatUsers().first?.user else { return }
        let url = URL(string: object.avatar_url ?? "")
        let indicator = SDWebImageActivityIndicator.medium
        cell.userImageView.sd_imageIndicator = indicator
        DispatchQueue.global(qos: .userInteractive).async {
            cell.userImageView.sd_setImage(with: url, placeholderImage: UIImage(named: ""))
        }
        cell.timeLabel.text = object.chat_time?.getLastSeenString(replace: true)
        cell.countView.isHidden = false
        cell.onlineImageView.isHidden = false
        cell.countLabel.text = object.message_count
        cell.userNameLabel.text = objarray._name
        let user = objarray.getFirstChatUser()?.user
        let lastMessageType = user?.last_message?.type ?? ""
        let lastMessageText = user?.last_message?._text ?? ""
        let lastMessageTime = user?.last_message?._time ?? ""
        cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaRegularOtf.name, size: cell.lastMessageLabel.font.pointSize)
        cell.lastSeenImage.isHidden = true
        if object.message_count == "0" {
            cell.countLabel.isHidden = true
            cell.countView.isHidden = true
        } else if object.message_count == "1" {
            cell.countLabel.isHidden = false
            cell.countView.isHidden = false
            cell.countView.backgroundColor = UIColor(hex: "C83747")
            cell.countLabel.text = object.message_count ?? ""
            cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaBoldOtf.name, size: cell.lastMessageLabel.font.pointSize)
        } else {
            cell.countLabel.isHidden = false
            cell.countView.isHidden = false
            cell.countView.backgroundColor = UIColor(hex: "C83747")
            cell.lastMessageLabel.font = cell.lastMessageLabel.font.bold
            cell.countLabel.text = object.message_count ?? ""
            cell.lastMessageLabel.font = UIFont(name: R.file.brSonomaBoldOtf.name, size: cell.lastMessageLabel.font.pointSize)
        }
        cell.lastMessageIcon.isHidden = false
        switch lastMessageType {
        case "left_text":
            let lat = Double(user?.last_message?.lat ?? "0.0") ?? 0.0
            let long = Double(user?.last_message?.lng ?? "0.0") ?? 0.0
            if lat > 0.0 || long > 0.0 {
                cell.lastMessageLabel.text = "Location"
                cell.lastMessageIcon.image = R.image.icon_search_location_vector()
            } else {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            }
        case "right_text":
            let lat = Double(user?.last_message?.lat ?? "0.0") ?? 0.0
            let long = Double(user?.last_message?.lng ?? "0.0") ?? 0.0
            if lat > 0.0 || long > 0.0 {
                cell.lastMessageLabel.text = "Location"
                cell.lastMessageIcon.image = R.image.icon_search_location_vector()
            } else {
                let messageString = self.decryptionAESModeECB(messageData: lastMessageText, key: lastMessageTime) ?? ""
                cell.lastMessageLabel.text = messageString
                cell.lastMessageIcon.isHidden = true
            }
        case "right_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_image":
            cell.lastMessageLabel.text = "Image"
            cell.lastMessageIcon.image = R.image.icon_image_vector()
        case "left_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "right_video":
            cell.lastMessageLabel.text = "Video"
            cell.lastMessageIcon.image = R.image.icon_video_player_vector()
        case "right_gif":
            cell.lastMessageLabel.text = "Gif"
            cell.lastMessageIcon.image = R.image.icon_gif_vector()
        case "left_gif":
            cell.lastMessageLabel.text = "Gif"
            cell.lastMessageIcon.image = R.image.icon_gif_vector()
        case "left_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "right_contact":
            cell.lastMessageLabel.text = "Contact Number"
            cell.lastMessageIcon.isHidden = true
        case "left_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "right_file":
            cell.lastMessageLabel.text = "File"
            cell.lastMessageIcon.image = R.image.icon_document_vector()
        case "left_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image =  R.image.icon_radios_vector()
        case "right_audio":
            cell.lastMessageLabel.text = "Audio"
            cell.lastMessageIcon.image = R.image.icon_radios_vector()
        case "left_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        case "right_sticker":
            cell.lastMessageLabel.text = "Sticker"
            cell.lastMessageIcon.image = R.image.icon_sticker_vector()
        default:
            break
        }
        if object.last_seen_status == "off" {
            cell.onlineImageView.isHidden = true
            cell.statusView.isHidden = true
        } else {
            if object.show_last_seen == "1" {
                cell.onlineImageView.isHidden = false
                cell.onlineImageView.tintColor = UIColor.green
                cell.statusView.isHidden = false
            } else{
                cell.onlineImageView.isHidden = false
                cell.onlineImageView.tintColor = UIColor.gray
                cell.statusView.isHidden = false
            }
        }
        if object.user_mute?.pin == "yes" {
            cell.pinMessage.isHidden = false
        } else {
            cell.pinMessage.isHidden = true
        }
        if object.user_mute?.notify == "no" {
            cell.muteImageView.isHidden = false
        } else {
            cell.muteImageView.isHidden = true
        }
    }
    
}
