//
//  GroupListBottomViewController.swift
//  WoWonder
//
//  Created by UnikApp on 09/12/22.
//  Copyright © 2022 ScriptSun. All rights reserved.
//

import UIKit
import Async
import WowonderMessengerSDK
import Toast_Swift
import CoreData

protocol GroupListOptionDelegate {
    func handleGroupListOptionTap(index: Int, optionName: String, indexPath: IndexPath)
}

class GroupListBottomViewController: UIViewController {
    
    // MARK: - IBOutlets
    
    @IBOutlet weak var archiveIcon: UIImageView!
    @IBOutlet weak var archiveLabel: UILabel!
    @IBOutlet weak var archiveView: UIControl!
    @IBOutlet weak var deleteIcon: UIImageView!
    @IBOutlet weak var deleteView: UIControl!
    @IBOutlet weak var pinIcon: UIImageView!
    @IBOutlet weak var pinLabel: UILabel!
    @IBOutlet weak var pinView: UIControl!
    @IBOutlet weak var muteNotificationIcon: UIImageView!
    @IBOutlet weak var muteNotificationLabel: UILabel!
    @IBOutlet weak var muteNotificationView: UIControl!
    @IBOutlet weak var markAsReadIcon: UIImageView!
    @IBOutlet weak var markAsReadView: UIControl!
    @IBOutlet weak var groupInfoIcon: UIImageView!
    @IBOutlet weak var groupInfoView: UIControl!
    @IBOutlet weak var exitGroupIcon: UIImageView!
    @IBOutlet weak var exitGroupView: UIControl!
    @IBOutlet weak var addMembersIcon: UIImageView!
    @IBOutlet weak var addMembersView: UIControl!
    
    // MARK: - Properties
    
    var sheetHeight: CGFloat = 0
    var sheetBackgroundColor: UIColor = .color_fill
    var sheetCornerRadius: CGFloat = 20
    private var hasSetOriginPoint = false
    private var originPoint: CGPoint?
    var delegate: GroupListOptionDelegate?
    var indexPath = IndexPath()
    var groupData: GroupChat?
    
    // MARK: - View Life Cycles
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // Do any additional setup after loading the view.
        
        self.initialConfig()
    }
    
    override func viewDidLayoutSubviews() {
        if !hasSetOriginPoint {
            hasSetOriginPoint = true
            originPoint = view.frame.origin
        }
    }
    
    // MARK: - Selectors
    
    // Archive Button Action
    @IBAction func archiveButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 0, optionName: "Archive", indexPath: self.indexPath)
        }
    }
    
    // Delete Button Action
    @IBAction func deleteButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 1, optionName: "Delete", indexPath: self.indexPath)
        }
    }
    
    // Pin Button Action
    @IBAction func pinButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 2, optionName: "Pin", indexPath: self.indexPath)
        }
    }
    
    // Mute Notification Button Action
    @IBAction func muteNotificationButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 3, optionName: "Mute Notification", indexPath: self.indexPath)
        }
    }
    
    // Mark As Read Button Action
    @IBAction func markAsReadButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 4, optionName: "Mark as read", indexPath: self.indexPath)
        }
    }
    
    // Group Info Button Action
    @IBAction func groupInfoButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 5, optionName: "Group Info", indexPath: self.indexPath)
        }
    }
    
    // Exit group Button Action
    @IBAction func exitGroupButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 6, optionName: "Exit group", indexPath: self.indexPath)
        }
    }
    
    // Add Members Button Action
    @IBAction func addMembersButtonAction(_ sender: UIControl) {
        self.dismiss(animated: true) {
            self.delegate?.handleGroupListOptionTap(index: 7, optionName: "Add Members", indexPath: self.indexPath)
        }
    }
    
    // MARK: - Helper Functions
    
    // Initial Config
    func initialConfig() {
        self.sheetHeight = ((self.groupData?.owner ?? false) ? 336 : 240) + 32 + self.view.safeAreaBottom
        view.frame.size.height = sheetHeight
        view.isUserInteractionEnabled = true
        view.backgroundColor = sheetBackgroundColor
        view.roundCorners(corners: [.topLeft, .topRight], radius: sheetCornerRadius)
        self.setPanGesture()
        self.setUpUI()
    }
    
    // SetUp UI
    func setUpUI() {
        self.addMembersView.isHidden = !(self.groupData?.owner ?? false)
        self.deleteView.isHidden = !(self.groupData?.owner ?? false)
        self.archiveLabel.text = self.groupData?.mute?.archive == "yes" ? "Unarchive" : "Archive"
        self.pinLabel.text = self.groupData?.mute?.pin == "yes" ? "UnPin" : "Pin"
        self.muteNotificationLabel.text = self.groupData?.mute?.notify == "no" ? "Unmute notification" : "Mute notification"
    }
    
    // Set Pan Gesture
    func setPanGesture() {
        let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panGestureRecognizerAction))
        view.addGestureRecognizer(panGesture)
    }
    
    // Gesture Recognizer
    @objc func panGestureRecognizerAction(sender: UIPanGestureRecognizer) {
        let translation = sender.translation(in: view)
        // Not allowing the user to drag the view upward
        guard translation.y >= 0 else { return }
        view.frame.origin = CGPoint(
            x: 0,
            y: self.originPoint!.y + translation.y
        )
        if sender.state == .ended {
            self.dismiss(animated: true, completion: nil)
        }
    }
    
}

// MARK: - Extensions

