import {InvisibleComponent} from "../controller.js";

let _status = Symbol("status");

/**
 * 后台服务组件
 * @param {[type]} dataModel [description]
 */
export default class Service extends InvisibleComponent {

  constructor(__tfp, dataModel, parent) {
    super(__tfp, "Service", dataModel, parent);
    
    this[_status] = 0;
    this.cbFuncs = [];  //回调函数
  }

  //服务请求状态，0：未请求，1：正在请求，2：请求完毕
  get status() { return this[_status] }
  set status(value) {}

  //服务路径
  get path() { return this.dataModel.path }
  set path(value) {this.dataModel.path = value}

  //请求参数
  get args() { return this.dataModel.args }
  set args(value) {this.dataModel.args = value}

  //请求参数设置
  get argSettings() { return this.dataModel.argSettings }
  set argSettings(value) {this.dataModel.argSettings = value}

  //参数变化时自动重载
  get autoReload() { return this.dataModel.autoReload ? true : false }
  set autoReload(value) {this.dataModel.autoReload = value ? true : false}

  //是否自动显示错误提示
  get autoShowError() { return this.dataModel.autoShowError ? true : false }
  set autoShowError(value) {this.dataModel.autoShowError = value ? true : false}

  /**
   * 设置请求参数设置
   * @param {[type]} name  [description]
   * @param {[type]} type  [description]
   * @param {[type]} value [description]
   */
  setArgSetting(name, type, value) {
    if(!name) {
      this._tfp.showMsg("请提供参数名称！");
      return;
    }
    if(!this.dataModel.argSettings) this.dataModel.argSettings = [];
    let arg = {
      name: name
    };
    if(type) arg.type = type;
    if(value) arg.value = value;
    let isExists = false;
    for(var i=0;i<this.dataModel.argSettings.length;i++) {
      if(this.dataModel.argSettings[i].name==arg.name) {
        isExists = true;
        this.dataModel.argSettings[i].type = type;
        this.dataModel.argSettings[i].value = value;
        break;
      }
    }
    if(!isExists) this.dataModel.argSettings.push(arg);
  }

  /**
   * 删除请求参数设置
   * @param  {[type]} name [description]
   * @return {[type]}      [description]
   */
  removeArgSetting(name) {
    if(!name || !this.dataModel.argSettings) return;
    for(var i=0;i<this.dataModel.argSettings.length;i++) {
      if(this.dataModel.argSettings[i].name==arg.name) {
        this.dataModel.argSettings.splice(i, 1);
        return;
      }
    }
  }

  /**
   * 显示错误信息
   * @param  {[type]} msg [description]
   * @return {[type]}     [description]
   */
  showError(msg) {
    console.error(msg);
    if(this.dataModel.autoShowError && typeof(window) != "undefined") {
      this._tfp.showMsg(msg);
    }
    if(this.onError) {
      this.onError(msg);
    } else if(this.dataModel.onError) {
      eval(this.dataModel.onError);
    }
  }

  /**
   * 获取HTTP请求对象
   * @return {[type]}         [description]
   */
  getHttpRequest() {
    var httpRequest;
    if (window.XMLHttpRequest) {
      httpRequest = new XMLHttpRequest();
    } else if (window.ActiveXObject) {
      httpRequest = new ActiveXObject("Msxml2.XMLHTTP");
      if (!httpRequest) {
        httpRequest = new ActiveXObject("Microsoft.XMLHTTP");
      }
    }
    if (!httpRequest) {
      this.showError("您的浏览器不支持Ajax，无法执行该操作！");
      return null;
    }
    return httpRequest;
  }

