function data(res) {
  return res?.data ?? res;
}

export async function forTweet(tweetId) {
  if (!tweetId) throw new Error("forTweet requires a tweetId");
  return data(await this.graphql("BirdwatchFetchNotes", { variables: { tweet_id: tweetId } }));
}

export async function get(noteId) {
  if (!noteId) throw new Error("get requires a noteId");
  const res = await this.graphql("BirdwatchFetchOneNote", { variables: { note_id: noteId } });
  return res?.data?.birdwatch_note_by_rest_id ?? res;
}

export async function translation(noteId, opts = {}) {
  if (!noteId) throw new Error("translation requires a noteId");
  return data(
    await this.graphql("BirdwatchFetchNoteTranslation", {
      variables: { note_id: noteId, ...opts.variables },
    }),
  );
}

export async function myProfile() {
  const res = await this.graphql("BirdwatchFetchAuthenticatedUserProfile", { variables: {} });
  return res?.data?.authenticated_user_birdwatch_profile ?? res;
}

export async function profile(alias) {
  if (!alias) throw new Error("profile requires an alias");
  const res = await this.graphql("BirdwatchFetchBirdwatchProfile", { variables: { alias } });
  return res?.data?.birdwatch_profile_by_alias ?? res;
}

export async function contributorNotes(alias, opts = {}) {
  if (!alias) throw new Error("contributorNotes requires an alias");
  return data(
    await this.graphql("BirdwatchFetchContributorNotesSlice", {
      variables: { alias, cursor: opts.cursor, ...opts.variables },
    }),
  );
}

export async function globalTimeline(opts = {}) {
  return data(
    await this.graphql("BirdwatchFetchGlobalTimeline", {
      variables: { cursor: opts.cursor, ...opts.variables },
    }),
  );
}

export async function batSignal(tweetId) {
  if (!tweetId) throw new Error("batSignal requires a tweetId");
  return data(await this.graphql("BirdwatchFetchBatSignal", { variables: { tweet_id: tweetId } }));
}

export async function canBeMediaNote(tweetId) {
  if (!tweetId) throw new Error("canBeMediaNote requires a tweetId");
  return data(
    await this.graphql("BirdwatchFetchCanTweetBeMediaNote", { variables: { tweetId } }),
  );
}

export async function clusterData(tweetId) {
  if (!tweetId) throw new Error("clusterData requires a tweetId");
  return data(await this.graphql("BirdwatchFetchClusterData", { variables: { tweetId } }));
}

export async function mediaMatches(tweetId, opts = {}) {
  if (!tweetId) throw new Error("mediaMatches requires a tweetId");
  return data(
    await this.graphql("BirdwatchFetchMediaMatchSlice", {
      variables: { tweet_id: tweetId, cursor: opts.cursor, ...opts.variables },
    }),
  );
}

export async function prominentMediaMatches(tweetId, opts = {}) {
  if (!tweetId) throw new Error("prominentMediaMatches requires a tweetId");
  return data(
    await this.graphql("BirdwatchFetchProminentMediaMatchSlice", {
      variables: { tweet_id: tweetId, cursor: opts.cursor, ...opts.variables },
    }),
  );
}

export async function sourceLinks(tweetId, opts = {}) {
  if (!tweetId) throw new Error("sourceLinks requires a tweetId");
  return data(
    await this.graphql("BirdwatchFetchSourceLinkSlice", {
      variables: { tweet_id: tweetId, cursor: opts.cursor, ...opts.variables },
    }),
  );
}

export async function sourceLinkTweet(tweetId) {
  if (!tweetId) throw new Error("sourceLinkTweet requires a tweetId");
  return data(await this.graphql("BirdwatchFetchSourceLinkTweet", { variables: { tweetId } }));
}

