//
//  ViewController.swift
//  Runner
//
//  Created by  Mohammad Aljammal  & Elham Rababah on 23/6/20.
//  Copyright © 2020 The Chromium Authors. All rights reserved.
//

import UIKit
import OpenTok
import Alamofire


class ViewController: UIViewController {
    
    var session: OTSession?
    var publisher: OTPublisher?
    var subscriber: OTSubscriber?
    
    var kApiKey:String = ""
    
    var kSessionId:String = ""
    
    var kToken:String = ""
    
    var VC_ID: Int = 0
    var TokenID: String = ""
    var generalid : String = ""
    var DoctorId: Int = 0
    var baseUrl:String = ""
    
    var callBack: ICallProtocol?
    var timer = Timer()
    var seconds = 30
    var isUserConnect : Bool = false
    
    
    override func viewDidLoad() {
          super.viewDidLoad()
        
          setupButtons()
          askForMicrophonePermission()
          requestCameraPermissionsIfNeeded()
          hideVideoMuted()
          setupSession()
          // Do any additional setup after loading the view.
      }
    
    
    private func getSessionStatus() {
            let URL_USER_REGISTER = baseUrl+"LiveCareApi/DoctorApp/GetSessionStatus"
            let headers: HTTPHeaders = [
                "Content-Type":"application/json",
                "Accept":"application/json",
                
            ]
            
            let parameters = [
                "VC_ID": VC_ID,
                "TokenID": TokenID,
                "generalid": generalid,
                "DoctorId" : DoctorId ,
                ] as [String : Any]
            Alamofire.request(URL_USER_REGISTER, method: .post,parameters: parameters, encoding: JSONEncoding.default, headers: headers).responseJSON{
                    response in
                if self.isUserConnect {
                } else {
                    if let result = response.result.value {
                        let jsonData = result as! NSObject
                        if((jsonData.value(forKey: "SessionStatus")) as! Int  == 2 || (jsonData.value(forKey: "SessionStatus")) as! Int == 3) {
                            //jsonData
                            let jsonObject: [String: Any] = [
                                "sessionStatus": result ,
                                "callResponse": "CallNotRespond",
                            ]
                        self.callBack?.sessionNotResponded(res: jsonObject)
                        
                        }
                        
                                    }
                    self.sessionDisconnect();
                    self.timer.invalidate()
                }
                    //getting json value from the server
                    
            }
        }
  
    func setupButtons() {
        perform(#selector(hideControlButtons), with: nil, afterDelay: 3)
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(remoteVideoTapped(_:)))
        view.addGestureRecognizer(tapGestureRecognizer)
        view.isUserInteractionEnabled = true
    }

    // MARK: -Microphone Camera and Permission Request
        func askForMicrophonePermission() {
            switch AVAudioSession.sharedInstance().recordPermission {
            case AVAudioSession.RecordPermission.granted:
                    break
                case AVAudioSession.RecordPermission.denied:
                    break
                case AVAudioSession.RecordPermission.undetermined:
                    // This is the initial state before a user has made any choice
                    // You can use this spot to request permission here if you want
                    AVAudioSession.sharedInstance().requestRecordPermission({ granted in
                        // Check for granted
                    })
                default:
                    break
            }
        }
    
    func notifyUserOfCameraAccessDenial() {
        // display a useful message asking the user to grant permissions from within Settings > Privacy > Camera
    }
    
    
    @IBAction func didClickMuteButton(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        publisher!.publishAudio = !sender.isSelected
        
    }
    
  @IBAction  func didClickSpeakerButton(_ sender: UIButton) {
         sender.isSelected = !sender.isSelected
         subscriber?.subscribeToAudio = !sender.isSelected
        // resetHideButtonsTimer()
     }

   @IBAction  func didClickVideoMuteButton(_ sender: UIButton) {
         sender.isSelected = !sender.isSelected
    if publisher!.publishVideo {
            publisher!.publishVideo = false
         } else {
            publisher!.publishVideo = true
         }
         localVideo.isHidden = sender.isSelected
         localVideoMutedBg.isHidden = !sender.isSelected
         localVideoMutedIndicator.isHidden = !sender.isSelected
       //  resetHideButtonsTimer()

     }
    
    
    @IBAction func didClickSwitchCameraButton(_ sender: UIButton) {
        sender.isSelected = !sender.isSelected
        if sender.isSelected {
            publisher!.cameraPosition = AVCaptureDevice.Position.front
        } else {
            publisher!.cameraPosition = AVCaptureDevice.Position.back
        }
      ///  resetHideButtonsTimer()
    }

    @IBAction func hangUp(_ sender: UIButton) {
        callBack?.sessionDone(res:["callResponse":"CallEnd"])
        sessionDisconnect()
    }

    
    func sessionDisconnect() {
        if (session != nil)  {
            print("disconnecting....")
            session!.disconnect(nil)
            dismiss(animated: true)
            return
        }
        dismiss(animated: true)
    }
    //  Converted to Swift 5.2 by Swiftify v5.2.26743 - https://swiftify.com/
    func requestCameraPermissionsIfNeeded() {

        // check camera authorization status
        let authStatus: AVAuthorizationStatus = AVCaptureDevice.authorizationStatus(for: .video)
        switch authStatus {
        case .authorized: break
                // camera authorized
                // do camera intensive stuff
            case .notDetermined:
                // request authorization

                AVCaptureDevice.requestAccess(for: .video, completionHandler: { granted in
                    DispatchQueue.main.async(execute: {

                        if granted {
                            // do camera intensive stuff
                        } else {
                            self.notifyUserOfCameraAccessDenial()
                        }
                    })
                })
            case .restricted, .denied:
                DispatchQueue.main.async(execute: {
                    self.notifyUserOfCameraAccessDenial()
                })
            default:
                break
        }
    }
    
    
    func hideVideoMuted() {
        remoteVideoMutedIndicator.isHidden = true
        localVideoMutedBg.isHidden = true
        localVideoMutedIndicator.isHidden = true
    }
   
