
import { fetcher } from '@cloudron/pankow';
import { API_ORIGIN } from '../constants.js';

function create() {
  const accessToken = localStorage.token;

  return {
    async list() {
      const perPage = 5000;

      let page = 1;
      let users = [];

      while (true) {
        let result;
        try {
          result = await fetcher.get(`${API_ORIGIN}/api/v1/users`, { page, per_page: perPage, access_token: accessToken });
        } catch (e) {
          return [e];
        }

        if (result.status !== 200) return [result];

        users = users.concat(result.body.users);

        if (result.body.users.length < perPage) break;

        page++;
      }

      users.forEach(u => {
        u.avatarUrl = `${API_ORIGIN}/api/v1/users/${u.id}/avatar?access_token=${accessToken}`;
      });

      return [null, users];
    },
    async add(user) {
      const data = {
        email: user.email,
        fallbackEmail: user.fallbackEmail,
        displayName: user.displayName,
        role: user.role
      };

      if (user.username) data.username = user.username;
      if (user.password) data.password = user.password;

      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users`, data, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 201) return [result];

      result.body.avatarUrl = `https://${API_ORIGIN}/api/v1/users/${user.id}/avatar?access_token=${accessToken}`;

      return [null, result.body];
    },
    async update(id, data) {
      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/profile`, data, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];

      return [null];
    },
    async remove(id) {
      let result;
      try {
        result = await fetcher.del(`${API_ORIGIN}/api/v1/users/${id}`, null, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async setLocalGroups(id, groupIds) {
      let result;
      try {
        result = await fetcher.put(`${API_ORIGIN}/api/v1/users/${id}/groups`, { groupIds }, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async setRole(id, role) {
      let result;
      try {
        result = await fetcher.put(`${API_ORIGIN}/api/v1/users/${id}/role`, { role }, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async setActive(id, active) {
      let result;
      try {
        result = await fetcher.put(`${API_ORIGIN}/api/v1/users/${id}/active`, { active }, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async setAvatar(id, file) {
      const fd = new FormData();
      fd.append('avatar', file);

      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/avatar`, fd, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async unsetAvatar(id) {
      let result;
      try {
        result = await fetcher.del(`${API_ORIGIN}/api/v1/users/${id}/avatar`, null, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async setGhost(id, password, expiresAt = 0) {
      const data = { password };

      if (expiresAt) data.expiresAt = expiresAt;

      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/ghost`, data, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 204) return [result];
      return [null];
    },
    async getPasswordResetLink(id) {
      let result;
      try {
        result = await fetcher.get(`${API_ORIGIN}/api/v1/users/${id}/password_reset_link`, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 200) return [result];
      return [null, result.body.passwordResetLink];
    },
    async sendPasswordResetEmail(id, email) {
      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/send_password_reset_email`, { email }, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 202) return [result];
      return [null];
    },
    async sendInviteEmail(id, email) {
      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/send_invite_email`, { email }, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 202) return [result];
      return [null];
    },
    async inviteLink(id) {
      let result;
      try {
        result = await fetcher.get(`${API_ORIGIN}/api/v1/users/${id}/invite_link`, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 200) return [result];
      return [null, result.body.inviteLink];
    },
    async disableTotp(id) {
      let result;
      try {
        result = await fetcher.post(`${API_ORIGIN}/api/v1/users/${id}/totp_disable`, {}, { access_token: accessToken });
      } catch (e) {
        return [e];
      }

      if (result.status !== 200) return [result];
      return [null];
    },
  };
}

export default {
  create,
};
