import UIKit
import SDWebImage
import CoreData
import Async
import WowonderMessengerSDK
import Toast_Swift

class UpdateGroupVC: BaseVC  {
    
    // MARK: - IBOutlets
    
    @IBOutlet weak var groupImage: UIImageView!
    @IBOutlet weak var cameraImage: UIImageView!
    @IBOutlet weak var groupNameTextField: EmojiTextField!
    @IBOutlet weak var groupNameBorderView: UIView!
    @IBOutlet weak var keyboardTypeButton: UIButton!
    @IBOutlet weak var viewTableView: UIView!
    @IBOutlet weak var tableView: UITableView!
    @IBOutlet weak var tableViewHeightConstraint: NSLayoutConstraint!
    @IBOutlet weak var saveButton: UIButton!
    @IBOutlet weak var exitGroupButton: UIButton!
    @IBOutlet weak var deleteGroupButton: UIButton!
    
    // MARK: - Properties
    
    private var selectedUsersArray: [UserData] = []
    private var idsString = ""
    private let imagePickerController = UIImagePickerController()
    private var imageData: Data? = nil
    var groupData: GroupData?
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        self.initialConfig()
    }
    
    override func viewWillAppear(_ animated: Bool) {
        if self.selectedUsersArray.count == 0 {
            self.viewTableView.isHidden = true
        } else {
            self.viewTableView.isHidden = false
            self.tableViewHeightConstraint.constant = CGFloat(68 * self.selectedUsersArray.count)
        }
    }
    
    // MARK: - Selectors
    
    // Back Button Action
    @IBAction func backButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.navigationController?.popViewController(animated: true)
    }
    
    // Keyboard Type Button Action
    @IBAction func keyboardTypeButtonAction(_ sender: UIButton) {
        self.groupNameTextField.isEmojiKeyboard = !(self.groupNameTextField.isEmojiKeyboard)
        self.groupNameTextField.becomeFirstResponder()
        self.groupNameTextField.reloadInputViews()
        self.keyboardTypeButton.setImage(self.groupNameTextField.isEmojiKeyboard ? R.image.icon_keyboard_vector() : R.image.icon_emoji_vector(), for: .normal)
    }
    
    // Add Image Button Action
    @IBAction func addImageButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        let alert = UIAlertController(title: "Select Source", message: "", preferredStyle: .alert)
        let camera = UIAlertAction(title: "Camera", style: .default) { action in
            if !UIImagePickerController.isSourceTypeAvailable(.camera) {
                self.view.makeToast("camera not found...")
                return
            }
            self.imagePickerController.sourceType = .camera
            self.present(self.imagePickerController, animated: true, completion: nil)
        }
        let gallery = UIAlertAction(title: "Gallery", style: .default) { (action) in
            self.imagePickerController.sourceType = .photoLibrary
            self.present(self.imagePickerController, animated: true, completion: nil)
        }
        let cancel = UIAlertAction(title: "Cancel", style: .destructive, handler: nil)
        alert.addAction(camera)
        alert.addAction(gallery)
        alert.addAction(cancel)
        self.present(alert, animated: true, completion: nil)
    }
    
    // Add Participants Button Action
    @IBAction func addParticipantsButtonAction(_ sender: UIButton) {
        if let newVC = R.storyboard.group.addParticipantsListViewController() {
            newVC.delegate = self
            newVC.selectedUserArray = self.selectedUsersArray
            self.navigationController?.pushViewController(newVC, animated: true)
        }
    }
    
    // Save Button Action
    @IBAction func saveButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        self.saveNewUserAdd()
    }
    
    // Exit Group Button Action
    @IBAction func exitGroupButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        if let alertVC = R.storyboard.group.groupAlertVC() {
            alertVC.delegate = self
            alertVC.messageText = "Are you sure to exit the group"
            alertVC.okText = "EXIT"
            self.present(alertVC, animated: true, completion: nil)
            alertVC.okButton.tag = 2002
        }
    }
    
    // Delete Group Button Action
    @IBAction func deleteGroupButtonAction(_ sender: UIButton) {
        self.view.endEditing(true)
        if let alertVC = R.storyboard.group.groupAlertVC() {
            alertVC.delegate = self
            alertVC.messageText = "Are you sure you want to delete the group"
            alertVC.okText = "DELETE GROUP"
            self.present(alertVC, animated: true, completion: nil)
            alertVC.okButton.tag = 3003
        }
    }
    
    // MARK: - Helper Functions
    
    // Initial Config
    func initialConfig() {
        self.imagePickerController.delegate = self
        self.imagePickerController.allowsEditing = false
        self.tableViewSetup()
        self.textFieldSetup()
        self.setData()
    }
    
    // TableView Setup
    func tableViewSetup() {
        self.tableView.delegate = self
        self.tableView.dataSource = self
        self.tableView.register(UINib(resource: R.nib.groupAddParticipantsCell), forCellReuseIdentifier: R.reuseIdentifier.groupAddParticipantsCell.identifier)
    }
    
    // TextField Setup
    func textFieldSetup() {
        self.groupNameTextField.attributedPlaceholder = NSAttributedString(
            string: "Enter group name",
            attributes: [NSAttributedString.Key.foregroundColor: UIColor.text_color_in_between as Any]
        )
        self.groupNameTextField.delegate = self
    }
    
    private func setData() {
        self.groupNameTextField.text = self.groupData?.group_name ?? ""
        let url = URL(string: self.groupData?.avatar ?? "")
        let indicator = SDWebImageActivityIndicator.medium
        self.groupImage.sd_imageIndicator = indicator
        DispatchQueue.global(qos: .userInteractive).async {
            self.groupImage.sd_setImage(with: url, placeholderImage: UIImage(named: ""))
        }
        if groupImage.image != nil {
            self.imageData = self.groupImage.image?.jpegData(compressionQuality: 1)
            self.cameraImage.isHidden = true
        }
        self.selectedUsersArray = self.groupData?.parts ?? []
        self.tableView.reloadData()
        if self.selectedUsersArray.count == 0 {
            self.viewTableView.isHidden = true
        } else {
            self.tableViewHeightConstraint.constant = CGFloat(68 * self.selectedUsersArray.count)
        }
    }
    
    func saveNewUserAdd() {
        self.idsString = self.selectedUsersArray.map { userData in
            return userData.user_id ?? ""
        }.joined(separator: ", ")
        print("idsString >>>>>", self.idsString)
        if self.imageData == nil {
            self.view.makeToast("Please select group avatar")
            return
        }
        if self.groupNameTextField.text?.trimmingCharacters(in: .whitespaces).count == 0 {
            self.view.makeToast("Please enter group name")
            return
        }
        if self.selectedUsersArray.count == 0 {
            self.view.makeToast("Please select at least one user")
            return
        }
        self.addParticipants()
    }
    
}

