export default function BaasSDK() {
  this._baseurl = "https://mkdlabs.com";
  this._project_id = "manaknight";
  this._baas_project_id = "manaknight";
  this._secret = "5fchxn5m8hbo6jcxiq3xddofodoacskye1";
  this._baas_secret = "5fchxn5m8hbo6jcxiq3xddofodoacskye1";
  this.fe_baseurl = "http://localhost:3000";
  // this._baseurl = "http://localhost:3048";

  this._table = "";
  this._custom = "";
  this._method = "";

  const raw = this._project_id + ":" + this._secret;
  let base64Encode = btoa(raw);

  this.getHeader = function () {
    return {
      Authorization: "Bearer " + localStorage.getItem("token"),
      "x-project": base64Encode,
    };
  };

  this.baseUrl = function () {
    return this._baseurl;
  };

  this.setTable = function (table) {
    this._table = table;
  };

  this.setProjectId = function (project_id) {
    this._project_id = project_id;
  };

  this.getProjectId = function () {
    return this._project_id;
  };

  this.setSecret = function (secret) {
    this._secret = secret;
  };

  this.getSecret = function () {
    return this._secret;
  };

  this.getProfile = async function () {
    const result = await fetch(this._baseurl + "/v2/api/lambda/profile", {
      method: "get",
      headers: {
        "Content-Type": "application/json",
        "x-project": base64Encode,
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    const json = await result.json();

    if (result.status === 401) {
      throw new Error(json.message);
    }

    if (result.status === 403) {
      throw new Error(json.message);
    }
    return json;
  };

  this.getSchemaTables = async function (projectId) {
    let raw = this._project_id + ":" + this._secret;
    let url = this._baseurl + "/v1/api/schema/table";
    if (projectId) {
      url = url + "?project_id=" + projectId;
    }
    let base64EncodeText = btoa(raw);
    const result = await fetch(url, {
      method: "get",
      headers: {
        "Content-Type": "application/json",
        "x-project": base64EncodeText,
        Authorization: "Bearer " + localStorage.getItem("token"),
      },
    });
    const json = await result.json();

    if (result.status === 401) {
      throw new Error(json.message);
    }

    if (result.status === 403) {
      throw new Error(json.message);
    }
    return json;
  };

  this.callRestAPI = async function (payload, method) {
    const header = {
      "Content-Type": "application/json",
      "x-project": base64Encode,
      Authorization: "Bearer " + localStorage.getItem("token"),
    };

    switch (method) {
      case "GET":
        const getResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/GET`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonGet = await getResult.json();

        if (getResult.status === 401) {
          throw new Error(jsonGet.message);
        }

        if (getResult.status === 403) {
          throw new Error(jsonGet.message);
        }
        return jsonGet;
      case "POST":
        const insertResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonInsert = await insertResult.json();

        if (insertResult.status === 401) {
          throw new Error(jsonInsert.message);
        }

        if (insertResult.status === 403) {
          throw new Error(jsonInsert.message);
        }
        return jsonInsert;
      case "PUT":
        const updateResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonUpdate = await updateResult.json();

        if (updateResult.status === 401) {
          throw new Error(jsonUpdate.message);
        }

        if (updateResult.status === 403) {
          throw new Error(jsonUpdate.message);
        }
        return jsonUpdate;
      case "DELETE":
        const deleteResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonDelete = await deleteResult.json();

        if (deleteResult.status === 401) {
          throw new Error(jsonDelete.message);
        }

        if (deleteResult.status === 403) {
          throw new Error(jsonDelete.message);
        }
        return jsonDelete;
      case "DELETEALL":
        const deleteAllResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonDeleteAll = await deleteAllResult.json();

        if (deleteAllResult.status === 401) {
          throw new Error(jsonDeleteAll.message);
        }

        if (deleteAllResult.status === 403) {
          throw new Error(jsonDeleteAll.message);
        }
        return jsonDeleteAll;
      case "GETALL":
        const getAllResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonGetAll = await getAllResult.json();

        if (getAllResult.status === 401) {
          throw new Error(jsonGetAll.message);
        }

        if (getAllResult.status === 403) {
          throw new Error(jsonGetAll.message);
        }
        return jsonGetAll;
      case "PAGINATE":
        if (!payload.page) {
          payload.page = 1;
        }
        if (!payload.limit) {
          payload.limit = 10;
        }
        const paginateResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonPaginate = await paginateResult.json();

        if (paginateResult.status === 401) {
          throw new Error(jsonPaginate.message);
        }

        if (paginateResult.status === 403) {
          throw new Error(jsonPaginate.message);
        }
        return jsonPaginate;
      case "CURSORPAGINATE":
        if (!payload.page) {
          payload.page = 1;
        }
        if (!payload.limit) {
          payload.limit = 10;
        }
        const cursorPaginateResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const cursorJsonPaginate = await cursorPaginateResult.json();

        if (cursorPaginateResult.status === 401) {
          throw new Error(cursorJsonPaginate.message);
        }

        if (cursorPaginateResult.status === 403) {
          throw new Error(cursorJsonPaginate.message);
        }
        return cursorJsonPaginate;
      case "AUTOCOMPLETE":
        const autocompleteResult = await fetch(
          this._baseurl + `/v1/api/rest/${this._table}/${method}`,
          {
            method: "post",
            headers: header,
            body: JSON.stringify(payload),
          }
        );
        const jsonAutocomplete = await autocompleteResult.json();

        if (autocompleteResult.status === 401) {
          throw new Error(jsonAutocomplete.message);
        }

        if (autocompleteResult.status === 403) {
          throw new Error(jsonAutocomplete.message);
        }
        return jsonAutocomplete;
      default:
        break;
    }
  };

  this.createDBModel = async function ( projectID, projectSecret, table, payload ) {
    let raw = projectID + ":" + projectSecret;
    let url = this._baseurl + "/v1/api/baas/create_table";
    
    let base64EncodeText = btoa( raw );
    const result = await fetch( url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-project": base64EncodeText,
        Authorization: "Bearer " + localStorage.getItem( "token" ),
      },
      body: JSON.stringify({
        table: table,
        payload: payload
      })
    } );
    const json = await result.json();

    if ( result.status === 401 ) {
      throw new Error( json.message );
    }

    if ( result.status === 403 ) {
      throw new Error( json.message );
    }
    return json;
  };

  this.alterDBModel = async function ( projectID, projectSecret, table, payload ) {
    let raw = projectID + ":" + projectSecret;
    let url = this._baseurl + "/v1/api/baas/alter_table";
    
    let base64EncodeText = btoa( raw );
    const result = await fetch( url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-project": base64EncodeText,
        Authorization: "Bearer " + localStorage.getItem( "token" ),
      },
      body: JSON.stringify({
        table: table,
        payload: payload
      })
    } );
    const json = await result.json();

    if ( result.status === 401 ) {
      throw new Error( json.message );
    }

    if ( result.status === 403 ) {
      throw new Error( json.message );
    }
    return json;
  };

  this.dropDBModel = async function ( projectID, projectSecret, table ) {
    let raw = projectID + ":" + projectSecret;
    let url = this._baseurl + "/v1/api/baas/delete_table";
    
    let base64EncodeText = btoa( raw );
    const result = await fetch( url, {
      method: "POST",
      headers: {
        "Content-Type": "application/json",
        "x-project": base64EncodeText,
        Authorization: "Bearer " + localStorage.getItem( "token" ),
      },
      body: JSON.stringify({
        table: table
      })
    } );
    const json = await result.json();

    if ( result.status === 401 ) {
      throw new Error( json.message );
    }

    if ( result.status === 403 ) {
      throw new Error( json.message );
    }
    return json;
  };


  return this;
}
