import LoginApi from '../api/LoginApi';

import {localStore} from 'mutants-microfx';
import {authKey,authKeys,prodProxyHost,proxyServer} from '../const/app';
import Channel from './Channel';
import {stores} from 'mutants-microfx';
import LogoutMV from '../middleware/LogoutMW';
import tools from '../util/tools';
import {destroyApp} from 'mutants-jsbridge';
import {runInAction} from 'mobx'
import {env} from 'mutants-microfx';
import _findIndex from 'lodash/findIndex'; 
const {constant,platform,browser,os} = env;
const crypto =  require('crypto');
const emptyAuth = {
   userId: '',
   orgId: '',
   accessToken: '',
   tplusToken: '',
   authorization: '',
   sid: '',
   OrganID:'',
   proxyserver: prodProxyHost,
   channel:{
    targetURL : window.localStorage.targetURL
   }
}
export default class User {

  username:string;
  password:string;
  userId:string;
  orgId:string;
  orgName:string;
  accessToken:string;
  tplusToken:string;
  authorization:string;
  sid:string;
  channel:{targetURL:string,throughProxy:boolean};
  orgList:Array<{orgId:string,orgName:string,orgFullName:string}>;
  proxyserver:string;



  //认证用户名 密码
  static async authentication(username:string,password:string):Promise<User|undefined>{
    password = User.pwdEncrypt(password);
    let auth = new User({username,password});
    let authResult = await LoginApi.authentication(auth);
    if(authResult){
      const authObj = auth.fromJS(authResult);
      return authObj;
    }
  }
  //认证用户名 密码 直接通过加密的密码进行登录的
  static async authentication2(username:string,password:string):Promise<User|undefined>{
    // password = User.pwdEncrypt(password);
    let auth = new User({username,password});
    let authResult = await LoginApi.authentication(auth);
    if(authResult){
      const authObj = auth.fromJS(authResult);
      return authObj;
    }
  }

  //修改密码
  static async updatePwd(oldPassword:string,newPassword:string){
    oldPassword = User.pwdEncrypt(oldPassword);
    newPassword = User.pwdEncrypt(newPassword);
    let updateResult = await LoginApi.updatePwd(oldPassword,newPassword);
    await runInAction(()=>{
      stores.user.options.set("password",newPassword)
    })
    
    return updateResult;
  }

  async initChannel(orgId:string){
    if(this.orgList){
       const checkOrg = this.orgList.some((org)=>{
          if(org.orgId === orgId){
            this.orgName = org.orgFullName;
            return true;
          }
       });
       if(!checkOrg){
          throw new Error(`orgId ${orgId} is out of range user orgList`);
       }
       
    }
    this.orgId = orgId;
    this.cache();    //初始化通道
    this.channel = await Channel.getChannel();
    //执行前端网关策略
    this.executeFEGatewayStrategy();
    //将会话信息缓存
    this.channel = await Channel.getChannel();
    this.cache();
  }

    //执行代理
    async executeFEGatewayStrategy(){
      try{
        const {data} = await LoginApi.getApiConfig();
        //执行代理灰度策略
        await this.executeProxyGrayStrategy(data);
        //执行云代理灰度策略
        await this.executeCloudproxyGrayStrategy(data);
      }catch(err){
        console.error('err=======',err);
      }
      
    }
  
    /**
     * 执行代理灰度策略
     * @param {*} data 配置信息
     */
    async executeProxyGrayStrategy(data){
      const {gray_filter} = data;
      const {gray_release = '',gray_domain = '',org_id=[],user_id=[],domain=[]} = gray_filter;
      if(!!gray_domain){
        switch (gray_release) {
          //全部灰度
          case 'all':
            this.proxyserver = gray_domain;
            break;
          
          //部分灰度
          case 'part':
            const isGray = _findIndex(org_id, orgId => this.orgId == orgId) > -1
                          || _findIndex(user_id, userId => this.userId == userId) > -1
                          || _findIndex(domain, dom => dom == this.channel.targetURL) > -1;
  
            if(isGray){
              this.proxyserver = gray_domain;
            }
            break;
          default:
            break;
        }
      }
    }
  
  
    /**
     * 执行云代理灰度策略
     * @param {*} data 配置信息
     */
    async executeCloudproxyGrayStrategy(data){
      const {cloudproxy_filter} = data;
      const {cloudproxy_domain = '',org_id=[],user_id=[],domain=[]} = cloudproxy_filter;
      if(!!cloudproxy_domain && !!this.channel.targetURL && this.channel.targetURL.indexOf('.chanjet.com')==-1){
            const isProxyserver = _findIndex(org_id, orgId => this.orgId == orgId) > -1
                          || _findIndex(user_id, userId => this.userId == userId) > -1
                          || _findIndex(domain, dom => dom == this.channel.targetURL) > -1;
            if(isProxyserver){
              this.channel.targetURL = proxyServer;
            }
      }
      
    }
  
  

  

