import { constructClaim } from '@coinweb/contract-kit';
import { readOp, storeOp } from 'cwait';

import { TypedClaim } from '../../../lib/dist/shared/types';
import { AddWordArgs, createWordKey, WordClaimBody } from '../offchain/shared';

function hashCode(str: string): string {
  let hash = 0;
  for (let i = 0, len = str.length; i < len; i++) {
    const chr = str.charCodeAt(i);
    // eslint-disable-next-line no-bitwise
    hash = (hash << 5) - hash + chr;
    // eslint-disable-next-line no-bitwise
    hash |= 0;
  }
  return `${(hash < 0 ? hash * -1 : hash).toString(16)}`;
}

export const addWord = async (...[word]: AddWordArgs) => {
  const id = hashCode(word);

  await storeOp(constructClaim(createWordKey(id), { word }, '0x0'));

  const wordClaim = await readOp<TypedClaim<WordClaimBody>>(createWordKey(id));

  const newWord1 = (wordClaim?.body.word ?? '') + '!';
  const newId1 = hashCode(newWord1);

  const newWord2 = (wordClaim?.body.word ?? '') + '!!';
  const newId2 = hashCode(newWord2);

  const newWord3 = (wordClaim?.body.word ?? '') + '!!!';
  const newId3 = hashCode(newWord3);

  await Promise.all([
    storeOp(constructClaim(createWordKey(newId1), { word: newWord1 }, '0x0')),
    storeOp(constructClaim(createWordKey(newId2), { word: newWord2 }, '0x0')),
    storeOp(constructClaim(createWordKey(newId3), { word: newWord3 }, '0x0')),
  ]);

  readOp<TypedClaim<WordClaimBody>>(createWordKey(newId3));
};