// MARK: - Extensions

// MARK: Api Call
extension UpdateGroupVC {
    
    // Exit Group
    private func exitGroup() {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            let groupId = self.groupData?.group_id ?? ""
            Async.background {
                GroupChatManager.instance.leaveGroup(group_Id: groupId , session_Token: sessionToken, type: "leave", completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("success = \(success?.api_status ?? 0)")
                                self.navigationController?.popViewController(animated: true)
                                appDelegate.window?.rootViewController?.view.makeToast(success?.message_data)
                            }
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("sessionError = \(sessionError?.errors?.error_text ?? "")")
                                self.view.makeToast(sessionError?.errors?.error_text ?? "")
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("serverError = \(serverError?.errors?.error_text ?? "")")
                                self.view.makeToast(serverError?.errors?.error_text ?? "")
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                print("error = \(error?.localizedDescription ?? "")")
                                self.view.makeToast(error?.localizedDescription ?? "")
                            }
                        }
                    }
                })
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
    // Delete Group
    private func deleteGroup() {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            let groupId = self.groupData?.group_id ?? ""
            Async.background {
                GroupChatManager.instance.deleteGroup(group_Id: groupId, session_Token: sessionToken, type: "delete", completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("success = \(success?.api_status ?? 0)")
                                guard let chat_id = self.groupData?.chat_id else { return }
                                let appDelegate = (UIApplication.shared.delegate) as? AppDelegate
                                let context = appDelegate?.persistentContainer.viewContext
                                let predicate = NSPredicate(format: "%K == %@", #keyPath(Messages.chat_id), chat_id)
                                let fetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "Messages")
                                fetchRequest.predicate = predicate
                                let deleteRequest = NSBatchDeleteRequest(fetchRequest: fetchRequest)
                                do {
                                    try context?.execute(deleteRequest)
                                    try context?.save()
                                } catch {
                                    print("error >>>>> ", error.localizedDescription)
                                }
                                let userPredicate = NSPredicate(format: "%K == %@", #keyPath(GroupChat.chat_id), chat_id)
                                let userFetchRequest = NSFetchRequest<NSFetchRequestResult>(entityName: "GroupChat")
                                userFetchRequest.predicate = userPredicate
                                let userDeleteRequest = NSBatchDeleteRequest(fetchRequest: userFetchRequest)
                                do {
                                    try context?.execute(userDeleteRequest)
                                    try context?.save()
                                } catch {
                                    print("error >>>>> ", error.localizedDescription)
                                }
                                self.navigationController?.popViewController(animated: true)
                                appDelegate?.window?.rootViewController?.view.makeToast(success?.message_data)
                            }
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("sessionError = \(sessionError?.errors?.error_text ?? "")")
                                self.view.makeToast(sessionError?.errors?.error_text ?? "")
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("serverError = \(serverError?.errors?.error_text ?? "")")
                                self.view.makeToast(serverError?.errors?.error_text ?? "")
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                print("error = \(error?.localizedDescription ?? "")")
                                self.view.makeToast(error?.localizedDescription ?? "")
                            }
                        }
                    }
                })
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
    // Update Group
    private func updateGroup() {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            let groupName  = self.groupNameTextField.text ?? ""
            let imageData = self.imageData ?? Data()
            let groupId = self.groupData?.group_id ?? ""
            Async.background {
                GroupChatManager.instance.updateGroup(session_Token: sessionToken, groupName: groupName, groupId: groupId, type: "edit", avatar_data: imageData, completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("success = \(success?.apiStatus ?? 0)")
                                self.navigationController?.popViewController(animated: true)
                            }
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("sessionError = \(sessionError?.errors?.error_text ?? "")")
                                self.view.makeToast(sessionError?.errors?.error_text ?? "")
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("serverError = \(serverError?.errors?.error_text ?? "")")
                                self.view.makeToast(serverError?.errors?.error_text ?? "")
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                print("error = \(error?.localizedDescription ?? "")")
                                self.view.makeToast(error?.localizedDescription ?? "")
                            }
                        }
                    }
                })
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
    // Add Participants
    private func addParticipants() {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            let part = self.idsString
            let groupId = self.groupData?.group_id ?? ""
            Async.background {
                GroupChatManager.instance.addParticipants(group_Id: groupId, session_Token: sessionToken, type: "add_user", part: part, completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            print("success = \(success?.api_status ?? 0)")
                            self.updateGroup()
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("sessionError = \(sessionError?.errors?.error_text ?? "")")
                                self.view.makeToast(sessionError?.errors?.error_text ?? "")
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("serverError = \(serverError?.errors?.error_text ?? "")")
                                self.view.makeToast(serverError?.errors?.error_text ?? "")
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                print("error = \(error?.localizedDescription ?? "")")
                                self.view.makeToast(error?.localizedDescription ?? "")
                            }
                        }
                    }
                })
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
    // remove Participants
    private func removeParticipants(part: String, index: Int) {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            let groupId = self.groupData?.group_id ?? ""
            Async.background {
                GroupChatManager.instance.removeParticipants(group_Id: groupId, session_Token: sessionToken, part: part, completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            print("success = \(success?.api_status ?? 0)")
                            self.selectedUsersArray.remove(at: index)
                            self.tableView.reloadData()
                            if self.selectedUsersArray.count == 0 {
                                self.viewTableView.isHidden = true
                            } else {
                                self.tableViewHeightConstraint.constant = CGFloat(68 * self.selectedUsersArray.count)
                            }
                        }
                    } else if sessionError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("sessionError = \(sessionError?.errors?.error_text ?? "")")
                                self.view.makeToast(sessionError?.errors?.error_text ?? "")
                            }
                        }
                    } else if serverError != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("serverError = \(serverError?.errors?.error_text ?? "")")
                                self.view.makeToast(serverError?.errors?.error_text ?? "")
                            }
                        }
                    } else {
                        Async.main {
                            self.dismissProgressDialog {
                                print("error = \(error?.localizedDescription ?? "")")
                                self.view.makeToast(error?.localizedDescription ?? "")
                            }
                        }
                    }
                })
            }
        } else {
            self.dismissProgressDialog {
                self.view.makeToast(InterNetError)
            }
        }
    }
    
}