    func setupSession() {
        //setup one time session
        if (session != nil) {
            session = nil
        }
        session = OTSession(
            apiKey: kApiKey,
            sessionId: kSessionId,
            delegate: self)
       
            var error: OTError?
            session!.connect(withToken: kToken,error: &error)
        

    }
   func connectToAnOpenTokSession() {
       session = OTSession(apiKey: kApiKey, sessionId: kSessionId, delegate: self)
       var error: OTError?
       session?.connect(withToken: kToken, error: &error)
       if error != nil {
           print(error!)
       }
   }
    
    func showAlert(_ string: String?) {
        // show alertview on main UI
        DispatchQueue.main.async(execute: {
            let alertVC = UIAlertController(
                title: "OTError",
                message: string,
                preferredStyle: .alert)
            self.present(alertVC, animated: true)
        })
    }
    
    
    
    
    @IBOutlet weak var localVideo: UIView!
    
    @IBOutlet weak var remoteVideo: UIView!
    
    @IBOutlet weak var controlButtons: UIView!
    
    @IBOutlet weak var remoteVideoMutedIndicator: UIImageView!
    
    @IBOutlet weak var localVideoMutedBg: UIImageView!
    

    @IBOutlet weak var localVideoMutedIndicator: UIImageView!
    
    @objc func updateTimer(){
        seconds -= 1     //This will decrement(count down)the seconds.
        print(seconds)
        if seconds == 0 {
            getSessionStatus()
            
        }
        
    }
    
}


extension ViewController: OTSessionDelegate {
    
   func sessionDidConnect(_ session: OTSession) {
       print("The client connected to the OpenTok session.")
    
       
        
    
    timer = Timer.scheduledTimer(timeInterval: 1, target: self,   selector: (#selector(ViewController.updateTimer)), userInfo: nil, repeats: true)
    

        setupPublisher()
    
   }
        
    func setupPublisher() {
        let settings = OTPublisherSettings()
        settings.name = UIDevice.current.name
        publisher = OTPublisher(delegate: self, settings: settings)

        var error: OTError? = nil
        session!.publish(publisher!, error: &error)
        if error != nil {
            showAlert(error?.localizedDescription)
        }
       
        publisher?.view!.frame = CGRect(x: localVideo.bounds.origin.x, y: localVideo.bounds.origin.y, width: localVideo.bounds.size.width, height: localVideo.bounds.size.height)

        localVideo.addSubview((publisher?.view)!)
    }

   func sessionDidDisconnect(_ session: OTSession) {
       print("The client disconnected from the OpenTok session.")
   }

   func session(_ session: OTSession, didFailWithError error: OTError) {
       print("The client failed to connect to the OpenTok session: \(error).")
   }
    
    func session(
        _ session: OTSession,
        connectionDestroyed connection: OTConnection
    ) {
       
        if subscriber?.stream!.connection.connectionId == connection.connectionId {
            cleanupSubscriber()
        }
        sessionDisconnect()
    }
    

   func session(_ session: OTSession, streamCreated stream: OTStream) {
       subscriber = OTSubscriber(stream: stream, delegate: self)
       guard let subscriber = subscriber else {
           return
       }

       var error: OTError?
       session.subscribe(subscriber, error: &error)
       guard error == nil else {
           print(error!)
           return
       }

       guard let subscriberView = subscriber.view else {
           return
       }
       subscriberView.frame = UIScreen.main.bounds
       view.insertSubview(subscriberView, at: 0)
    
//    if nil == subscriber {
//        setupSubscribe(stream)
//    }
   }
    
    func setupSubscribe(_ stream: OTStream?) {
        subscriber = OTSubscriber(stream: stream!, delegate: self)

        var error: OTError? = nil
        session!.subscribe(subscriber!, error: &error)
        if error != nil {
            showAlert(error!.localizedDescription)
        }
    }
   func session(_ session: OTSession, streamDestroyed stream: OTStream) {
   

    if subscriber?.stream?.streamId == stream.streamId {
           cleanupSubscriber()
       }
       print("A stream was destroyed in the session.")
   }


    func cleanupSubscriber() {
        subscriber?.view!.removeFromSuperview()
        subscriber = nil
    }
    
    func session(
        _ session: OTSession?,
        connectionCreated connection: OTConnection?
    ) {
//        startTimer(callDuration, warningDuration)
        if let connectionId = connection?.connectionId {
            print("session connectionCreated (\(connectionId))")
        }
        isUserConnect  = true
        timer.invalidate()
    }

}

extension ViewController: OTPublisherDelegate {
   func publisher(_ publisher: OTPublisherKit, didFailWithError error: OTError) {
       print("The publisher failed: \(error)")
   }
    @objc func remoteVideoTapped(_ recognizer: UITapGestureRecognizer?) {
           if controlButtons.isHidden {
               controlButtons.isHidden = false
               perform(#selector(hideControlButtons), with: nil, afterDelay: 3)
           }
       }
}

extension ViewController: OTSubscriberDelegate {
   public func subscriberDidConnect(toStream subscriber: OTSubscriberKit) {
       print("The subscriber did connect to the stream.")
   }

   public func subscriber(_ subscriber: OTSubscriberKit, didFailWithError error: OTError) {
       print("The subscriber failed to connect to the stream.")
   }
    @objc func hideControlButtons() {
        controlButtons.isHidden = true
    }
}

