//
//  HMG_GUEST.swift
//  HMG-iOS-Wifi
//
//  Created by ZiKambrani on 23/03/1442 AH.
//  Copyright © 1442 ZiKambrani. All rights reserved.
//

import UIKit
import NetworkExtension
import SystemConfiguration.SCNetworkConnection

fileprivate var TEST = false
fileprivate let SSID = "GUEST-POC"
fileprivate var USER = ""
fileprivate var PASS = ""

fileprivate func supportedEAPTypes() -> [NSNumber]{
    let peap = NEHotspotEAPSettings.EAPType.EAPPEAP.rawValue
    let fast = NEHotspotEAPSettings.EAPType.EAPFAST.rawValue
    let tls  = NEHotspotEAPSettings.EAPType.EAPTLS.rawValue
    let ttls = NEHotspotEAPSettings.EAPType.EAPTTLS.rawValue
    return [NSNumber(value: peap), NSNumber(value: fast), NSNumber(value: tls), NSNumber(value: ttls)]
}

class HMG_Internet{
    static  let shared = HMG_Internet()
    
    private var complete:((_ status:Bool, _ message:String) -> Void)!
    func connect(patientId:String, completion:@escaping ((_ status:Bool, _ message:String) -> Void)){
        complete = completion
        
        if isAlreadyConnected() {
            hasInternet { (has) in
                if has == true{
                    FlutterText.with(key: "alreadyConnectedHmgNetwork"){ localized in
                        self.complete(true, localized)
                    }
                    return
                }else{
                    FlutterText.with(key: "connectedToHmgNetworkWithNoInternet"){ localized in
                        self.complete(false, localized)
                    }
                }
            }
        }else{
            connect(patientId: patientId)
        }
    }
    
    private func connect(patientId:String) {
        
        getWifiCredentials(patientId: patientId) {
            let trust_cert = Bundle.main.certificate(named: "GuestPOC_Certificate")
            guard trust_cert.trust() == true else{
                FlutterText.with(key: "notConnectedToHmgNetworkSecurityIssue"){ localized in
                    self.complete(false,localized)
                }
                return
            }
            
            let eapSettings = NEHotspotEAPSettings()
            eapSettings.username = USER
            eapSettings.password = PASS
            eapSettings.trustedServerNames = ["*.hmg.com","onboard.hmg.com","hmg.com"]
            eapSettings.supportedEAPTypes = [supportedEAPTypes().first!]
//            eapSettings.isTLSClientCertificateRequired = true
//            eapSettings.ttlsInnerAuthenticationType = .eapttlsInnerAuthenticationMSCHAPv2 // MSCHAPv2
//            eapSettings.setIdentity(Bundle.main.identity(named: "GuestPOC_Certificate", password: "1"))
//            eapSettings.setTrustedServerCertificates([trust_cert])
            
            let hotspotConfig = NEHotspotConfiguration(ssid: SSID, eapSettings: eapSettings)
            NEHotspotConfigurationManager.shared.apply(hotspotConfig) {[weak self] (error) in
                guard let self = self else { return; }
                
                if let error = error {

                    FlutterText.with(key: "errorConnectingHmgNetwork"){ localized in
                        self.complete(false,localized)
                    }
                    
                }else{
                    _ = Timer.scheduledTimer(withTimeInterval: 5, repeats: false) { (timer) in
                        self.hasInternet { (has) in
                            if has == true{
                                FlutterText.with(key: "connectedHmgNetworkWithInternet"){ localized in
                                    self.complete(true,localized)
                                }
                                return
                            }else{
                                FlutterText.with(key: "connectedToHmgNetworkWithNoInternet"){ localized in
                                    self.complete(false,localized)
                                }
                            }
                        }
                    }
                }
            }
            
        }
    }
    
    private func isAlreadyConnected() -> Bool{
        var currentSSID: String?
        if let interfaces = CNCopySupportedInterfaces() as NSArray? {
            for interface in interfaces {
                if let interfaceInfo = CNCopyCurrentNetworkInfo(interface as! CFString) as NSDictionary? {
                    currentSSID = interfaceInfo[kCNNetworkInfoKeySSID as String] as? String
                    break
                }
            }
        }
        print("CurrentConnectedSSID: \(currentSSID)")
        return currentSSID == SSID
    }
    
    
    private func getWifiCredentials(patientId:String, success: @escaping (() -> Void)){
        if TEST {
            success()
            return
        }
        
        guard let url = API.WIFI_CREDENTIALS.toUrl() else { return assert(true, "Invalid URL: \(API.WIFI_CREDENTIALS)") }

        // JSON Body for HTTP Request
        let json: [String: Any] = ["PatientID": patientId]
        let jsonData = try? JSONSerialization.data(withJSONObject: json)
        
        var request = URLRequest(url: url, timeoutInterval: 20)
        request.httpMethod = "POST"
        request.setValue("application/json", forHTTPHeaderField: "Content-Type")
        request.httpBody = jsonData

        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                self.somethingWentWrong()
                return
            }
            
            if let responseJSON = try? JSONSerialization.jsonObject(with: data, options: []) as? [String: Any]{
                if let requiredData = (responseJSON["Hmg_SMS_Get_By_ProjectID_And_PatientIDList"] as? [[String:Any]])?.first,
                    let userName = requiredData["UserName"] as? String, let password = requiredData["Password"] as? String{
                    
                    USER = userName
                    PASS = password
                    success()
                    
                }else if let errorMessage = responseJSON["ErrorMessage"] as? String{
                    self.complete(false, errorMessage)
                }else{
                    self.somethingWentWrong()
                }
            }else{
                self.somethingWentWrong()
            }
            
        }
        task.resume()
        
    }
    
    private func somethingWentWrong(){
        FlutterText.with(key: "somethingWentWrong") { (localized) in
            self.complete(false, localized)
        }
    }
    
    
    func hasInternet( completion:@escaping ((Bool)->Void)){
        
        let testUrl = "https://captive.apple.com"
        var request = URLRequest(url: URL(string: testUrl)!,timeoutInterval: 5)
        request.httpMethod = "GET"
        let task = URLSession.shared.dataTask(with: request) { data, response, error in
            guard let data = data else {
                completion(false)
                return
            }
            
            completion(
                String(data: data, encoding: .utf8)!
                    .replacingOccurrences(of: " ", with: "")
                    .replacingOccurrences(of: "\n", with: "")
                    .lowercased()
                    .contains("<title>success</title>")
            )
            
        }
        task.resume()
    }
    
}