// MARK: TableView Setup
extension UpdateGroupVC: UITableViewDelegate, UITableViewDataSource {
    
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return selectedUsersArray.count
    }
    
    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let cell = self.tableView.dequeueReusableCell(withIdentifier: "GroupAddParticipantsCell", for: indexPath) as! GroupAddParticipantsCell
        let userData = self.selectedUsersArray[indexPath.row]
        cell.delegate = self
        cell.indexPath = indexPath
        cell.cancelButton.isHidden = self.groupData?.user_id == userData.user_id
        cell.setData(object: userData)
        return cell
    }
    
}

//MARK: AddParticipantsListViewControllerDelegate Methods
extension UpdateGroupVC: AddParticipantsListViewControllerDelegate {
    
    func sendSelectedParticipants(selectedParticipants: [UserData]) {
        self.selectedUsersArray = selectedParticipants
        self.tableView.reloadData()
        if self.selectedUsersArray.count == 0 {
            self.viewTableView.isHidden = true
        } else {
            self.tableViewHeightConstraint.constant = CGFloat(68 * self.selectedUsersArray.count)
        }
    }
    
}

// MARK: UIImagePickerControllerDelegate Methods
extension UpdateGroupVC: UIImagePickerControllerDelegate, UINavigationControllerDelegate {
    