// MARK: GroupListOptionDelegate Methods
extension ChatUserListVC: GroupListOptionDelegate {
    
    func handleGroupListOptionTap(index: Int, optionName: String, indexPath: IndexPath) {
        print(optionName + " Tapped")
        let groupChat = self.groupChats[indexPath.row]
        for group in self.groupsArray {
            if group.group_id == groupChat.group_id {
                self.groupApiData = group
                break
            }
        }
        switch index {
        case 0:
            if groupChat.mute?.archive == "yes" {
                self.archiveGroupChat(archive: "no", chat_id: groupChat.chat_id ?? "")
            } else {
                self.archiveGroupChat(archive: "yes", chat_id: groupChat.chat_id ?? "")
            }
        case 1:
            if let alertVC = R.storyboard.group.groupAlertWithTitleVC() {
                alertVC.delegate = self
                alertVC.titleText  = "Delete The Entire Conversation?"
                alertVC.messageText = "Once you delete your copy of conversation, it cannot be undone."
                alertVC.okText = "YES"
                alertVC.cancelText = "NO"
                self.present(alertVC, animated: true, completion: nil)
                alertVC.okButton.tag = indexPath.row
            }
        case 2:
            if groupChat.mute?.pin == "yes" {
                self.pinGroupChat(pin: "no", chat_id: groupChat.chat_id ?? "")
            } else {
                self.pinGroupChat(pin: "yes", chat_id: groupChat.chat_id ?? "")
            }
        case 3:
            if groupChat.mute?.notify == "yes" {
                self.notifyGroupChat(notify: "no", chat_id: groupChat.chat_id ?? "")
            } else {
                self.notifyGroupChat(notify: "yes", chat_id: groupChat.chat_id ?? "")
            }
        case 4:
            print("")
        case 5:
            if let newVC = R.storyboard.group.groupInfoViewController() {
                 newVC.groupData = self.groupApiData
                self.navigationController?.pushViewController(newVC, animated: true)
            }
        case 6:
            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 = indexPath.row
            }
        case 7:
            if let newVC = R.storyboard.group.updateGroupVC() {
                 newVC.groupData = self.groupApiData
                self.navigationController?.pushViewController(newVC, animated: true)
            }
        default:
            break;
        }
    }
    
}

// MARK: GroupAlertWithTitleVCDelegate Methods
extension ChatUserListVC: GroupAlertWithTitleVCDelegate {
    
    func groupAlertWithTitleOKButtonPressed(_ sender: UIButton) {
        let groupChat = self.groupChats[sender.tag]
        self.deleteGroup(group_id: groupChat.group_id ?? "")
    }
    
}

// MARK: GroupAlertVCDelegate Methods
extension ChatUserListVC: GroupAlertVCDelegate {
    
    func groupAlertOKButtonPressed(_ sender: UIButton) {
        let groupChat = self.groupChats[sender.tag]
        self.exitGroup(group_id: groupChat.group_id ?? "")
    }
    
}

// MARK: Api Call
extension ChatUserListVC {
    
    func archiveGroupChat(archive: String, chat_id: String) {
        Async.background {
            GroupChatManager.instance.muteGroupChat(muteType: API.Params.archive, mute: archive, chat_id: chat_id) { (success, sessionError, serverError, error) in
                if success != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            print(success?.message ?? "")
                            self.fetchGroupChatData()
                        }
                    }
                } 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)
                        }
                    }
                }
            }
        }
    }
    
    func pinGroupChat(pin: String, chat_id: String) {
        Async.background {
            GroupChatManager.instance.muteGroupChat(muteType: API.Params.pin, mute: pin, chat_id: chat_id) { (success, sessionError, serverError, error) in
                if success != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            print(success?.message ?? "")
                            self.fetchGroupChatData()
                        }
                    }
                } 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)
                        }
                    }
                }
            }
        }
    }
    
    func notifyGroupChat(notify: String, chat_id: String) {
        Async.background {
            GroupChatManager.instance.muteGroupChat(muteType: API.Params.notify, mute: notify, chat_id: chat_id) { (success, sessionError, serverError, error) in
                if success != nil {
                    Async.main {
                        self.dismissProgressDialog {
                            print(success?.message ?? "")
                            self.fetchGroupChatData()
                        }
                    }
                } 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)
                        }
                    }
                }
            }
        }
    }
    
    // Delete Group
    private func deleteGroup(group_id: String) {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            Async.background {
                GroupChatManager.instance.deleteGroup(group_Id: group_id, session_Token: sessionToken, type: "delete", completionBlock: { (success, sessionError, serverError, error) in
                    if success != nil {
                        Async.main {
                            self.dismissProgressDialog {
                                print("success = \(success?.api_status ?? 0)")
                                self.view.makeToast(success?.message_data)
                                let appDelegate = (UIApplication.shared.delegate) as? AppDelegate
                                let context = appDelegate?.persistentContainer.viewContext
                                let predicate = NSPredicate(format: "%K == %@", #keyPath(Messages.chat_id), group_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), group_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.fetchGroupChatData()
                            }
                        }
                    } 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)
            }
        }
    }
    
    // Exit Group
    private func exitGroup(group_id: String) {
        if Connectivity.isConnectedToNetwork() {
            let sessionToken = AppInstance.instance.sessionId ?? ""
            Async.background {
                GroupChatManager.instance.leaveGroup(group_Id: group_id , 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.view.makeToast(success?.message_data)
                                self.fetchGroupChatData()
                            }
                        }
                    } 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)
            }
        }
    }
    
}
