import Foundation
import Alamofire
import WowonderMessengerSDK

class ChatManager {
    
    static let instance = ChatManager()
    
    func getUserMessages(user_id: String, session_Token: String, receipent_id: String, limit: Int = -1, afterMsgId: String? = nil, beforeMsgId: String? = nil, messageId: String? = nil, _ completionBlock: @escaping (_ Success: MessageModelResponse?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let covertedReceipientId = Int(receipent_id) ?? 0
        var params: [String : Any] = [
            API.Params.recipient_id : covertedReceipientId,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
        ]
        if limit > 0 {
            params["limit"] = limit
        }
        if let afterMsgId = afterMsgId {
            params["after_message_id"] = afterMsgId
        }
        if let beforeMsgId = beforeMsgId {
            params["before_message_id"] = beforeMsgId
        }
        if let messageId = messageId {
            params["message_id"] = messageId
        }
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.GET_USER_CHATS_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(MessageModelResponse.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func sendMessage(message: String, session_token: String, ReceipientId: String, lat: Double, lng: Double, reply_id: String, story_id: String, completionBlock: @escaping (_ Success: SendMessageResponse?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let covertedReceipientId = Int(ReceipientId) ?? 0
        let messageHashId = Int(arc4random_uniform(UInt32(100000)))
        let params = [
            API.Params.message_hash_id : messageHashId,
            API.Params.user_id : covertedReceipientId,
            API.Params.text : message,
            API.Params.lat : lat,
            API.Params.lng: lng,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id,
            API.Params.story_id: story_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEND_MESSAGE_API + session_token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SendMessageResponse.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func sendChatData(message_hash_id: Int, receipent_id: String, session_Token: String, type: String, audio_data: Data?, image_data: Data?, video_data: Data?, imageMimeType: String?, videoMimeType: String?, audioMimeType: String?, text: String, file_data: Data?, file_Extension: String?, fileMimeType: String?, reply_id: String, story_id: String, completionBlock: @escaping (_ Success: SendMessageModelOld?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.message_hash_id : message_hash_id,
            API.Params.user_id : receipent_id,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id,
            API.Params.story_id: story_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEND_MESSAGE_API + session_Token
        print("urlString >>>>> ", urlString)
        let headers: HTTPHeaders = [
            "Content-type": "multipart/form-data"
        ]
        AF.upload(multipartFormData: { (multipartFormData) in
            for (key, value) in params {
                multipartFormData.append("\(value)".data(using: String.Encoding.utf8)!, withName: key as String)
            }
            if type == "image" {
                if let data = image_data{
                    multipartFormData.append(data, withName:"file", fileName: "image.jpg", mimeType: imageMimeType ?? "")
                }
            } else if type == "video" {
                if let data = video_data {
                    multipartFormData.append(data, withName: "file", fileName: "video.mp4", mimeType: videoMimeType ?? "")
                }
            } else if type == "audio" {
                if let data = audio_data {
                    multipartFormData.append(data, withName: "file", fileName: "audio.\(file_Extension ?? "")", mimeType: audioMimeType ?? "")
                }
            } else if type == "location" {
                if let fileData = file_data {
                    multipartFormData.append(fileData, withName: "file", fileName: "location.\(file_Extension ?? "")", mimeType: fileMimeType ?? "")
                }
            } else {
                if let fileData = file_data {
                    multipartFormData.append(fileData, withName: "file", fileName: "file.\(file_Extension ?? "")", mimeType: fileMimeType ?? "")
                }
            }
        }, to: urlString, usingThreshold: UInt64.init(), method: .post, headers: headers).responseJSON(completionHandler: { (response) in
            print("Succesfully uploaded")
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SendMessageModelOld.self, from: data)
                    print("Success = \(result.apiStatus ?? 0)")
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        })
    }
    
    func sendContactApiCall(message_hash_id: Int, receipent_id: String, sendType: String, jsonPayload: String, session_Token: String, Contact: String = "1", reply_id: String, story_id: String, completionBlock: @escaping (_ Success: SendMessageModelOld?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.message_hash_id : message_hash_id,
            API.Params.user_id : receipent_id,
            API.Params.text : jsonPayload,
            API.Params.contact : Contact,
            API.Params.type : sendType,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id,
            API.Params.story_id: story_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEND_MESSAGE_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SendMessageModelOld.self, from: data)
                    print("Success = \(result.messageData ?? [])")
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func deleteChatMessage(messageId: String, session_Token: String, completionBlock: @escaping (_ Success: ApiMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.message_id : messageId,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.DELETE_MESSAGE_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(ApiMessageModel.self, from: data)
                    print("Success = \(result.message ?? "")")
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func sendGIF(message_hash_id: Int, receipent_id: String, URl: String, session_Token: String, reply_id: String, story_id: String, completionBlock: @escaping (_ Success: SendMessageModelOld?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let covertedReceipientId = Int(receipent_id)
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id : convertedHashID,
            API.Params.user_id : covertedReceipientId ?? 0,
            API.Params.gif : URl,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id,
            API.Params.story_id: story_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEND_MESSAGE_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String: Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SendMessageModelOld.self, from: data)
                    print("Success = \(result.messageData ?? [])")
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func sendSticker(message_hash_id: Int, receipent_id: String, sticker_id: Int, URl: String, session_Token: String, reply_id: String, completionBlock: @escaping (_ Success: SendMessageModelOld?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let covertedReceipientId = Int(receipent_id)
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id : convertedHashID,
            API.Params.user_id : covertedReceipientId ?? 0,
            API.Params.image_url : URl,
            API.Params.sticker_id: sticker_id,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEND_MESSAGE_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String: Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SendMessageModelOld.self, from: data)
                    print("Success = \(result.messageData ?? [])")
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func getSearchMessage(user_id: String, text: String, completionBlock: @escaping (_ Success: SearchMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.type: API.Params.search,
            API.Params.user_id : user_id,
            API.Params.text: text
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.SEARCH_MESSAGE_API + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(SearchMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func getPinMessage(chat_id: String, completionBlock: @escaping (_ Success: PinMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.chat_id : chat_id,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.MESSAGE_API.GET_PIN_MESSAGE + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(PinMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func pinMessage(message_id: String, pin: String, chat_id: String, completionBlock: @escaping (_ Success: ApiMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.message_id: message_id,
            API.Params.type: API.Params.user,
            API.Params.pin: pin,
            API.Params.chat_id : chat_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.MESSAGE_API.PIN_MESSAGE + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(ApiMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func getFavMessage(chat_id: String, completionBlock: @escaping (_ Success: FavMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.chat_id : chat_id,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.MESSAGE_API.GET_FAV_MESSAGE + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(FavMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func favMessage(message_id: String, fav: String, chat_id: String, completionBlock: @escaping (_ Success: ApiMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.message_id: message_id,
            API.Params.type: API.Params.user,
            API.Params.fav: fav,
            API.Params.chat_id : chat_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.MESSAGE_API.FAV_MESSAGE + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(ApiMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func reactMessage(message_id: String, reaction: String, completionBlock: @escaping (_ Success: ApiMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.id: message_id,
            API.Params.reaction: reaction,
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.MESSAGE_API.REACT_MESSAGE + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(ApiMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
    func forwardMessage(message_id: String, recipient_id: String, completionBlock: @escaping (_ Success: ForwardMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let covertedReceipientId = Int(recipient_id) ?? 0
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.id: message_id,
            API.Params.recipient_id: covertedReceipientId,
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Chat_Methods.FORWARD_MESSAGE_API + AppInstance.instance._sessionId
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON { (response) in
            if let res = response.value as? [String : Any] {
                print("Response = \(res)")
                guard let apiStatus = res["api_status"] else { return }
                if apiStatus is Int {
                    print("apiStatus Int = \(apiStatus)")
                    let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                    let result = try! JSONDecoder().decode(ForwardMessageModel.self, from: data)
                    completionBlock(result, nil, nil, nil)
                } else {
                    let apiStatusString = apiStatus as? String
                    if apiStatusString == "400" {
                        print("apiStatus String = \(apiStatus)")
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, result, nil, nil)
                    } else if apiStatusString == "404" {
                        let data = try! JSONSerialization.data(withJSONObject: res, options: [])
                        let result = try! JSONDecoder().decode(ServerKeyErrorModel.self, from: data)
                        print("AuthError = \(result.errors?.error_text ?? "")")
                        completionBlock(nil, nil, result, nil)
                    }
                }
            } else {
                print("error = \(response.error?.localizedDescription ?? "")")
                completionBlock(nil, nil, nil, response.error)
            }
        }
    }
    
}