export async function authenticatedMatch(noteId) {
  if (!noteId) throw new Error("authenticatedMatch requires a noteId");
  return data(
    await this.graphql("BirdwatchFetchAuthenticatedBirdwatchMatchSlice", {
      variables: { note_id: noteId },
    }),
  );
}

export async function aliasOptions() {
  return data(await this.graphql("BirdwatchFetchAliasSelfSelectOptions", { variables: {} }));
}

export async function aliasStatus() {
  const res = await this.graphql("BirdwatchFetchAliasSelfSelectStatus", { variables: {} });
  return res?.data?.authenticated_user_birdwatch_alias_self_select_status ?? res;
}

export async function publicData() {
  const res = await this.graphql("BirdwatchFetchPublicData", { variables: {} });
  return res?.data?.birdwatch_latest_public_data_file_bundle ?? res;
}

export async function signUpEligibility() {
  const res = await this.graphql("BirdwatchFetchSignUpEligiblity", { variables: {} });
  return res?.data?.birdwatch_sign_up_eligibility ?? res;
}

export async function suggestionFeedback(suggestionId) {
  if (!suggestionId) throw new Error("suggestionFeedback requires a suggestionId");
  return data(
    await this.graphql("BirdwatchFetchSuggestionFeedbackOverview", {
      variables: { suggestionId },
    }),
  );
}

export async function create(tweetId, dataV1, opts = {}) {
  if (!tweetId) throw new Error("create requires a tweetId");
  if (!dataV1) throw new Error("create requires a data_v1 note payload");
  return await this.graphql("BirdwatchCreateNote", {
    body: { variables: { tweet_id: tweetId, data_v1: dataV1, ...opts.variables } },
  });
}

export async function remove(noteId) {
  if (!noteId) throw new Error("remove requires a noteId");
  return await this.graphql("BirdwatchDeleteNote", { body: { variables: { note_id: noteId } } });
}

export async function rate(noteId, rating = {}) {
  if (!noteId) throw new Error("rate requires a noteId");
  return await this.graphql("BirdwatchCreateRating", {
    body: { variables: { note_id: noteId, ...rating } },
  });
}

export async function deleteRating(noteId) {
  if (!noteId) throw new Error("deleteRating requires a noteId");
  return await this.graphql("BirdwatchDeleteRating", {
    body: { variables: { note_id: noteId } },
  });
}

export async function appeal(noteId, opts = {}) {
  if (!noteId) throw new Error("appeal requires a noteId");
  return await this.graphql("BirdwatchCreateAppeal", {
    body: { variables: { note_id: noteId, ...opts.variables } },
  });
}

export async function request(tweetId) {
  if (!tweetId) throw new Error("request requires a tweetId");
  return await this.graphql("BirdwatchCreateBatSignal", {
    body: { variables: { tweet_id: tweetId } },
  });
}

export async function deleteRequest(tweetId) {
  if (!tweetId) throw new Error("deleteRequest requires a tweetId");
  return await this.graphql("BirdwatchDeleteBatSignal", {
    body: { variables: { tweet_id: tweetId } },
  });
}

export async function selectAlias(opts = {}) {
  return await this.graphql("BirdwatchAliasSelect", { body: { variables: { ...opts.variables } } });
}

export async function editNotificationSettings(params = {}) {
  return await this.graphql("BirdwatchEditNotificationSettings", {
    body: { variables: { ...params } },
  });
}

export async function editUserSettings(params = {}) {
  return await this.graphql("BirdwatchEditUserSettings", { body: { variables: { ...params } } });
}

export async function acknowledgeEarnOut() {
  return await this.graphql("BirdwatchProfileAcknowledgeEarnOut", { body: { variables: {} } });
}

export async function admitUser(opts = {}) {
  return await this.graphql("BirdwatchAdmitUser", { body: { variables: { ...opts.variables } } });
}

export async function removeUser(opts = {}) {
  return await this.graphql("BirdwatchRemoveUser", { body: { variables: { ...opts.variables } } });
}
