import secrets from "../lib/secrets";
import { encryptMessage } from "./signingUtilities";
import { encodeResponse } from "./appUtility";
import { getSliceRange } from "./numberUtilities";
import { THRESHOLD } from "../constants/secrets";

/** Initialize
 */
export const initSecrets = (bits, rngType) => secrets.init(bits, rngType);

export const setRNG = rngType => secrets.setRNG(rngType);
export const getSecretsConfig = () => secrets.getConfig();

/**
 * Function generates a random bits length string, and output it in hexadecimal format
 *
 * @param {number} bits
 * @returns {string} hex
 */
export const generateSecret = bits => secrets.random(bits);

/**
 * Divide a secret expressed in hexadecimal form into numShares number of shares, requiring that threshold number of shares be present for reconstructing the secret
 *
 * @param {string} secret
 * @param {number} numShares
 * @param {number} threshold
 * @param {number} [padLength=128]
 * @returns {array}
 */
export const divideSecretToShares = (
  secret,
  numShares,
  threshold,
  padLength = 128
) => secrets.share(secret, numShares, threshold, padLength);

/**
 * Reconstructs a secret from shares
 *
 * @param {array} shares
 * @returns {string}
 */
export const combineSecret = shares => secrets.combine(shares);

export const encryptShare = async (share, publicKey) =>
  await encryptMessage(share, publicKey, "secretPart");

/** Account Recovery key management */

export const generateRecoveryKey = () => {
  const recoveryKey = generateSecret(512);
  return recoveryKey;
};

export const getRecoveryKeyShares = (recoveryKey, sharesNumber) => {
  return divideSecretToShares(recoveryKey, sharesNumber, THRESHOLD);
};

function getSecretSliceRange(max) {
  const { beginIndex, endIndex } = getSliceRange(max);
  if (endIndex - beginIndex < THRESHOLD) {
    return getSecretSliceRange(max);
  }

  return { beginIndex, endIndex };
}

export const checkRecoveryKeyCombine = (recoveryKey, recoveryKeyShares) => {
  let checkKey;

  const { beginIndex, endIndex } = getSecretSliceRange(
    recoveryKeyShares.length + 1
  );
  console.log({ beginIndex, endIndex });
  checkKey = combineSecret(recoveryKeyShares.slice(beginIndex, endIndex));
  if (checkKey !== recoveryKey) {
    return encodeResponse(
      "400",
      "",
      "Sanity check with required number of shares failed"
    );
  }
  checkKey = combineSecret(recoveryKeyShares.slice(0, 1));
  if (checkKey === recoveryKey) {
    return encodeResponse(
      "400",
      "",
      "Sanity check with less than required shares failed"
    );
  }
  checkKey = combineSecret(recoveryKeyShares);
  if (checkKey !== recoveryKey) {
    return encodeResponse("400", "", "Sanity check with all shares failed");
  }

  return encodeResponse("200", "", "Check passed");
};