import { Injectable } from '@angular/core';
import _sodium from 'libsodium-wrappers';
import { public_key, secret_key } from '../../environments/environment.prod';

@Injectable({
  providedIn: 'root'
})
export class EncService {

  constructor() { }

  public async isEncrypted(value: string): Promise<boolean>{
    try{
      await this.decrypt(value);
      return true;
    }catch(error: any){
      return false;
    }
  }

  public encrypt(value: string){
    return (async() => {
      await _sodium.ready;
      const sodium = _sodium;
      var nonce = sodium.randombytes_buf(sodium.crypto_box_NONCEBYTES);

      var encoded = sodium.crypto_box_easy(
        value,
        nonce, 
        this.stringToUT8(public_key),
        this.stringToUT8(secret_key),
      );

      var encoded_string = "";
      encoded.forEach(charCode => {
        let char = String.fromCharCode(charCode);
        encoded_string += char;
      });

      var nonce_string = "";
      nonce.forEach(charCode => {
        let char = String.fromCharCode(charCode);
        nonce_string += char;
      })

      var encoded_base64 = window.btoa(encoded_string);
      var nonce_base64 = window.btoa(nonce_string);

      let enc = window.btoa(encoded_base64 + '|' + nonce_base64);
      return enc;
    })();
  }

  public decrypt(value: string){
    return(async() => {
      await _sodium.ready;
      const sodium = _sodium;

      let value_string = window.atob(value);
      let value_array = value_string.split('|');

      let encoded_string = window.atob(value_array[0]);
      let nonce_string = window.atob(value_array[1]);

      let encoded_array = [];
      for(let i = 0; i < encoded_string.length; i++){
        let char = encoded_string.charCodeAt(i);
        encoded_array.push(char);
      }

      let nonce_array = [];
      for(let i = 0; i < nonce_string.length; i++){
        let char = nonce_string.charCodeAt(i);
        nonce_array.push(char);
      }

      let encoded_utf8 = new Uint8Array(encoded_array);
      let nonce_utf8 = new Uint8Array(nonce_array);
      
      var decoded = sodium.crypto_box_open_easy(
        encoded_utf8,
        nonce_utf8,
        this.stringToUT8(public_key),
        this.stringToUT8(secret_key)
      );
      
      let decoder = new TextDecoder();
      let decoded_string = decoder.decode(decoded);
      
      return decoded_string;
    })();
  }

  private stringToUT8(key: string): Uint8Array {
    let pk_dec = window.atob(key);
    let arr_enc = [];

    for (let index = 0; index < pk_dec.length; index++) {
      arr_enc.push(pk_dec.charCodeAt(index));
    }

    var arr = new Uint8Array(arr_enc);
    return arr;
  }
}