  setChannel(targetURL:string){
    this.channel = Channel.setChannel(targetURL)
    this.cache();
  }

  //登录T+
  async loginTplus(param:{clientName? :string,desc? :string}){
      if(tools.isApp()&&!!window.localStorage.tplusToken){
        //移动端做共享token 基于性能优化考虑  复用token  其余登录绕过此过程
        //从ls中获取登录token信息，绕过此步骤
        this.tplusToken = window.localStorage.tplusToken;
        this.authorization = `token ${this.tplusToken}`;
        if(!!window.localStorage.sid){
          this.sid = window.window.localStorage.sid;
        }
        this.cache();
        stores.user.login(this);
        return;
      }
      let result = await LoginApi.getTplusToken(param);
      if(result.indexOf(';')>-1){
        let data = result.split(';');
        this.tplusToken = data[0];
        this.sid = data[1];
      }else{
        this.tplusToken = result;
      }
      this.authorization = `token ${this.tplusToken}`;
      this.cache();
      stores.user.login(this);
  }

  //切换账套后更新User信息
  async changeUserInfo(param:{orgName:string,orgId:string,targetURL:string,tplusToken:string}){
    if(param.tplusToken.indexOf(';')>-1){
      let data = param.tplusToken.split(';');
      this.tplusToken = data[0];
      this.sid = data[1];
    }else{
      this.tplusToken = param.tplusToken;
    }
    this.authorization = `token ${this.tplusToken}`;
    this.orgId = param.orgId;
    this.orgName = param.orgName;
    this.setChannel(param.targetURL);
    if(!!window.localStorage.sid){
      this.sid = window.window.localStorage.sid;
    }
    this.cache();
    stores.user.login(this);
}

  

  // 二维码登录，只传入userid orgid
  async QRLogin({userId, orgId}) {
    this.orgId = orgId;
    this.userId = userId;
    this.accessToken = '***';
    this.cache();
    await this.loginTplus({clientName: '扫码登录', desc: '扫码登录'});
  }

  static pwdEncrypt(password){
    let md5 = crypto.createHash('md5');
    md5.update(password);
    password = md5.digest('hex');
    return password;
  }

  constructor(obj? :object){
    if(obj){
      Object.assign(this,obj);
    }
  }

  fromJS(result){
    //获取企业信息
    var orgListInfo = result.orgListInfo;
    const orgLength = orgListInfo.orgList.length;
    if (orgLength > 0) {
      this.userId = result.user_id;
      this.accessToken = result.access_token;
      this.orgList = orgListInfo.orgList
    }
    return this;
  }

  //缓存数据
  cache(){
    localStore.set(authKey,this);
    authKeys.forEach((authKey)=>{
      if(!tools.isNull(this[authKey])){
        localStore.set(authKey,this[authKey]);
      }
    });
  }


  //恢复数据
  static restore(){
    let auth = localStore.get(authKey);
    if(auth == null || auth == undefined){
      auth = emptyAuth;
    }
    return auth;

    // const accessToken = localStore.get('accessToken');
    // if(!tools.isNull(accessToken)){
    //   let cacheObj = {};
    //   authKeys.forEach((item)=>{
    //     cacheObj[item] = localStore.get(item);
    //   });
    //   return cacheObj; 
    // }
    // return emptyAuth;
  }

  static clear(){
    if ((stores.posLoginStore || {}).savePosCode) {
      stores.posLoginStore.savePosCode(false);
    }
    User.clearLocalSession();
  }

  static clearLocalSession(){
    localStore.remove(authKey);
    authKeys.forEach((item)=>{
      localStore.remove(item);
    });
    Channel.clear();
  }

  //注销对象
  static async logout(fn? :()=>any, isdestroyApp = true) {
    await User.posLogout();//pos注销
    LogoutMV.execute();
    User.clear();
    fn && fn();
    // 用户退出不用调用history，门户可以通过用户状态判断显示登录页面
    if(stores.user){
      stores.user.logout();
    }
    await User.mobileLogout(isdestroyApp);//移动端注销
  }

  //移动端注销
  static async mobileLogout(isdestroyApp = true){
    //移动端的场景
    //轻应用 与 微信
    if(tools.isApp() || platform === constant.platform.weixin ){
      //清空store中的用户信息
      if(stores.user){
        stores.user.logout();
      }
      if(isdestroyApp){
        destroyApp();
      }
     
    }
  }

  //pos端注销
  static async posLogout(){
    const {posIsLogin} = stores.posLoginStore || {};
    posIsLogin && await LoginApi.logout();
  }

  //通过一次性码登录CIA
  static async loginByAuthcode(authCode:string){
    let authResult = await LoginApi.authenticationByCode(authCode);
    return authResult;
  }

  //判断用户是否登录
  static isLogined():boolean{
    const user = User.restore();
    if(tools.isNull(user.accessToken)||tools.isNull(user.userId)||tools.isNull(user.orgId)){
      return false;
    }
    return true;
  }

}
