//
//  OnboardingViewController.swift
//  EncuestaMarle
//
//  Created by Tatiana Castro on 5/21/19.
//  Copyright © 2019 Marle. All rights reserved.
//

import UIKit
import ResearchKit

var jsonDict_reg = [String: Any]()
var n_jsonDict_reg = [String: Any]()
var jsonDict_r = [String: Any]()
var n_jsonDict_r = [String: Any]()
var jsonString_reg = String()
var jsonString_r = String()
var jsonData_reg = Data()
var newResponseReg: Bool = false
var response_reg: String = "" {
    didSet {
        newResponseReg = true
    }
}
var newResponseR: Bool = false
var response_r: String = "" {
    didSet {
        newResponseR = true
    }
}
var task = ORKTaskViewController()
var consentDocument = ConsentDocument()
var task_def = String()

var sentPDF: Bool = false
var jsonPDF = String()
var response_PDF = String()
var tokenPDF = String()

var resetPassword: Bool = false
var jsonString_reset = String()
var jsonDict_reset = [String: Any]()
var n_jsonDict_reset = [String: Any]()
var response_reset = String()

var response_id = String()

func getConsent_task(task: ORKTaskViewController) -> ORKTaskViewController{
    return task
}

func limpiarJson_reg(){
    let resultados_encuestas = jsonDict_reg["results"] as! [[String:Any]]
    if let resultado_pregunta = resultados_encuestas[2]["results"] as? [[String:Any]]{
        n_jsonDict_reg["token"]=token
        tokenPDF = token
        n_jsonDict_reg["email"]=resultado_pregunta[0]["textAnswer"]
        n_jsonDict_reg["password"]=resultado_pregunta[1]["textAnswer"]
        n_jsonDict_reg["gender"]=resultado_pregunta[3]["choiceAnswers"]
        
        // -------------------------------------------- ☹️ ----------------------------------------------
        
        // Removed due to Apple screwing up the keyboard constraints
        
        n_jsonDict_reg["job"]=resultado_pregunta[4]["choiceAnswers"]
        let date = resultado_pregunta[5]["dateAnswer"] as! String
        n_jsonDict_reg["yearBirth"]=date.prefix(4)
    }
}

func limpiarJson_recovery(){
    let resultados_encuestas = jsonDict_r["results"] as! [[String:Any]]
    if let resultado_pregunta = resultados_encuestas[0]["results"] as? [[String:Any]]{
        n_jsonDict_r["token"]=token
        n_jsonDict_r["email"]=resultado_pregunta[0]["textAnswer"]
        n_jsonDict_r["password"]=resultado_pregunta[1]["textAnswer"]
    }
}

//func limpiarJson_reset(){
//    let resultados_encuestas = jsonDict_reset["results"] as! [[String:Any]]
//    if let resultado_pregunta = resultados_encuestas[0]["results"] as? [[String:Any]]{
//        n_jsonDict_reset["email"]=resultado_pregunta[0]["textAnswer"]
//    }
//}

func sendEmail(email: String) {
    
    //impiarJson_reset()
    
    let jsonObject: NSMutableDictionary = NSMutableDictionary()
    
    jsonObject.setValue(email, forKey: "email")
    
    let request = NSMutableURLRequest(url: NSURL(string: "http://tania.uprrp.edu/askForEmail.php")! as URL)
    request.httpMethod = "POST"
    
    let jsonData: NSData
            
    do {
        jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
        let jsonEmail = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
        print("✅ Email recieved, sending request...")
        
        let postString = "data=\(jsonEmail)"
        request.httpBody = postString.data(using: String.Encoding.utf8)
        
        let task = URLSession.shared.dataTask(with: request as URLRequest) {
            data, response, error in
            if error != nil {
                print("error=\(String(describing: error))")
                return
            }
            
            print("response solito Email = \(String(describing: response))") //Error: 1062
            
            let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
            print("responseString Email = \(String(describing: responseString))")
            
            response_reset = responseString as! String
        }
        
        task.resume()
        
    } catch {
        print ("❌ JSON Failure")
    }
}

func sendJson_reg() {
    
    let request = NSMutableURLRequest(url: NSURL(string: "http://tania.uprrp.edu/registration.php")! as URL)
    request.httpMethod = "POST"
    let postString = "data=\(jsonString_reg)"
    print("json Sign-Up ✅")
    request.httpBody = postString.data(using: String.Encoding.utf8)
    
    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in
        if error != nil {
            print("error=\(String(describing: error))")
            return
        }
        
        print("response solito Sign Up = \(String(describing: response))") //Error: 1062
        
        let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        print("responseString Sign Up = \(String(describing: responseString))")
        
        response_reg = responseString! as String
    }
    task.resume()
}