  /**
   * 请求服务
   * @param  {[type]}   args 请求参数
   * @param  {Function} cb   回调函数
   */
  request(args, cb) {
    if(!this.path) {
      this.showError("请提供服务路径！");
      return;
    }
    if(cb) this.cbFuncs.push(cb);
    //如果当前服务对象正在发送请求，则不重复请求
    if(this[_status] == 1) return;
    this[_status] = 1;
    //设置请求参数
    if(!args) args = {};
    args.service = this.path;
    if(this.dataModel.args) {
      for(let p in this.dataModel.args) {
        args[p] = this.dataModel.args[p];
      }
    }
    if(this.dataModel.argSettings) {
      for(var i=0;i<this.dataModel.argSettings.length;i++) {
        let arg = this.dataModel.argSettings[i];
        if(arg.type=="QueryString") {
          if(arg.value) {
            args[arg.name] = this._tfp.getUrlArg(arg.value);
          } else {
            args[arg.name] = this._tfp.getUrlArg(arg.name);
          }
        } else if(arg.type=="ComponentVal") {
          let cpt = null;
          if(arg.value) {
            cpt = this._tfp.get(arg.value);
          } else {
            cpt = this._tfp.get(arg.name);
          }
          if(cpt) args[arg.name] = cpt.value;
        } else if(arg.type=="ComponentAttr") {
          if(arg.value && arg.value.indexOf(".")>0) {
            let cptInfo = arg.value.split(".");
            let cpt = this._tfp.get(cptInfo[0]);
            if(cpt && cptInfo[1]!="") args[arg.name] = cpt[cptInfo[1]];
          }
        } else if(arg.type=="DialogArg") {
          if(arg.value) {
            let dialogArgs = null;
            try {
              dialogArgs = JSON.parse(this._tfp.getDialogArgs());
              args[arg.name] = dialogArgs[arg.value];
            } catch(e) {
              this._tfp.showMsg(e.message);
            }
          } else {
            args[arg.name] = this._tfp.getDialogArgs();
          }
        } else if(arg.type=="Expression") {
          //TODO
        } else {
          args[arg.name] = arg.value;
        }
      }
    }

    //是否终止请求，如果服务请求有关的事件处理函数返回true
    //则表示终止请求，不再执行后续代码
    let endRequest = false;

    this.exeEventHandler("onRequest");

    //如果设置了请求前需要执行的事件处理函数，则执行该函数
    /*if(this.onRequest && typeof this.onRequest == "function") {
      endRequest = this.onRequest(args);
    } else if(this.dataModel.onRequest) {
      endRequest = eval(this.dataModel.onRequest);
      if(endRequest) return;
    }*/
    
    //设置身份验证信息
    if(typeof(top)!="undefined" && top.taskMsgAuthObj) {
      let authObj = {
        args: {}
      };
      top.taskMsgAuthObj.setAuthData(authObj);
      for(let arg in authObj.args) {
        args[arg] = authObj.args[arg];
      }
    } else if(typeof(window.parent)!="undefined" && window.parent.taskMsgAuthObj) {
      let authObj = {
        args: {}
      };
      window.parent.taskMsgAuthObj.setAuthData(authObj);
      for(let arg in authObj.args) {
        args[arg] = authObj.args[arg];
      }
    } else if(typeof(tmClient)!="undefined" 
        && ((tmClient.clientOSType=="iOS" && typeof(TMiOSClient)!="undefined")
        || (tmClient.clientOSType=="Android" && typeof(TMAndroidClient)!="undefined"))) {
      let authData = JSON.parse(tmClient.getAuthData());
      args._auth_org = authData._auth_org;
      args._auth_ts = authData._auth_ts;
      args._auth_data = authData._auth_data;
    } else {
      if(this._tfp.getUrlArg("_auth_org")) args._auth_org = this._tfp.getUrlArg("_auth_org");
      if(this._tfp.getUrlArg("_auth_ts")) args._auth_ts = this._tfp.getUrlArg("_auth_ts");
      if(this._tfp.getUrlArg("_auth_data")) args._auth_data = this._tfp.getUrlArg("_auth_data");
    }
    //console.log(args);
    
    if("undefined" != typeof top.taskBuilder) {
      var that = this;
      top.taskBuilder.requestByIPC(this.path, args, function(req, res) {
        that.onResponse(req, res);
      });
    } else {
      this.sendRequest(args);
    }
  }

  exeResponseFunc(req, res, responseFuncStr) {
    if(responseFuncStr.indexOf(".")<0 && responseFuncStr.indexOf(" ")<0
      && responseFuncStr.indexOf("=")<0 && responseFuncStr.indexOf("(")<0
      && responseFuncStr.indexOf(")")<0) {
      eval(responseFuncStr+"(req, res)");
    } else {
      eval(responseFuncStr);
    }
  }

  onResponse(req, res) {
    if (res.code == 0) {
      if(this.srcElement) req.srcElement = this.srcElement;
      if(this.cbFuncs.length>0) {
        for(var i=0; i<this.cbFuncs.length; i++) {
          this.cbFuncs[i](req, res);
        }
      }
      if(this.dataModel.onResponse && typeof(this.dataModel.onResponse)=="string") {
        this.exeResponseFunc(req, res, this.dataModel.onResponse);
      }
    } else {
      //如果是身份验证失败
      if(res.code == 501) {
        top.location = "/";
        return;
      }
      this.showError(res.message);
    }
  }

  sendRequest(args) {
    var that = this;
    var httpRequest = this.getHttpRequest();
    try {
      httpRequest.onreadystatechange = function() {
        if (httpRequest.readyState == 4) {
          that[_status] = 2;
          if (httpRequest.status == 200) {
            var response = JSON.parse(httpRequest.responseText);
            that.onResponse(args, response);
          } else if (httpRequest.status == 404) {
            that.showError("请求的服务不存在！");
          } else {
            if(httpRequest.status!==0)
              that.showError("向服务器发送请求时发生意外错误！\r\n错误代码：" + httpRequest.status);
          }
        }
      };

      var serverPath = location.toString();
      serverPath = serverPath.substr(0, serverPath.indexOf("/", 8)+1);
      httpRequest.open("POST", serverPath+"Service", true);
      httpRequest.setRequestHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
      httpRequest.send(JSON.stringify(args));
    } catch (e) {
      this.showError("向服务器发送请求时发生意外错误！\r\n错误描述：" + e.message);
    }
  }

  initRuntime() {
    let that = this;
    if(this.dataModel.argSettings && this.dataModel.autoReload) {
      for(var i=0;i<this.dataModel.argSettings.length;i++) {
        let arg = this.dataModel.argSettings[i];
        if(arg.type=="ComponentVal") {
          let cpt = null;
          if(arg.value) {
            cpt = this._tfp.get(arg.value);
          } else {
            cpt = this._tfp.get(arg.name);
          }
          if(!cpt) continue;
          if(!cpt.formulaIpts) cpt.formulaIpts = [];
          if(!cpt.formulaIpts.contains(that.id))
            cpt.formulaIpts.push(that.id);
        }
      }
    }
  }
}