text: import * as sdk from 'matrix-js-sdk';
  import cons from '../state/cons';
  import { getBaseUrl } from '../../util/matrixUtil';
  
  async function login(username, homeserver, password) {
    let baseUrl = null;
    try {
      baseUrl = await getBaseUrl(homeserver);
    } catch (e) {
      baseUrl = `https://${homeserver}`;
    }
  
    if (typeof baseUrl === 'undefined') throw new Error('Homeserver not found');
  
    const client = sdk.createClient({ baseUrl });
  
    const response = await client.login('m.login.password', {
      user: `@${username}:${homeserver}`,
      password,
      initial_device_display_name: cons.DEVICE_DISPLAY_NAME,
    });
  
    localStorage.setItem(cons.secretKey.ACCESS_TOKEN, response.access_token);
    localStorage.setItem(cons.secretKey.DEVICE_ID, response.device_id);
    localStorage.setItem(cons.secretKey.USER_ID, response.user_id);
    localStorage.setItem(cons.secretKey.BASE_URL, response?.well_known?.['m.homeserver']?.base_url || baseUrl);
  }
  
  async function getAdditionalInfo(baseUrl, content) {
    try {
      const res = await fetch(`${baseUrl}/_matrix/client/r0/register`, {
        method: 'POST',
        body: JSON.stringify(content),
        headers: {
          'Content-Type': 'application/json; charset=utf-8',
        },
        credentials: 'same-origin',
      });
      const data = await res.json();
      return data;
    } catch (e) {
      throw new Error(e);
    }
  }
  async function verifyEmail(baseUrl, content) {
    try {
      const res = await fetch(`${baseUrl}/_matrix/client/r0/register/email/requestToken           `, {
        method: 'POST',
        body: JSON.stringify(content),
        headers: {
          'Content-Type': 'application/json; charset=utf-8',
        },
        credentials: 'same-origin',
      });
      const data = await res.json();
      return data;
    } catch (e) {
      throw new Error(e);
    }
  }
  
  let session = null;
  let clientSecret = null;
  let sid = null;
  async function register(username, homeserver, password, email, recaptchaValue, terms, verified) {
    const baseUrl = await getBaseUrl(homeserver);
  
    if (typeof baseUrl === 'undefined') throw new Error('Homeserver not found');
  
    const client = sdk.createClient({ baseUrl });
  
    const isAvailable = await client.isUsernameAvailable(username);
    if (!isAvailable) throw new Error('Username not available');
  
    if (typeof recaptchaValue === 'string') {
      await getAdditionalInfo(baseUrl, {
        auth: {
          type: 'm.login.recaptcha',
          session,
          response: recaptchaValue,
        },
      });
    } else if (terms === true) {
      await getAdditionalInfo(baseUrl, {
        auth: {
          type: 'm.login.terms',
          session,
        },
      });
    } else if (verified !== true) {
      session = null;
      clientSecret = client.generateClientSecret();
      const verifyData = await verifyEmail(baseUrl, {
        email,
        client_secret: clientSecret,
        send_attempt: 1,
      });
      if (typeof verifyData.error === 'string') {
        throw new Error(verifyData.error);
      }
      sid = verifyData.sid;
    }
  
    const additionalInfo = await getAdditionalInfo(baseUrl, {
      auth: { session: (session !== null) ? session : undefined },
    });
    session = additionalInfo.session;
    if (typeof additionalInfo.completed === 'undefined' || additionalInfo.completed.length === 0) {
      return ({
        type: 'recaptcha',
        public_key: additionalInfo.params['m.login.recaptcha'].public_key,
      });
    }
    if (additionalInfo.completed.find((process) => process === 'm.login.recaptcha') === 'm.login.recaptcha'
      && !additionalInfo.completed.find((process) => process === 'm.login.terms')) {
      return ({
        type: 'terms',
        en: additionalInfo.params['m.login.terms'].policies.privacy_policy.en,
      });
    }
    if (verified || additionalInfo.completed.find((process) => process === 'm.login.terms') === 'm.login.terms') {
      const tpc = {
        client_secret: clientSecret,
        sid,
      };
      const verifyData = await getAdditionalInfo(baseUrl, {
        auth: {
          session,
          type: 'm.login.email.identity',
          threepidCreds: tpc,
          threepid_creds: tpc,
        },
        username,
        password,
      });
      if (verifyData.errcode === 'M_UNAUTHORIZED') {
        return { type: 'email' };
      }
  
      localStorage.setItem(cons.secretKey.ACCESS_TOKEN, verifyData.access_token);
      localStorage.setItem(cons.secretKey.DEVICE_ID, verifyData.device_id);
      localStorage.setItem(cons.secretKey.USER_ID, verifyData.user_id);
      localStorage.setItem(cons.secretKey.BASE_URL, baseUrl);
      return { type: 'done' };
    }
    return {};
  }
  
  export { login, register };
  