func sendJson_r() {
    
    limpiarJson_recovery()
       do {
           let jsonData_r = try JSONSerialization.data(withJSONObject: n_jsonDict_r, options: .prettyPrinted)
           jsonString_r = NSString(data: jsonData_r, encoding: String.Encoding.utf8.rawValue)! as String
       }
       catch {
           print(error.localizedDescription)
       }
    
    
    let request = NSMutableURLRequest(url: NSURL(string: "http://tania.uprrp.edu/recoverAccount.php")! as URL)
    request.httpMethod = "POST"
    let postString = "data=\(jsonString_r)"
    request.httpBody = postString.data(using: String.Encoding.utf8)
    
    let task = URLSession.shared.dataTask(with: request as URLRequest) {
        data, response, error in
        if error != nil {
            print("error=\(String(describing: error))")
            return
        }
        
        print("response Recover Account ⚠️ solito = \(String(describing: response))") //Error: 1062
        
        let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
        print("response Recover Account ⚠️ reg= \(String(describing: responseString))")
        
        response_r = responseString as! String
        // REMEMBER TO PRESENT ERRORS BASED ON RESPONSE (EMAIL MAL OR PW MAL)
    }
    task.resume()
}

func sendPDF(_ base64EncodedPDF: String, _ date: Date) {
    
    if sentPDF == false {
        let request = NSMutableURLRequest(url: NSURL(string: "http://tania.uprrp.edu/getSignatureIOS2.php")! as URL)
        request.httpMethod = "POST"
        
    //    let jsonObject1: [String: Any] = [
    //        "data": [
    //            "signaturePDFBase64": base64EncodedPDF,
    //            "signatureDate": date,
    //            "token": tokenPDF
    //        ],
    //    ]
        
        let jsonObject: NSMutableDictionary = NSMutableDictionary()
        
        jsonObject.setValue(base64EncodedPDF, forKey: "signaturePDFBase64")
        jsonObject.setValue(date.description, forKey: "signatureDate")
        jsonObject.setValue(tokenPDF, forKey: "token")
        
        print("Date is formatted as: 📆")
        print(date.description)
        
        let jsonData: NSData
        
        do {
            jsonData = try JSONSerialization.data(withJSONObject: jsonObject, options: JSONSerialization.WritingOptions()) as NSData
            let jsonString_PDF = NSString(data: jsonData as Data, encoding: String.Encoding.utf8.rawValue) as! String
            print("✅ jsonPDF Created, sending request...")
            
            let postString = "data=\(jsonString_PDF)"
            request.httpBody = postString.data(using: String.Encoding.utf8)
            
            let task = URLSession.shared.dataTask(with: request as URLRequest) {
                data, response, error in
                if error != nil {
                    print("error=\(String(describing: error))")
                    return
                }
                
                print("response solito PDF = \(String(describing: response))") //Error: 1062
                
                let responseString = NSString(data: data!, encoding: String.Encoding.utf8.rawValue)
                print("responseString PDF = \(String(describing: responseString))")
                
                response_PDF = responseString as! String
            }
            sentPDF = true
            task.resume()
            
        } catch {
            print ("❌ JSON Failure")
        }
    }
}

class OnboardingViewController: UIViewController {
    