    func imagePickerController(_ picker: UIImagePickerController, didFinishPickingMediaWithInfo info: [UIImagePickerController.InfoKey : Any]) {
        let image = info[UIImagePickerController.InfoKey.originalImage] as! UIImage
        self.groupImage.image = image
        self.cameraImage.isHidden = true
        self.imageData = image.jpegData(compressionQuality: 1)
        self.dismiss(animated: true, completion: nil)
    }
    
}

// MARK: deleteParticipantDelegate Methods
extension UpdateGroupVC: GroupAddParticipantsCellDelegate {
    
    func handleDeleteParticipant(indexPath: IndexPath) {
        if let alertVC = R.storyboard.group.groupAlertVC() {
            alertVC.delegate = self
            alertVC.messageText = "Remove " + (self.selectedUsersArray[indexPath.row].name ?? "")
            alertVC.okText = "YES"
            alertVC.cancelText = "NO"
            self.present(alertVC, animated: true, completion: nil)
            alertVC.okButton.tag = indexPath.row
        }
    }
    
}

// MARK: GroupAlertVCDelegate Methods
extension UpdateGroupVC: GroupAlertVCDelegate {
    
    func groupAlertOKButtonPressed(_ sender: UIButton) {
        if sender.tag == 2002 {
            self.exitGroup()
        } else if sender.tag == 3003 {
            self.deleteGroup()
        } else {
            self.removeParticipants(part: self.selectedUsersArray[sender.tag].user_id ?? "", index: sender.tag)
        }
    }
    
}

// MARK: UITextFieldDelegate Methods
extension UpdateGroupVC: UITextFieldDelegate {
    
    func textFieldDidBeginEditing(_ textField: UITextField) {
        switch textField {
        case self.groupNameTextField:
            self.groupNameBorderView.backgroundColor = .accent
        default:
            break
        }
    }
    
    func textFieldDidEndEditing(_ textField: UITextField) {
        switch textField {
        case self.groupNameTextField:
            self.groupNameBorderView.backgroundColor = UIColor(hex: "DDDDDD")
            self.groupNameTextField.isEmojiKeyboard = false
            self.keyboardTypeButton.setImage(self.groupNameTextField.isEmojiKeyboard ? R.image.icon_keyboard_vector() : R.image.icon_emoji_vector(), for: .normal)
        default:
            break
        }
    }
    
}
