import { EncryptionService } from "../../../common/service/EncryptionService";
import { Routes } from "../../../common/routes/Routes";
import { ChatMessageDTO } from "../../../common/dto/ChatMessageDTO";
import {
  ReencryptionDTO,
  DecryptedDTO,
} from "../../../common/dto/ReencryptionDTO";
import { Credentials } from "../../../common/global/Credentials";
import { MessageCipher } from "../../../common/entity/MessageCipher";
import log from "loglevel";

export async function changePassphrase(es: EncryptionService) {
  //   $("#changePassphraseForm").val();

  const user =
    (document.getElementById("changePassphraseDropDown") as HTMLOptionElement)
      .value || "error";

  const passphraseOld: string = $("#passphraseOld").val() as string;
  const passphraseNew: string = $("#passphraseNew").val() as string;

  log.debug(Credentials.authToken);
  const messages = await getAllMessages(user, Credentials.authToken);

  const decrypted = Promise.all(
    messages.map(
      async (m): Promise<DecryptedDTO> => {
        const msg = await es.decryptAsPromise(passphraseOld, m.messageCipher);
        const m2 = { ...m, messageId: m.messageCipher.id, message: msg };
        return m2;
      }
    )
  );

  const reencrypted = (await decrypted).map((m) => {
    const mdto = es.encrypt(passphraseNew, m.message);
    const mc = <MessageCipher>{ id: m.messageId, ...mdto };
    const rdto = <ReencryptionDTO>{ ...m, messageCipher: mc };
    return rdto;
  });

  log.debug(reencrypted);

  const decryptedAgain = Promise.all(
    reencrypted.map(async (m) => {
      return es.decryptAsPromise(passphraseNew, m.messageCipher);
    })
  );

  const deb = await decryptedAgain;
  log.debug(deb);

  sendReencryptedMessages(reencrypted, Credentials.authToken);
}

async function getAllMessages(user: string, authToken: string) {
  let headers = new Headers();
  // headers.append('Accept','application/json')
  // headers.append('Content-Type', 'application/json');
  headers.append("X-AUTH-TOKEN", authToken);
  let response = await fetch(`${Routes.Admin.getAllMessagesURL}${user}`, {
    method: "GET",
    headers: headers,
  });
  return response.json() as Promise<ReencryptionDTO[]>;
}

async function getAllRegularUsers(authToken: string) {
  let headers = new Headers();
  // headers.append('Accept','application/json')
  // headers.append('Content-Type', 'application/json');
  headers.append("X-AUTH-TOKEN", authToken);
  let response = await fetch(`${Routes.Admin.getAllRegularUsersURL}`, {
    method: "GET",
    headers: headers,
  });
  let data = (await response.json()) as string[];
  return data;
}

function sendReencryptedMessages(
  rrencryptionDTOs: ReencryptionDTO[],
  authToken: string
) {
  let headers = new Headers();
  //	console.log("Token = " + btoa("hmm" + ":" + "hmm"))

  // headers.append('Accept','application/json')
  headers.append("Content-Type", "application/json");
  headers.append("X-AUTH-TOKEN", authToken);
  fetch(Routes.Admin.reencryptURL, {
    method: "POST",
    headers: headers,
    body: JSON.stringify(rrencryptionDTOs),
  }).then((response) => console.log(response));
}
