import Foundation
import Alamofire
import WowonderMessengerSDK

class StoriesManager {
    
    static let instance = StoriesManager()
    
    func getStories(session_Token: String, limit: Int, completionBlock: @escaping (_ Success: StoriesResponse?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.list_id : limit,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Stories_Constants_Methods.GET_STORIES_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON(completionHandler: { (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(StoriesResponse.self, from: data)
                    print("Success = \(result.stories ?? [])")
                    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 getStoryById(session_Token: String, id: String, completionBlock: @escaping (_ Success: StoryModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.id : id,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Stories_Constants_Methods.GET_STORY_BY_ID_API + session_Token
        print("urlString >>>>> ", urlString)
        AF.request(urlString, method: .post, parameters: params, encoding: URLEncoding.default, headers: nil).responseJSON(completionHandler: { (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(StoryModel.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 createStory(session_Token: String, type: String, storyDescription: String, storyTitle: String, data: Data?, completionBlock: @escaping (_ Success: CreateStoryModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let params = [
            API.Params.file_type : type,
            API.Params.story_description : storyDescription,
            API.Params.story_title : storyTitle,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Stories_Constants_Methods.CREATE_STORY_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 = data {
                    multipartFormData.append(data, withName: "file", fileName: "file.jpg", mimeType: data.mimeType)
                }
            }
            if type == "video" {
                if let data = data {
                    multipartFormData.append(data, withName: "file", fileName: "video.mp4", mimeType: data.mimeType)
                }
            }
        }, 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(CreateStoryModel.self, from: data)
                    print("Success = \(result.storyID ?? 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 deleteStory(session_Token: String, story_id: String, completionBlock: @escaping (_ Success: ApiMessageModel?, _ AuthError: ErrorModel?, _ ServerKeyError: ServerKeyErrorModel?, Error?) -> () ) {
        let converted = Int(story_id)
        let params = [
            API.Params.story_id : converted ?? 0,
            API.Params.server_key : API.SERVER_KEY.Server_Key
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Stories_Constants_Methods.DELETE_STORY_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 reactStory(story_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: story_id,
            API.Params.reaction: reaction,
        ] as [String : Any]
        print("params >>>>> ", params)
        let urlString = API.Stories_Constants_Methods.REACT_STORY_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(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)
            }
        }
    }
    
}
