//
//  WXUserInfoRemoteAPI.swift
//  PaiaiDataKit
//
//  Created by FFIB on 2018/12/26.
//  Copyright © 2018 FFIB. All rights reserved.
//

import Foundation
import RxSwift

fileprivate let WXAppid = "wx4e22a0c8ae6d766d"
fileprivate let WXSecret = "636ac848016c593575d11143c55c8333"

struct WXUserInfoRemoteAPI: UserInfoRemoteAPI {
    
    init() {}
    
    func login() -> Single<UserInfo> {
        #if (arch(i386) || arch(x86_64))
        return Single.create(subscribe: { (observer) in
            observer(.success(UserInfo(json: ["user_id": "fiDz2Ms" as AnyObject, "userName": "郑剑飞" as AnyObject, "photoPath": "https://wx.qlogo.cn/mmopen/vi_32/Q0j4TwGTfTJibSYLgvXpMakvD9FaCqfiaWqcMiaiaz905YxWPuO4hy8F2lGheV7kVr9vKKXFgmL1S5s4QJgxwuwtVw/132" as AnyObject])))
            return Disposables.create()
        })
        #else
        loginWithWeChat()
        return addWXLoginDidFinish().flatMap({
            return self.getWXToken(param: $0)
        }).flatMap({
            return self.getWXUserInfo(param: $0)
        }).flatMap({
            return self.wxLogin(param: $0)
        }).do(onSuccess: { res in
            print(res)
        })
        #endif
    }
    
    fileprivate func loginWithWeChat() {
        let request = SendAuthReq()
        request.scope = "snsapi_userinfo,snsapi_base"
        request.state = "skilogin"
        
        WXApi.send(request)
    }
    
    fileprivate func addWXLoginDidFinish() -> Single<[String: String]> {
        return Single.create(subscribe: { observer -> Disposable in
            NotificationCenter.default.addObserver(forName: Notification.wxNotification.login, object: nil, queue: nil, using: { notification in
                guard let userInfo = notification.userInfo,
                    let errcode = userInfo["errCode"] as? Int,
                    let code = userInfo["code"] as? String else {
                        Toast.show(message: "获取code失败")
                        return observer(.error(ParseError()))
                }
                switch errcode {
                case 0:
                    observer(.success(["appid": WXAppid, "secret": WXSecret,
                                       "code": code, "grant_type": "authorization_code"]))
                case -4:
                    Toast.show(message: "您拒绝授权,登录失败")
                    break
                case -2:
                    Toast.show(message: "您取消了登录,登录失败")
                    break
                default:
                    Toast.show(message: "发生未知错误,登录失败")
                    break
                }
                return observer(.error(BusinessError(id: errcode)))
            })
            return Disposables.create()
        })
    }

    fileprivate func parseWxToken(json: JSON) -> [String: String]? {
        guard let token = json["access_token"] as? String,
            let openId = json["openid"] as? String else { return nil }
        return ["access_token": token, "openid": openId]
    }
    
    fileprivate func getWXToken(param: [String: String]) -> Single<[String: String]> {
        let resource = ContentResource<[String: String]>(host: "https://api.weixin.qq.com",
                                                      path: .wxAccessToken,
                                                      parameter: param,
                                                      parseJSON: parseWxToken)
        
        return NetworkApi.share.get(resource: resource)
    }

    fileprivate func getWXUserInfo(param: [String: String]) -> Single<[String: Any]> {
        let resource = ContentResource<[String: Any]>(host: "https://api.weixin.qq.com",
                                                      path: .wxUserInfo,
                                                      parameter: param,
                                                      parseJSON: { $0 })
        return NetworkApi.share.get(resource: resource)
    }
    
    fileprivate func parseAuthorize(json: JSON) -> UserInfo? {
        guard let data = json["data"] as? [String: AnyObject] else { return nil }
        return UserInfo(json: data)
    }

    fileprivate func wxLogin(param: [String: Any]) -> Single<UserInfo> {
        let resource = ContentResource<UserInfo>(path: .authorize, parameter: param, parseJSON: parseAuthorize)
        return resource.loadContent()
    }
}