'use strict';

const crypto = require('crypto')
const axios = require('axios')
const log = require('electron-xlog');

module.exports = {
    _sdk_app_id: 0,
    _user_id: '',
    _domain: '',
    _token: '',
    _user_info_map: [],

    /** 导出接口 */
    init: function(debug, sdkAppId = 0, userId = '', token = ''){
        if (debug){
            this._domain = 'https://cs.api.qcloud.com';
        }else{
            this._domain = 'https://iclass.api.qcloud.com';
        }
        this._sdk_app_id = sdkAppId;
        this._user_id = userId;
        this._token = token;
        this._log("[TAG-CLIENT] init->sdkappid: "+sdkAppId+", userId: "+userId+", token: "+token+", debug:"+debug);
    },
    /** 获取内部token */
    getToken: function(){
        return this._token;
    },
    /** Demo接口 */
    initInfo: function(classId, nickName, demoType, callback){
        var data = JSON.stringify({
            class_id: classId,
            nickname: nickName,
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            demo_name: demoType
        });
        var reqUrl = this._domain + '/demo/v1/init?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&random=' 
            + Math.floor(Math.random() * 10000) + '&sign=' + this._calcSign(data);

        this._log('[TAG-CLIENT] initInfo->url: ' + reqUrl);
        this._log('[TAG-CLIENT] initInfo->req: ' + data);

        this._post({url: reqUrl, data: data}, (ret, json) => {
            if (ret) this._token = json.token;
            callback(ret, json);
        })
    },
    /** 企业模块 */
    getCompanyInfo: function (companyId, callback) {
        var id = parseInt(companyId)
        var data = JSON.stringify({
          enterprise_id: id
        })
        var reqUrl = this._domain + '/saas/v1/business/base/info?random=' + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] getCompanyInfo->url: ' + reqUrl);
        this._log('[TAG-CLIENT] getCompanyInfo->req: ' + data);
    
        this._post({url: reqUrl, data: data}, (ret, json) => {
          if (ret) this._sdk_app_id = json.sdkappid;
          callback(ret, json);
        }, "getCompanyInfo")
    },
    /** 帐号模块 */
    getUserSig:  function (userId, password, callback) {
        this._user_id = userId;

        var data = JSON.stringify({
            password: password,
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            role: 'student'
        });
        var reqUrl = this._domain + '/saas/v1/user/login?sdkappid=' + this._sdk_app_id + '&user_id=' + userId + '&random=' 
            + Math.floor(Math.random() * 10000) + '&sign=' + this._calcSign(data);

        this._log('[TAG-CLIENT] getUserSig->url: ' + reqUrl);
        this._log('[TAG-CLIENT] getUserSig->req: ' + data);

        this._post({url: reqUrl, data: data}, (ret, json) => {
            if (ret) this._token = json.token;
            callback(ret, json);
        }, "getUserSig")
    },
    getQuickUserNick: function(userId){
        if (null != this._user_info_map[userId]){
            return this._user_info_map[userId].nickname;
        }else{
            this.getUserInfo(userId, (ret, json)=>{});
            return userId;
        }
    },
    getUserInfo: function(userId, callback){
        if (null != this._user_info_map[userId]){
            callback(true, this._user_info_map[userId]);
            return;
        }

        var data = JSON.stringify({
          user_id: ""+userId
        });

        var reqUrl = this._domain + '/saas/v1/user/info?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random=' 
            + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] getUserInfo->url: ' + reqUrl);
        this._log('[TAG-CLIENT] getUserInfo->req: ' + data);

        this._post({url: reqUrl, data: data}, (ret, json) => {
            if (ret){
                this._user_info_map[userId] = json.user_info;
            }
            callback(ret, json.user_info);
        }, "getUserInfo")
    },
    getGuestInfo: function(classId, nick, callback){
        var data = JSON.stringify({
            class_id: classId,
            nickname: nick
          });
  
          var reqUrl = this._domain + '/saas/v1/user/visitor/get?random=' 
              + Math.floor(Math.random() * 10000) + '&sign=' + this._calcSign(data);;
  
          this._log('[TAG-CLIENT] getGuestInfo->url: ' + reqUrl);
          this._log('[TAG-CLIENT] getGuestInfo->req: ' + data);
  
          this._post({url: reqUrl, data: data}, callback, "getGuestInfo");
    },
    /** 版本检测 */
    checkVersion: function(companyId, curVersion, callback){
        var data = JSON.stringify({
            enterprise_id: companyId,
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            local_version: curVersion
        });
        var reqUrl = this._domain + '/saas/v1/client/check/update?random=' 
            + Math.floor(Math.random() * 10000) + '&sign=' + this._calcSign(data);

        this._log('[TAG-CLIENT] checkVersion->url: ' + reqUrl);
        this._log('[TAG-CLIENT] checkVersion->req: ' + data);

        this._post({url: reqUrl, data: data}, (ret, json) => {
            callback(ret, json);
        }, "checkVersion")
    },
    /** 课堂模块 */
    getClassList: function(index, size, statuses, callback){
        var data = JSON.stringify({
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            index: index,
            size: size,
            create_time_desc: true,
            class_status: statuses
        })

        var reqUrl = this._domain + '/saas/v1/class/list?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random=' 
            + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] getClassInfo->url: ' + reqUrl)
        this._log('[TAG-CLIENT] getClassInfo->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "getClassList");
    },
    getPublicClassList: function(index, size, statuses, callback){
        var data = JSON.stringify({
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            index: index,
            size: size,
            create_time_desc: true,
            class_status: statuses
        })

        var reqUrl = this._domain + '/saas/v1/class/public/list?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random=' 
            + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] getPublicClassList->url: ' + reqUrl)
        this._log('[TAG-CLIENT] getPublicClassList->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "getPublicClassList");
    },
    getClassInfo: function (class_id, callback) {
        var data = JSON.stringify({
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            class_id: class_id
        })

        var reqUrl = this._domain + '/saas/v1/class/info?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random=' 
            + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] getClassInfo->url: ' + reqUrl)
        this._log('[TAG-CLIENT] getClassInfo->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "getClassInfo");
    },    
    startClass: function(class_id, callback){
        var data = JSON.stringify({
            class_id: class_id
        });

        var reqUrl = this._domain + '/saas/v1/class/start?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
            + Math.floor(Math.random() * 10000);
        
        this._log('[TAG-CLIENT] startClass->url: ' + reqUrl)
        this._log('[TAG-CLIENT] startClass->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "startClass");
    },
    endClass: function(class_id, callback){
        var data = JSON.stringify({
            class_id: class_id
        });

        var reqUrl = this._domain + '/saas/v1/class/stop?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
            + Math.floor(Math.random() * 10000);
        
        this._log('[TAG-CLIENT] endClass->url: ' + reqUrl)
        this._log('[TAG-CLIENT] endClass->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "endClass");
    },
    /** 成员模块 */
    enterClass: function(class_id, class_token, callback){
        var dataMap = {
            platform: (process.platform != 'darwin') ? 'PC' : 'Mac',
            class_id: class_id
        }
        if (class_token && class_token.length > 0){
            dataMap.password = class_token;
        }
        var data = JSON.stringify(dataMap);

        var reqUrl = this._domain + '/saas/v1/member/join?sdkappid=' + this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random=' 
            + Math.floor(Math.random() * 10000);

        this._log('[TAG-CLIENT] enterClass->url: ' + reqUrl)
        this._log('[TAG-CLIENT] enterClass->req: ' + data)

        this._post({url: reqUrl, data: data}, callback, "enterClass");
    },
    quitClass: function(class_id, callback){
        var data = JSON.stringify({
          class_id: class_id
        });

        var reqUrl = this._domain + '/saas/v1/member/quit?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
            + Math.floor(Math.random() * 10000);

        log.info("[TAG-BUS] quitClass->url: "+reqUrl);
        log.info("[TAG-BUS] quitClass->req: "+data);
        
        this._post({url: reqUrl, data: data}, callback, "quitClass");
    },
    getMemberList: function(classId, index, callback){
        var data = JSON.stringify({
          class_id: classId,
          index: index
        });

        var reqUrl = this._domain + '/saas/v1/member/runtime/list?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
            + Math.floor(Math.random() * 10000);

        log.info("[TAG-BUS] getMemberList->url: "+reqUrl);
        log.info("[TAG-BUS] getMemberList->req: "+data);
        
        this._post({url: reqUrl, data: data}, callback, "getMemberList");
    },
    /** 状态上报 */
    reportEvent: function(class_id, event, data, callback=null){
        var data = JSON.stringify({
          class_id: class_id,
          event: event,
          data: data
        });

        var reqUrl = this._domain + '/saas/v1/report/event?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
            + Math.floor(Math.random() * 10000);

        log.info("[TAG-BUS] reportEvent->url: "+reqUrl);
        log.info("[TAG-BUS] reportEvent->req: "+data);

        this._post({url: reqUrl, data: data}, (ret, json)=>{
            if (null != callback){
                callback(ret, json);
            }
        }, "reportEvent");
    },
    /** 签到模块 */
    getCheckInResult: function(classId, checkId, callback){
        var data = JSON.stringify({
            class_id: classId,
            check_id: checkId
          });
  
          var reqUrl = this._domain + '/saas/v1/checkIn/result?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] getCheckInResult->url: "+reqUrl);
          log.info("[TAG-BUS] getCheckInResult->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "getCheckInResult");
    },
    udpateStudentCheckin: function(classId, checkId, userid, callback){
        var data = JSON.stringify({
            class_id: classId,
            check_id: checkId,
            check_in_member:userid
          });
  
          var reqUrl = this._domain + '/saas/v1/checkIn/info?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] getCheckInResult->url: "+reqUrl);
          log.info("[TAG-BUS] getCheckInResult->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "udpateStudentCheckin");
    },
    /** 答题模块 */
    createQuestion: function(classId, questionId, options, answer, callback){
        var data = JSON.stringify({
            class_id: classId,
            question_id: questionId,
            options, options,
            correct_answer: answer
          });
  
          var reqUrl = this._domain + '/saas/v1/question/launch?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] createQuestion->url: "+reqUrl);
          log.info("[TAG-BUS] createQuestion->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "createQuestion");
    },
    commitAnswer: function(classId, questionId, selection, callback){
        var data = JSON.stringify({
            class_id: classId,
            question_id: questionId,
            reply_id: this._user_id,
            reply_select: selection
          });
  
          var reqUrl = this._domain + '/saas/v1/question/reply?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] commitAnswer->url: "+reqUrl);
          log.info("[TAG-BUS] commitAnswer->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "commitAnswer");
    },
    queryQuestionResult: function(classId, questionId, callback){
        var data = JSON.stringify({
            class_id: classId,
            question_id: questionId
          });
  
          var reqUrl = this._domain + '/saas/v1/question/result?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] queryQuestionResult->url: "+reqUrl);
          log.info("[TAG-BUS] queryQuestionResult->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "queryQuestionResult");
    },
    queryQuestionInfo: function(classId, questionId, replyId, callback){
        var data = JSON.stringify({
            class_id: classId,
            question_id: questionId,
            reply_id: replyId
          });
  
          var reqUrl = this._domain + '/saas/v1/question/info?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] queryQuestionInfo->url: "+reqUrl);
          log.info("[TAG-BUS] queryQuestionInfo->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "queryQuestionInfo");
    },
    cancelQuestion(classId, questionId, action, callback){
        var data = JSON.stringify({
            class_id: classId,
            question_id: questionId,
            action: action
          });
  
          var reqUrl = this._domain + '/saas/v1/question/cancel?sdkappid=' +this._sdk_app_id + '&user_id=' + this._user_id + '&token=' + this._token + '&random='
              + Math.floor(Math.random() * 10000);
  
          log.info("[TAG-BUS] cancelQuestion->url: "+reqUrl);
          log.info("[TAG-BUS] cancelQuestion->req: "+data);
  
          this._post({url: reqUrl, data: data}, callback, "cancelQuestion");
    },

    /** 测试 */
    _log: function(msg){
        log.info(msg);
    },
    _err: function(msg){
        log.error(msg);
    },
    
    /** 通用接口 */
    _calcSign: function (data) {
        return crypto.createHash('md5').update(data).digest('hex');
    },

    _post: function (option, callback, name="post") {
        option.headers = {'Content-Type': 'application/json'};
        option.method = 'POST';
        axios(option).then((rsp) => {
            this._log('[TAG-CLIENT] '+name+'->rsp: ' + JSON.stringify(rsp.data, null, 2));
            callback(rsp.data && rsp.data.error_code == 0, rsp.data);
        }).catch((err) => {
            this._err('[TAG-CLIENT] '+name+'->fail: '+ err.stack);
            callback(false, err.message);
        })
    }
}