    @IBAction func joinButtonTapped(_ sender: UIButton) {
        
        let consentStep = ORKVisualConsentStep(identifier: "VisualConsentStep", document: consentDocument)
        
        let registrationTitle = NSLocalizedString("Registration", comment: "")
        let passcodeValidationRegularExpressionPattern = "^(?=.*\\d).{4,8}$"
        let passcodeValidationRegularExpression = try! NSRegularExpression(pattern: passcodeValidationRegularExpressionPattern)
        let passcodeInvalidMessage = NSLocalizedString("A valid password must be 4 to 8 characters long and include at least one numeric character.", comment: "")
        let registrationOptions: ORKRegistrationStepOption =  [.includeGender, .includeJob, .includeDOB]
        let registrationStep = ORKRegistrationStep(identifier: "registration", title: registrationTitle, text: "Register for MARLE Study", passcodeValidationRegularExpression: passcodeValidationRegularExpression, passcodeInvalidMessage: passcodeInvalidMessage, options: registrationOptions)
        
        let signature = consentDocument.signatures!.first!
        let reviewConsentStep = ORKConsentReviewStep(identifier: "ConsentReviewStep", signature: signature, in: consentDocument)
        
        reviewConsentStep.text = "Review the consent form."
        reviewConsentStep.reasonForConsent = "Consent to join the MARLE Study."
        
        let passcodeStep = ORKPasscodeStep(identifier: "Passcode")
        passcodeStep.text = "Now you will create a passcode to identify yourself to the app and protect access to information you've entered."
        
        
        let completionStep = ORKCompletionStep(identifier: "CompletionStep")
        completionStep.title = "Welcome aboard."
        completionStep.text = "Thank you for joining this study."
    
        print("checko")
        task_def = "registration"
        let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, registrationStep])
        let taskViewController = ORKTaskViewController(task: orderedTask, taskRun: nil)
        taskViewController.delegate = self
        if response_reg == "Error:Email"{
            let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, registrationStep])
            let taskViewController = ORKTaskViewController(task: orderedTask, taskRun: nil)
            taskViewController.delegate = self
            present(taskViewController, animated: true){
                let alertTitle = NSLocalizedString("Error: Email Already Registered", comment: "")
                let alertMessage = NSLocalizedString("Exit and try recovering your account", comment: "")
                let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                taskViewController.present(alert, animated: true, completion: nil)
                self.performSegue(withIdentifier: "toOnboarding", sender: nil)
            }
        }
        else if response_reg == "Error:Token"{
            let orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, registrationStep])
            let taskViewController = ORKTaskViewController(task: orderedTask, taskRun: nil)
            taskViewController.delegate = self
            present(taskViewController, animated: true){
                let alertTitle = NSLocalizedString("Error: Phone Already Used", comment: "")
                let alertMessage = NSLocalizedString("This phone has been used to create an account already. Please contact your mentor.", comment: "")
                let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                taskViewController.present(alert, animated: true, completion: nil)
                self.performSegue(withIdentifier: "toOnboarding", sender: nil)
            }
        }
        else{
            let c_orderedTask = ORKOrderedTask(identifier: "Join", steps: [consentStep, reviewConsentStep, registrationStep, completionStep])
            let c_taskViewController = ORKTaskViewController(task: c_orderedTask, taskRun: nil)
            c_taskViewController.delegate = self
            present(c_taskViewController, animated: true, completion: nil)
 
            let taskViewController = ORKTaskViewController(task: EncuestaMarle, taskRun: nil)
            taskViewController.delegate = (self as ORKTaskViewControllerDelegate)
            present(taskViewController, animated: true, completion: nil)
            

        }
    }
    
    @IBAction func recover_account(_ sender: UIButton) {
        class LoginViewController : ORKLoginStepViewController {
            override func forgotPasswordButtonTapped() {
                var email: String = ""
                let alertTitle = NSLocalizedString("Enter your email", comment: "")
                let alertMessage = NSLocalizedString("You will recieve instructions to reset your password.", comment: "")
                let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                alert.addTextField { (textField) in
                    textField.placeholder = "Email"
                }
                alert.addAction(UIAlertAction(title: "Submit", style: UIAlertAction.Style.default, handler: { [weak alert] (_) in
                    let textField = alert!.textFields![0] // Force unwrapping because we know it exists.
                    print("Text field email: \(String(describing: textField.text))")
                    email = textField.text!
                    sendEmail(email: email)
                    let alertTitle2 = NSLocalizedString("If the email is registered we will send you an email", comment: "")
                    let alertMessage2 = NSLocalizedString("Check \(email) for instructions to reset your password", comment: "")
                    let alert2 = UIAlertController(title: alertTitle2, message: alertMessage2, preferredStyle: UIAlertController.Style.alert)
                    alert2.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                    self.present(alert2, animated: true, completion: nil)
                }))
                alert.addAction(UIAlertAction(title: "Cancel", style: UIAlertAction.Style.cancel , handler: nil))
                
                self.present(alert, animated: true, completion: nil)
            }
        }
        
        let loginTitle = NSLocalizedString("Recover Account", comment: "")
        let loginStep = ORKLoginStep(identifier: "recover" , title: loginTitle, text: "Fill out information to recover account", loginViewControllerClass: LoginViewController.self)
        
        let orderedTask = ORKOrderedTask(identifier: "Join", steps: [loginStep])
        let taskViewController = ORKTaskViewController(task: orderedTask, taskRun: nil)
        taskViewController.delegate = self
        
        if (resetPassword) {
            task_def = "reset"
            resetPassword = false
            let alertTitle2 = NSLocalizedString("Email will arrive soon", comment: "")
            let alertMessage2 = NSLocalizedString("Check your inbox for instructions to reset your password", comment: "")
            let alert2 = UIAlertController(title: alertTitle2, message: alertMessage2, preferredStyle: UIAlertController.Style.alert)
            alert2.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
            self.present(alert2, animated: true, completion: nil)
        }
        else {
            task_def = "recover"
        }
        present(taskViewController, animated: true, completion: nil)

    }
    
}

