//
//  BroadcastManager.swift
//  WoWonder
//
//  Created by iMac on 16/05/24.
//  Copyright © 2024 ScriptSun. All rights reserved.
//

import Foundation
import Alamofire
import WowonderMessengerSDK

class BroadcastManager {
    
    static let instance = BroadcastManager()
    
    func createBroadcast(session_Token: String, broadcast_name: String, users: String, avatar_data: Data?, completionBlock: @escaping (_ Success: CreateBroadcastModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.type : API.Params.create,
            API.Params.name : broadcast_name,
            API.Params.users :users,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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 let avatarData = avatar_data {
                multipartFormData.append(avatarData, withName: "image", fileName: "avatar.jpg", mimeType: "image/png")
            }
        }, 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(CreateBroadcastModel.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 getBroadcast(session_Token: String, limit: Int, offset: Int, completionBlock: @escaping (_ Success: BroadcastModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.type : API.Params.get,
            API.Params.limit : limit,
            API.Params.offset: offset
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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(BroadcastModel.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 getBroadcastById(session_Token: String, broadcast_id: Int, completionBlock: @escaping (_ Success: BroadcastDataModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.type : API.Params.get_by_id,
            API.Params.id : broadcast_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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(BroadcastDataModel.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 editBroadcasr(session_Token: String, name: String, broadcast_id: Int, added_users: String, remove_users: String, avatar_data: Data?, completionBlock: @escaping (_ Success: EditBroadcastModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.type: API.Params.edit,
            API.Params.name: name,
            API.Params.id: broadcast_id,
            API.Params.added_users: added_users,
            API.Params.remove_users: remove_users,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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 let avatarData = avatar_data {
                multipartFormData.append(avatarData, withName: "image", fileName: "avatar.jpg", mimeType: "image/png")
            }
        }, 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(EditBroadcastModel.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 deleteBroadcast(broadcast_id: Int, session_Token: String, completionBlock: @escaping (_ Success: DeleteBroadcastModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.session_token : session_Token,
            API.Params.id : broadcast_id,
            API.Params.type : API.Params.delete,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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(DeleteBroadcastModel.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 sendMessageToBroadcast(message_hash_id: Int, broadcast_id: Int, text: String, session_Token: String, lat: Double, lag: Double, reply_id: String, completionBlock: @escaping (_ Success: BroadcastMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id : convertedHashID,
            API.Params.id : broadcast_id as Any,
            API.Params.text : text,
            API.Params.type : API.Params.send,
            "lat": lat,
            "lng": lag,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id
        ] as [String : Any]
        print("params >>>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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] {
                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(BroadcastMessageModel.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 sendBroadcastChatData(message_hash_id: Int, broadcast_id: Int, session_Token: String, type: String, image_data: Data?, imageMimeType: String?, video_data: Data?, videoMimeType: String?, file_data: Data?, file_Extension: String?, fileMimeType: String?, audio_data: Data?, audio_Extension: String?, audioMimeType: String?, reply_id: String, completionBlock: @escaping (_ Success: BroadcastMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.message_hash_id : message_hash_id,
            API.Params.type : API.Params.send,
            API.Params.id : broadcast_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.BROADCAST_API.GET_BROADCAST_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.\(audio_Extension ?? "")", mimeType: audioMimeType ?? "")
                }
            } 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(BroadcastMessageModel.self, from: data)
                    print("Success = \(result.api_status ?? 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 sendContactToBroadcast(message_hash_id: Int, broadcast_id: Int, jsonPayload: String, session_Token: String, contact: String = "1", reply_id: String, completionBlock: @escaping (_ Success: BroadcastMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id : convertedHashID,
            API.Params.id : broadcast_id,
            API.Params.text : jsonPayload,
            API.Params.contact : contact,
            API.Params.type : API.Params.send,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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] {
                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(BroadcastMessageModel.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 sendGIF(message_hash_id: Int, broadcast_id: Int, url: String, session_Token: String, reply_id: String, completionBlock: @escaping (_ Success: BroadcastMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id : convertedHashID,
            API.Params.id : broadcast_id,
            // API.Params.Text : url,
            API.Params.gif : url,
            API.Params.type : API.Params.send,
            API.Params.server_key : API.SERVER_KEY.Server_Key,
            API.Params.reply_id : reply_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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] {
                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(BroadcastMessageModel.self, from: data)
                    print("Success = \(result.message_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 sendSticker(message_hash_id: Int, broadcast_id: Int, url: String, sticker_id: String, session_Token: String, reply_id: String, completionBlock: @escaping (_ Success: BroadcastMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let convertedHashID = "\(message_hash_id)"
        let params = [
            API.Params.message_hash_id: convertedHashID,
            API.Params.id: broadcast_id,
            API.Params.image_url: url,
            API.Params.sticker_id: sticker_id,
            API.Params.type: API.Params.send,
            API.Params.server_key: API.SERVER_KEY.Server_Key,
            API.Params.reply_id: reply_id
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.BROADCAST_API.GET_BROADCAST_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] {
                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(BroadcastMessageModel.self, from: data)
                    print("Success = \(result.message_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)
            }
        }
    }
    
}
