import { EncryptionService } from "../../../common/service/EncryptionService";
import {
  ReencryptionDTO,
  DecryptedDTO,
} from "../../../common/dto/ReencryptionDTO";
import { Credentials } from "../../../common/global/Credentials";
import { MessageCipher } from "../../../common/entity/MessageCipher";
import log from "loglevel";
import { NotificationService } from "../../../common/service/NotificationService";
import { isPassphraseValid } from "../../../common/util/Passphrase";
import {
  getAllMessages,
  sendReencryptedMessages,
} from "../../../common/ajax/Messages";

export async function changePassphrase(
  es: EncryptionService,
  ns: NotificationService,
  authToken: string
): Promise<void> {
  //   $("#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;

  const valid = await isPassphraseValid(passphraseOld, user, es, authToken);

  if (!valid) {
    log.error("Please check your passphrase");
    ns.error("Please check your passphrase");
    return;
  }

  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);

  /* Uncomment to see the reencryption result
  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);

  ns.success("Successfully changed passphrase");
}