extension OnboardingViewController : ORKTaskViewControllerDelegate {
    
    public func taskViewController(_ taskViewController: ORKTaskViewController, didFinishWith reason: ORKTaskViewControllerFinishReason, error: Error?) {
        switch reason {
        case .completed:
            if task_def == "reset" {
                let taskResult_reset = taskViewController.result
                let jsonData_reset = try! ORKESerializer.jsonData(for: taskResult_reset)
                jsonString_reset = NSString(data: jsonData_reset, encoding: String.Encoding.utf8.rawValue)! as String
                jsonDict_reset = convertToDictionary(text: jsonString_r as String) as! [String: Any]
                do {
                    let jsonData_reset = try JSONSerialization.data(withJSONObject: jsonDict_reset, options: .prettyPrinted)
                    jsonString_reset = NSString(data: jsonData_reset, encoding: String.Encoding.utf8.rawValue)! as String
                }
                catch {
                    print(error.localizedDescription)
                }
                //sendEmail()
                
                
            }
            else if task_def == "recover"{
                let taskResult_r = taskViewController.result
                let jsonData_r = try! ORKESerializer.jsonData(for: taskResult_r)
                jsonString_r = NSString(data: jsonData_r, encoding: String.Encoding.utf8.rawValue)! as String
                jsonDict_r = convertToDictionary(text: jsonString_r as String) as! [String: Any]
                do {
                    let jsonData_r = try JSONSerialization.data(withJSONObject: jsonDict_r, options: .prettyPrinted)
                    jsonString_r = NSString(data: jsonData_r, encoding: String.Encoding.utf8.rawValue)! as String
                }
                catch {
                    print(error.localizedDescription)
                }
                sendJson_r()
                
                // TODO:
                // THIS REPRESENTS HOW TO RESPOND TO WRONG INPUT
                
                while(newResponseR == false) {}
                newResponseR = false
                
                // implement if (resetPassword == true) workflow
                
                if (response_r == "Error:hash" || response_r == "Error:password") {
                    
                    let alertTitle = NSLocalizedString("Email and Password do not match", comment: "")
                    let alertMessage = NSLocalizedString("Try again or tap forgot password.", comment: "")
                    let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                    taskViewController.present(alert, animated: true, completion: nil)
                    //self.performSegue(withIdentifier: "toOnboarding", sender: nil)
                }
                else if response_r == "Error:token"{
                    let alertTitle = NSLocalizedString("Phone already registered", comment: "")
                    let alertMessage = NSLocalizedString("This phone has been used to create an account already. Please contact your mentor and inform them about this error message", comment: "")
                    let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                    taskViewController.present(alert, animated: true, completion: nil)
                    //self.performSegue(withIdentifier: "toOnboarding", sender: nil)
                }
                
                else {
                    UserDefaults.standard.set(true, forKey: "registered")
                    UserDefaults.standard.synchronize()
                    performSegue(withIdentifier: "unwindToStudy", sender: nil)
                }
            }
            else{
                let taskResult_reg = taskViewController.result
                
                if let stepResult = taskResult_reg.stepResult(forStepIdentifier: "ConsentReviewStep"),
                    let signatureResult = stepResult.results?.first as? ORKConsentSignatureResult {
                    print("Signature generated ✅")
                    print(signatureResult)
                    let signatureDate = signatureResult.endDate
                    // lets try to make a pdf for this
                    
                    let documentCopy = consentDocument
                    signatureResult.apply(to: documentCopy)
                    
                    documentCopy.makePDF { (data, error) -> Void in
                        
                        var docURL = (FileManager.default.urls(for: .documentDirectory, in: .userDomainMask)).last as NSURL?
                        docURL = docURL?.appendingPathComponent("ConsentDocument.pdf") as NSURL?
                        
                        do {
                            try data?.write(to:docURL! as URL)
                            print("PDF generated ✅")
                            print(docURL! as URL)
                            if let pdfBase64 = data?.base64EncodedString() {
                                sendPDF(pdfBase64, signatureDate)
                            }
                            
                            
                        } catch let error {
                            print("❌")
                            print(error.localizedDescription)
                            
                        }
                    }
                    
//                    let sigJson = try! ORKESerializer.jsonData(for: signatureResult)
//                    print(sigJson.base64EncodedString())
                }
                
                let jsonData_reg = try! ORKESerializer.jsonData(for: taskResult_reg)
                jsonString_reg = NSString(data: jsonData_reg, encoding: String.Encoding.utf8.rawValue)! as String
                jsonDict_reg = convertToDictionary(text: jsonString_reg as String) as! [String: Any]
                limpiarJson_reg()
                do {
                    let jsonData_reg = try JSONSerialization.data(withJSONObject: n_jsonDict_reg, options: .prettyPrinted)
                    jsonString_reg = NSString(data: jsonData_reg, encoding: String.Encoding.utf8.rawValue)! as String
                }
                catch {
                    print(error.localizedDescription)
                }
                
                // TODO:
                
                // MAYBE THIS DOES IT BETTER
                sendJson_reg()
                while(newResponseReg == false) {}
                newResponseReg = false
                if response_reg == "Error:email"{
                    
                    let alertTitle = NSLocalizedString("Email Already Registered", comment: "")
                    let alertMessage = NSLocalizedString("Exit and try recovering your account", comment: "")
                    let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                    taskViewController.present(alert, animated: true, completion: nil)
                    //self.performSegue(withIdentifier: "toOnboarding", sender: nil)
                }
                else if response_reg == "Error:token"{
                    let alertTitle = NSLocalizedString("Phone Already Used", comment: "")
                    let alertMessage = NSLocalizedString("This phone has been used to create an account already. Please contact your mentor.", comment: "")
                    let alert = UIAlertController(title: alertTitle, message: alertMessage, preferredStyle: UIAlertController.Style.alert)
                    alert.addAction(UIAlertAction(title: "OK", style: UIAlertAction.Style.default, handler: nil))
                    taskViewController.present(alert, animated: true, completion: nil)
                    //self.performSegue(withIdentifier: "toOnboarding", sender: nil)
                }
                else{
                    UserDefaults.standard.set(true, forKey: "registered")
                    UserDefaults.standard.synchronize()
//                    let vc = ResearchContainerViewController()
//                    self.present(vc, animated: true, completion: nil)
                    performSegue(withIdentifier: "unwindToStudy", sender: nil)

 //                   performSegue(withIdentifier: "toStudy2", sender: self)
                }

//                else{
//                    present(taskViewController, animated: true){
//                        let completionStep = ORKCompletionStep(identifier: "CompletionStep")
//                        completionStep.title = "Welcome aboard."
//                        completionStep.text = "Thank you for joining this study."
//                        let orderedTask = ORKOrderedTask(identifier: "Join", steps: [completionStep])
//                        let c_taskViewController = ORKTaskViewController(task: orderedTask, taskRun: nil)
//                        c_taskViewController.delegate = self
//                        taskViewController.present(c_taskViewController, animated: true)
//                    }
//                }
            }
            
        case .discarded, .failed, .saved:
            dismiss(animated: true, completion: nil)
        }
    }
}

@IBDesignable extension UIButton {

    @IBInspectable var borderWidth: CGFloat {
        set {
            layer.borderWidth = newValue
        }
        get {
            return layer.borderWidth
        }
    }

    @IBInspectable var cornerRadius: CGFloat {
        set {
            layer.cornerRadius = newValue
        }
        get {
            return layer.cornerRadius
        }
    }

    @IBInspectable var borderColor: UIColor? {
        set {
            guard let uiColor = newValue else { return }
            layer.borderColor = uiColor.cgColor
        }
        get {
            guard let color = layer.borderColor else { return nil }
            return UIColor(cgColor: color)
        }
    }
}

//extension NSLayoutConstraint {
//
//    override public var description: String {
//        let id = identifier ?? ""
//        return "id: \(id), constant: \(constant)" //you may print whatever you want here
//    }
//}
