//
//  FloatingButton.swift
//  Qmera
//
//  Created by Yayan Dwi on 03/09/21.
//

import UIKit
import nuSDKService
import NotificationBannerSwift


public class FloatingButton: UIView {
    
    var groupView: UIStackView!
    var scrollView: UIScrollView!
    var button_fb1: UIButton!
    var button_fb2: UIButton!
    var button_fb3: UIButton!
    var button_fb4: UIButton!
    var nexilis_button: UIImageView!
    var nexilis_pin: UIImageView!
    var leadingConstraintPin: NSLayoutConstraint!
    var bottomConstraintPin: NSLayoutConstraint!
    var trailingConstraintPin: NSLayoutConstraint!
    var topConstraintPin: NSLayoutConstraint!
    var lastPosY: CGFloat?
    var lastImageButton = ""
    var iconCC = ""
    
    let indicatorCounterFB = UIView()
    let labelCounterFB = UILabel()
    let indicatorCounterFBBig = UIImageView()
    
    var datePull: Date?
    
    var panGesture: UIPanGestureRecognizer?
    
    public weak var mySettingDelegate: SettingMABDelegate?
    
    public var isShow: Bool = false
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        commonInit()
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    
    private func commonInit() {
        backgroundColor = .clear
        frame = CGRect(x: UIScreen.main.bounds.width - 50, y: (UIScreen.main.bounds.height / 2) - 50, width: 50.0, height: 50.0)
        
        panGesture = UIPanGestureRecognizer(target: self, action: #selector(draggedView(_:)))
        addGestureRecognizer(panGesture!)
        
        nexilis_button = UIImageView()
        nexilis_button.translatesAutoresizingMaskIntoConstraints = false
        nexilis_button.isUserInteractionEnabled = true
        if Utils.getIconDock() != nil {
            let dataImage = try? Data(contentsOf: URL(string: Utils.getUrlDock()!)!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
            if dataImage != nil {
                nexilis_button.image = UIImage(data: dataImage!)
            }
        } else {
            nexilis_button.image = UIImage(named: "pb_button", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)
        }
        
        let qmeraTap = UITapGestureRecognizer(target: self, action: #selector(qmeraTap))
        qmeraTap.numberOfTouchesRequired = 1
        nexilis_button.addGestureRecognizer(qmeraTap)
        
        let qmeraLongPress = UILongPressGestureRecognizer(target: self, action: #selector(qmeraLongPress(gestureRecognizer:)))
        nexilis_button.addGestureRecognizer(qmeraLongPress)
        
        addSubview(nexilis_button)
        
        nexilis_button.widthAnchor.constraint(equalToConstant: 50.0).isActive = true
        nexilis_button.heightAnchor.constraint(equalToConstant: 50.0).isActive = true
        nexilis_button.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        nexilis_button.bottomAnchor.constraint(equalTo: bottomAnchor).isActive = true
        
        scrollView = UIScrollView()
        scrollView.translatesAutoresizingMaskIntoConstraints = false
        scrollView.layer.borderWidth = 1.0
        scrollView.layer.borderColor = UIColor.white.cgColor
        scrollView.layer.cornerRadius = 8.0
        scrollView.layer.masksToBounds = true
        scrollView.backgroundColor = .black.withAlphaComponent(0.25)
        addSubview(scrollView)
        
        scrollView.widthAnchor.constraint(equalTo: widthAnchor).isActive = true
        scrollView.centerXAnchor.constraint(equalTo: centerXAnchor).isActive = true
        scrollView.topAnchor.constraint(equalTo: topAnchor).isActive = true
        scrollView.bottomAnchor.constraint(equalTo: nexilis_button.topAnchor).isActive = true
        
        groupView = UIStackView()
        groupView.translatesAutoresizingMaskIntoConstraints = false
        groupView.axis = .vertical
        groupView.distribution = .fillEqually

        scrollView.addSubview(groupView)

        groupView.widthAnchor.constraint(equalToConstant: 40).isActive = true
        groupView.topAnchor.constraint(equalTo: scrollView.topAnchor, constant: 5).isActive = true
        groupView.bottomAnchor.constraint(equalTo: scrollView.bottomAnchor, constant: -5).isActive = true
        groupView.leftAnchor.constraint(equalTo: scrollView.leftAnchor, constant: 6).isActive = true
        
        pullButton()
        
        let center: NotificationCenter = NotificationCenter.default
        center.addObserver(self, selector: #selector(imageFBUpdate(notification:)), name: NSNotification.Name(rawValue: "imageFBUpdate"), object: nil)
        center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: "onReceiveChat"), object: nil)
        center.addObserver(self, selector: #selector(checkCounter), name: NSNotification.Name(rawValue: "reloadTabChats"), object: nil)
        let tapGesture = UITapGestureRecognizer(target: self, action: #selector(hideButton))
        tapGesture.cancelsTouchesInView = false
        UIApplication.shared.windows.first?.rootViewController?.view.addGestureRecognizer(tapGesture)
    }
    
    private func pullButton() {
        if datePull == nil || Int(Date().timeIntervalSince(datePull!)) >= 60 {
            datePull = Date()
        } else if Int(Date().timeIntervalSince(datePull!)) < 60 {
            return
        }
        if !CheckConnection.isConnectedToNetwork()  || API.nGetCLXConnState() == 0 {
            let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
            imageView.tintColor = .white
            let banner = FloatingNotificationBanner(title: "Check your connection".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
            banner.show()
            return
        }
        DispatchQueue.global().async { [self] in
            if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.pullFloatingButton(), timeout: 30 * 1000){
                if response.isOk() {
                    let data = response.getBody(key: CoreMessage_TMessageKey.DATA, default_value: "")
                    if !data.isEmpty {
                        if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: String.Encoding.utf8)!, options: JSONSerialization.ReadingOptions()) as? [AnyObject] {
                            DispatchQueue.main.async { [self] in
                                groupView.subviews.forEach({ $0.removeFromSuperview() })
                                if jsonArray.count == 0 {
                                    getDefaultButton()
                                } else {
                                    for json in jsonArray {
                                        let package_id = json["package_id"] as! String
                                        let app_id = (json["app_id"] as? String) ?? ""
                                        let icon = (json["icon"] as? String) ?? ""
                                        let newButton = UIButton()
                                        newButton.heightAnchor.constraint(equalToConstant: 40).isActive = true
                                        newButton.translatesAutoresizingMaskIntoConstraints = false
                                        DispatchQueue.global().async {
                                            let data = try? Data(contentsOf: URL(string: "https://newuniverse.io/get_file?account=\(Nexilis.sAPIKey)&image=\(icon)")!) //make sure your image in this url does exist, otherwise unwrap in a if let check / try-catch
                                            DispatchQueue.main.async {
                                                if data != nil {
                                                    newButton.setImage(UIImage(data: data!), for: .normal)
                                                }
                                            }
                                        }
                                        groupView.addArrangedSubview(newButton)
                                        newButton.restorationIdentifier = package_id
                                        newButton.accessibilityIdentifier = app_id
                                        newButton.addTarget(self, action: #selector(fbTap), for: .touchUpOutside)
                                    }
                                }
                                let countSubviewsAfter = groupView.subviews.count
                                if countSubviewsAfter <= 4 {
                                    scrollView.isScrollEnabled = false
                                }
                            }
                        }
                    } else {
                        groupView.subviews.forEach({ $0.removeFromSuperview() })
                        getDefaultButton()
                    }
                } else {
                    groupView.subviews.forEach({ $0.removeFromSuperview() })
                    getDefaultButton()
                }
            }
        }
    }
    
    func getDefaultButton() {
        button_fb1 = UIButton()
        button_fb1.heightAnchor.constraint(equalToConstant: 40).isActive = true
        button_fb1.translatesAutoresizingMaskIntoConstraints = false
        button_fb1.setImage(UIImage(named: "pb_button_cc", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
        groupView.addArrangedSubview(button_fb1)
        button_fb1.addTarget(self, action: #selector(fb1Tap), for: .touchUpOutside)
        
        button_fb2 = UIButton()
        button_fb2.heightAnchor.constraint(equalToConstant: 40).isActive = true
        button_fb2.translatesAutoresizingMaskIntoConstraints = false
        button_fb2.setImage(UIImage(named: "pb_button_chat", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
        groupView.addArrangedSubview(button_fb2)
        button_fb2.addTarget(self, action: #selector(fb2Tap), for: .touchUpOutside)
        checkCounter()
        
        button_fb3 = UIButton()
        button_fb3.heightAnchor.constraint(equalToConstant: 40).isActive = true
        button_fb3.translatesAutoresizingMaskIntoConstraints = false
        button_fb3.setImage(UIImage(named: "pb_button_call", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
        groupView.addArrangedSubview(button_fb3)
        button_fb3.addTarget(self, action: #selector(fb3Tap), for: .touchUpOutside)
        
        button_fb4 = UIButton()
        button_fb4.heightAnchor.constraint(equalToConstant: 40).isActive = true
        button_fb4.translatesAutoresizingMaskIntoConstraints = false
        button_fb4.setImage(UIImage(named: "pb_button_stream", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
        groupView.addArrangedSubview(button_fb4)
        button_fb4.addTarget(self, action: #selector(fb4Tap), for: .touchUpOutside)
    }
    
    @objc func draggedView(_ sender:UIPanGestureRecognizer){
        let size = UIScreen.main.bounds
        let widthScreen = size.width
        let heightScreen = size.height
        let minimumx = (widthScreen + 30) - widthScreen
        let maximumx = widthScreen - 30
        let translation = sender.translation(in: self)
        var xPos = center.x + translation.x
        var yPos = center.y + translation.y
        bringSubviewToFront(self)
        if (xPos < minimumx) {
            xPos = minimumx
        }
        if (xPos > maximumx) {
            xPos = maximumx
        }
        if(isShow) {
            let minimumy = CGFloat(120.5) //30
            let maximumy = heightScreen - 100
            if(yPos < minimumy) {
                yPos = minimumy
            }
            if(yPos > maximumy) {
                yPos = maximumy
            }
        } else {
            let minimumy = (heightScreen + 50) - heightScreen
            let maximumy = heightScreen - 20
            if(yPos < minimumy) {
                yPos = minimumy
            }
            if(yPos > maximumy) {
                yPos = maximumy
            }
        }
        center = CGPoint(x: xPos, y: yPos)
        sender.setTranslation(CGPoint.zero, in: self)
        if lastPosY != nil {
            lastPosY = nil
        }
        UserDefaults.standard.set(center.x, forKey: "xlastPosFB")
        UserDefaults.standard.set(center.y, forKey: "ylastPosFB")
    }
    
    @objc func imageFBUpdate(notification: NSNotification) {
        
    }
    
    @objc func checkCounter() {
        let counter = queryCountCounter()
        if counter > 0 {
            DispatchQueue.main.async { [self] in
                if !indicatorCounterFB.isDescendant(of: button_fb2) {
                    button_fb2.addSubview(indicatorCounterFB)
                    indicatorCounterFB.layer.cornerRadius = 7.5
                    indicatorCounterFB.layer.masksToBounds = true
                    indicatorCounterFB.backgroundColor = .systemRed
                    indicatorCounterFB.anchor(top: button_fb2.topAnchor, left: button_fb2.leftAnchor, height: 15, minWidth: 15, maxWidth: 20)
                    indicatorCounterFB.addSubview(labelCounterFB)
                    labelCounterFB.anchor(left: indicatorCounterFB.leftAnchor, right: indicatorCounterFB.rightAnchor, paddingLeft: 5, paddingRight: 5, centerX: indicatorCounterFB.centerXAnchor, centerY: indicatorCounterFB.centerYAnchor)
                    labelCounterFB.font = .systemFont(ofSize: 10)
                    labelCounterFB.textColor = .white
                }
                if !indicatorCounterFBBig.isDescendant(of: nexilis_button){
                    nexilis_button.addSubview(indicatorCounterFBBig)
                    indicatorCounterFBBig.tintColor = .systemRed
                    indicatorCounterFBBig.image = UIImage(systemName: "staroflife.circle.fill")
                    indicatorCounterFBBig.anchor(top: nexilis_button.topAnchor, left: nexilis_button.leftAnchor, paddingTop: 5, paddingLeft: 5, width: 15, height: 15)
                }
                labelCounterFB.text = "\(counter)"
            }
        } else {
            DispatchQueue.main.async { [self] in
                if indicatorCounterFB.isDescendant(of: button_fb2) {
                    indicatorCounterFB.removeFromSuperview()
                }
                if indicatorCounterFBBig.isDescendant(of: nexilis_button) {
                    indicatorCounterFBBig.removeFromSuperview()
                }
            }
        }
    }
    
    private func queryCountCounter() -> Int32 {
        var counter: Int32?
        Database.shared.database?.inTransaction({ (fmdb, rollback) in
            if let cursor = Database.shared.getRecords(fmdb: fmdb, query: "SELECT SUM(counter) FROM MESSAGE_SUMMARY"), cursor.next() {
                counter = cursor.int(forColumnIndex: 0)
                cursor.close()
            }
        })
        return counter ?? 0
    }
    
    @objc func qmeraTap() {
        show(isShow: !isShow)
    }
    
    @objc func fbTap(_ sender: UIButton) {
        let package_id = sender.restorationIdentifier!
        var app_id = sender.accessibilityIdentifier!
        var indexTap = 0
        if package_id.contains("_fb"){
            indexTap = Int(String(package_id.split(separator: "_")[1]).substring(from: 2, to: 2))!
        }
        if indexTap == 2 {
            app_id = package_id.components(separatedBy: "_")[2]
        }
        Nexilis.buttonClicked(index: indexTap, id: app_id)
        hideButton()
    }
    
    @objc func fb1Tap() {
        Nexilis.openContactCenter()
        hideButton()
    }
    
    @objc func fb2Tap() {
        Nexilis.openChat()
        hideButton()
    }
    
    @objc func fb3Tap() {
        Nexilis.openCall()
        hideButton()
    }
    
    @objc func fb4Tap() {
        Nexilis.openStreaming()
        hideButton()
    }
    
    @objc func qmeraLongPress(gestureRecognizer: UILongPressGestureRecognizer) {
        if gestureRecognizer.state == .began {
            if mySettingDelegate != nil {
                mySettingDelegate?.settingDelegate()
            } else {
                let navigationController = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "settingNav") as! UINavigationController
                navigationController.modalPresentationStyle = .fullScreen
                navigationController.navigationBar.tintColor = .white
                navigationController.navigationBar.barTintColor = .mainColor
                navigationController.navigationBar.isTranslucent = false
                navigationController.navigationBar.overrideUserInterfaceStyle = .dark
                navigationController.navigationBar.barStyle = .black
                let cancelButtonAttributes: [NSAttributedString.Key: Any] = [NSAttributedString.Key.foregroundColor: UIColor.white]
                UIBarButtonItem.appearance().setTitleTextAttributes(cancelButtonAttributes, for: .normal)
                let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
                navigationController.navigationBar.titleTextAttributes = textAttributes
                navigationController.view.backgroundColor = .mainColor
                UIApplication.shared.rootViewController?.present(navigationController, animated: true, completion: nil)
            }
            hideButton()
        }
    }
    
    @objc public func hideButton() {
        if isShow {
            show(isShow: false)
        }
        if self.frame.origin.x < UIScreen.main.bounds.width / 2 - 30 {
            self.frame.origin.x = 0
        } else {
            self.frame.origin.x = UIScreen.main.bounds.width - 50
        }
    }
    
    public func show(isShow: Bool) {
        self.isShow = isShow
        if isShow {
            pullButton()
            if indicatorCounterFBBig.isDescendant(of: nexilis_button) {
                indicatorCounterFBBig.isHidden = true
            }
            let height = CGFloat(217) //40
            var yPosition = frame.origin.y - height + 50
            if yPosition <= 25 {
                lastPosY = frame.origin.y
                yPosition = 25
            }
            frame = CGRect(x: frame.origin.x, y: yPosition, width: frame.width, height: height)
            DispatchQueue.main.asyncAfter(deadline: .now() + 0.5, execute: { [self] in
                if isShow {
                    let countSubviewsAfter = groupView.subviews.count
                    if countSubviewsAfter > 5 {
                        scrollView.flashScrollIndicators()
                    }
                }
            })
        } else {
            if indicatorCounterFBBig.isDescendant(of: nexilis_button) {
                indicatorCounterFBBig.isHidden = false
            }
            let height = CGFloat(217) //40
            var yPosition = frame.origin.y + height - 50
            if lastPosY != nil {
                yPosition = lastPosY!
            }
            frame = CGRect(x: frame.origin.x, y: yPosition, width: frame.width, height: frame.width)
        }
    }
}

public protocol SettingMABDelegate: AnyObject {
    func settingDelegate()
}
