import { selectLoginTypeInWxMini } from '../qq-mini/init';
import { Toast } from '../toast';
import { refreshCurrentPage } from '../utils/pages/refresh';

import { LoginMpType } from './types';
import { getAppId } from './utils';


function resetLoginStatus(showLoadingWhenLoginInMp: boolean) {
  MpLogin.isLogining = false;

  if (showLoadingWhenLoginInMp) {
    Toast.dismissLoading();
  }
}

function showLoginToast(showLoadingWhenLoginInMp: boolean) {
  if (showLoadingWhenLoginInMp) {
    Toast.showLoading('登录中...');
  }
}

function saveLoginInfoToLocal(param: any) {
  const loginInfoText = param.headers?.logininfo
  || param.headers?.Logininfo
  || param.header?.logininfo
  || param.header?.Logininfo;

  if (!loginInfoText) {
    return;
  }

  try {
    const loginInfo = JSON.parse(loginInfoText);
    if (loginInfo.uid) {
      window.sessionStorage.setItem('tip_uid', loginInfo.uid);
    }
    if (loginInfo.ouid) {
      window.sessionStorage.setItem('tip_ouid', loginInfo.ouid);
    }
    if (loginInfo.accesstoken) {
      window.sessionStorage.setItem('tip_accesstoken', loginInfo.accesstoken);
    }

    if (loginInfo.ouid) {
      localStorage.setItem('user-info-targetopenid', loginInfo.ouid);
    }
    if (loginInfo.ticket) {
      localStorage.setItem('user-info-ticket', loginInfo.ticket);
    }
    if (loginInfo.sessionId) {
      localStorage.setItem('user-info-sessionid', loginInfo.sessionId);
    }
  } catch (e) {
    console.log(`parse loginInfo e: ${JSON.stringify(e)}`);
  }
}


class MpLogin {
  public static isLogining = false;
  public static reLoginCount = 0;
  public static appId = '';
  public static loginMpType = LoginMpType.LoginMpWeixin;
  public static showLoadingWhenLoginInMp = false;
  public static isRedirectAfterLogin = false;
  public static notRefreshInMp = false;

  public static getGlobalEBus: (() => any) = () => {};

  public static login(url = '', qqOrWxCode = ''): void {
    // 最多重试3次
    // if (MpLogin.reLoginCount >= 3) {
    //   return;
    // }
    // MpLogin.reLoginCount = MpLogin.reLoginCount + 1;
    const { showLoadingWhenLoginInMp } = MpLogin;

    showLoginToast(showLoadingWhenLoginInMp);


    if (qqOrWxCode) {
      MpLogin.code2ticket(qqOrWxCode, url);
      return;
    }
    // 异常逻辑
    resetLoginStatus(showLoadingWhenLoginInMp);
  }

  /**
   * 拿code去后台换票据和openid
   * @param code 平台提供的token
   * @param url 触发登录的请求url
   */
  public static code2ticket(code: string, url: string) {
    const { showLoadingWhenLoginInMp, isRedirectAfterLogin, notRefreshInMp } = MpLogin;

    let ltype = 'tiploginwxproc';
    switch (MpLogin.loginMpType) {
      case LoginMpType.LoginMpWeixin:
        ltype = 'tiploginwxproc';
        break;
      case LoginMpType.LoginMpQQ:
        ltype = 'tiploginqqproc';
        break;
    }
    const reqUrl = url?.indexOf('?')
      ? `${url}&_ltype=${ltype}&appid=${MpLogin.appId}&code=${code}`
      : `${url}?_ltype=${ltype}&appid=${MpLogin.appId}&code=${code}`;
    console.info('code2ticket.reqUrl', reqUrl);

    uni.request({
      url: reqUrl,
      dataType: 'text',
      method: 'POST',
      success(res) {
        console.info('uni.request.res', res);

        if (res.statusCode >= 200 && res.statusCode < 300) {
          saveLoginInfoToLocal(res);
          // 清除旧账号cookie信息
          MpLogin.getGlobalEBus()?.emit('event-on-mini-program-login');

          if (!notRefreshInMp) {
            refreshCurrentPage(isRedirectAfterLogin);
          }
        }
        resetLoginStatus(showLoadingWhenLoginInMp);
      },
      fail() {
        resetLoginStatus(showLoadingWhenLoginInMp);
      },
    });
  }
}

const getLoginAppId = ({
  selectQQ,
  qqAppIdInWxMini = '',
}: {
  selectQQ: boolean,
  qqAppIdInWxMini?: string
}) => {
  if (selectQQ) {
    return qqAppIdInWxMini;
  }
  return getAppId();
};

/**
 * 获取小程序登录信息
 * @param appId 要登录的小程序appId
 * @param loginMpType 登录平台类型
 * @param url 触发登录的请求url
 */
export async function loginMp({
  url,
  getGlobalEBus,
  showLoadingWhenLoginInMp,
  isRedirectAfterLogin,
  notRefreshInMp,
  qqAppIdInWxMini,
}: {
  url: string;
  getGlobalEBus: (() => {});
  showLoadingWhenLoginInMp?: boolean;
  isRedirectAfterLogin?: boolean;
  notRefreshInMp?: boolean;
  qqAppIdInWxMini?: string;
}) {
  console.info('[loginMp] starting');
  if (MpLogin.isLogining) {
    console.info('[loginMp] return');
    return;
  }

  MpLogin.isLogining = true;

  const { selectQQ = false, qqCode = '', wxCode = '' } = await selectLoginTypeInWxMini();
  console.info('selectLoginTypeInWxMini.res', selectQQ, qqCode, wxCode);

  const loginAppId = getLoginAppId({ selectQQ, qqAppIdInWxMini });

  console.info('[loginMp] selectQQ: ', selectQQ);
  console.info('[loginMp] loginAppId: ', loginAppId);
  console.info('[loginMp] qqCode:', qqCode);
  const loginMpType = selectQQ ? LoginMpType.LoginMpQQ : LoginMpType.LoginMpWeixin;

  MpLogin.appId = loginAppId;
  MpLogin.loginMpType = loginMpType;
  MpLogin.getGlobalEBus = getGlobalEBus;
  MpLogin.showLoadingWhenLoginInMp = !!showLoadingWhenLoginInMp;
  MpLogin.isRedirectAfterLogin = !!isRedirectAfterLogin;
  MpLogin.notRefreshInMp = !!notRefreshInMp;


  return await MpLogin.login(
    url,
    qqCode || wxCode || '',
  );
}

