import React from 'react';
import ReactDOM from 'react-dom';
import crypto from 'crypto';
import "core-js/stable";
import "regenerator-runtime/runtime";
import * as cryptojs from 'crypto-js';
import $ from 'jquery';
var Buffer = require('buffer').Buffer;

var folderparts = 0;
var permissions = "0";
var patient = 0;
var justified = "0";

class Generate_Sign_Butn extends React.Component {
  RSASign(string_sign) {
    console.log(string_sign)
    var signerObject = crypto.createSign("RSA-SHA256");
    var PrivateKey = sessionStorage.getItem('privkey')
    signerObject.update(string_sign);
    var signature = signerObject.sign(PrivateKey, false);
    console.log(signature);
    var b64encoded = btoa(String.fromCharCode.apply(null, signature))
    return(b64encoded)
    }

  get_license_signed(){
    var patient_id = document.getElementById('id_patient').value;
    var user = document.getElementById('username').innerHTML;
    var justified_id = document.getElementById('id_justified').value;
    var expdate_id = document.getElementById('id_exp_date').value;
    var permissions_object = document.getElementById('id_permissions')
    var folder_parts_object = document.getElementById('id_folder_parts')
    var patient_object = document.getElementById('id_patient')
    var justified_object = document.getElementById('id_justified')
    var buttsn = new Generate_Sign_Butn();
    patient_id = buttsn.return_string_fromObject(patient, patient_object)
    justified_id = buttsn.return_string_fromObject(justified, justified_object)
    permissions = buttsn.return_string_fromObject(permissions, permissions_object)
    folderparts = buttsn.return_string_fromObject(folderparts, folder_parts_object)
    var signature_string = patient_id + "&" + justified_id + "&" + user + "&" + expdate_id.replace(" ", ",")  + "&" + permissions + "&" + folderparts
    var signatured = buttsn.RSASign(signature_string)
    document.getElementById('id_signature').value = signatured
    return signatured;
  }
  return_string_fromObject(ids, element){
    var object_string = "";
    for (var i = 0; i < ids.length; i++){
        object_string += element.options[ids[i]].text
        object_string += ","
    }
    object_string = object_string.substring(0, object_string.length-1)
    return object_string
  }
  render() {
    return (
      <button onClick={this.get_license_signed}>Generate Signature</button>
    );
  }
}

function get_Params(){
    var patient_id = document.getElementById('id_patient').textContent;
    var justified_id = document.getElementById('id_justified').textContent;
    var expdate_id = document.getElementById('id_exp_date').textContent;
    var permissions = document.getElementById('id_permission').textContent
    var folderparts = document.getElementById('id_folder_parts').textContent
    var creator = document.getElementById('id_license_creator').textContent
    var signature = document.getElementById('id_signature').textContent
    signature = signature.replaceAll("\n", "")
    signature = signature.replaceAll(" ", "")
    var content_key = document.getElementById('id_content_key').textContent
    content_key = content_key.replaceAll("\n", "")
    content_key = content_key.replaceAll(" ", "")
    var serversign = document.getElementById('licenseserver_sign').textContent
    if (serversign){
    serversign = serversign.replaceAll("\n", "")
    serversign = serversign.replaceAll(" ", "")
    var sig_array = [patient_id, creator, justified_id, expdate_id, permissions, folderparts, signature, content_key, serversign]}
    else {
        var sig_array = [patient_id, creator, justified_id, expdate_id, permissions, folderparts, signature, content_key]
    }
    return sig_array;
}

function getPrivKey(){
    var privkey = document.getElementById('privkey').value;
    var pubkey = document.getElementById('pubkey').value;
    sessionStorage.setItem("privkey", privkey);
    sessionStorage.setItem("pubkey", pubkey);
}

var submitLogin = document.getElementById('submit_login');
if(submitLogin){
    if (submitLogin.attachEvent) { submitLogin.attachEvent("submit", getPrivKey)} else {
        submitLogin.addEventListener("submit", getPrivKey)}}

var check_submit = document.getElementById('submit_button_license');
if(check_submit){
    document.getElementById("id_patient").onclick = function() {
      patient = Array.from(this.selectedOptions).map(option => option.index)
    }
    document.getElementById("id_justified").onclick = function() {
      justified = Array.from(this.selectedOptions).map(option => option.index)
    }
    document.getElementById("id_folder_parts").onclick = function() {
      folderparts = Array.from(this.selectedOptions).map(option => option.index)
    }
    document.getElementById("id_permissions").onclick = function() {
      permissions = Array.from(this.selectedOptions).map(option => option.index)
    }
}

async function display_folderpart(id){
    var jsonArr = []
    var params = get_Params()
    var license = new License(params)
    license.serversign = params[8]
    jsonArr.push(license)
    jsonArr.push(id)
    var response_create = await fetch('http://192.168.192.75:8000/folder/read/', {
        method: 'POST',
        body: JSON.stringify(jsonArr), // string or object
        headers: {
          'Content-Type': 'application/json'
        }
    })
    var myJason = await response_create.json()
    console.log(response_create)
    console.log(myJason.key)
    console.log(base64ToArrayBuffer(myJason.key))
    var key = decrypt_key(base64ToArrayBuffer(myJason.key))
    var enc_content = myJason.content.replace(id, "")
    var content = aes_decrypt(key, enc_content)
    console.log(content)
    if (license.permissions.includes("Write")) {
        ReactDOM.render(<div><div>{id}</div>
            <textarea id="check_in_data" cols="40" rows="5"></textarea>
            <div><button onClick={() => check_in_data(id, key, jsonArr)}>Check In</button></div></div>, document.getElementById('content_parts'))
    } else {
        ReactDOM.render(<div>{content}</div>, document.getElementById('license_cfaesontent'))
    }
    document.getElementById("check_in_data").value = content
}

async function check_in_data(id, key, jsonArr){
    var content = document.getElementById("check_in_data").value
    console.log(content)
    var butin = new Generate_Sign_Butn()
    var privkey = get_priv_key()
    var encrypted_content = aes_encrypt(key, content)
    var today = new Date()
    var date = today.getFullYear()+'-'+(today.getMonth()+1)+'-'+today.getDate()
    var time = today.getHours() + ":" + today.getMinutes() + ":" + today.getSeconds()
    var date_time = date + "|" + time
    var change_signature = butin.RSASign(date_time + "|" + encrypted_content)
    console.log(encrypted_content)
    jsonArr.push(encrypted_content)
    jsonArr.push(date_time)
    jsonArr.push(change_signature)
    var response_create = await fetch('http://192.168.192.75:8000/folder/write/', {
        method: 'POST',
        body: JSON.stringify(jsonArr), // string or object
        headers: {
          'Content-Type': 'application/json'
        }
    })
    var myJason = await response_create.json()
    console.log("jo")
}

class Buaton_API extends React.Component {
async call_api (){
    var jsonArr = []
    var license = new License(get_Params())
    folderparts = license.folderparts
    folderparts = folderparts.split(", ")
    document.getElementById("license_content").style.visibility = "visible"
    var i = folderparts.map((part) => {
    return <button id={part} onClick={() => display_folderpart(part)}>{part}</button>})
    ReactDOM.render(i, document.getElementById('part_buttons'))
}
  render() {
    return (
      <button onClick={this.call_api}>Use License</button>
    );
  }
}

var readAPI = document.getElementById('use_license');

if (readAPI) {
    ReactDOM.render(<Buaton_API />, document.getElementById('use_license'))
}

var check_if_creating = document.getElementById('create_available');
if (check_if_creating) {
    ReactDOM.render(<Generate_Sign_Butn />, document.getElementById('create_available'))
}

function get_pub_key(){
    var pubkey = sessionStorage.getItem('pubkey')
    return pubkey
}

function get_priv_key(){
    var privkey = sessionStorage.getItem('privkey')
    return privkey
}

function get_random_key(){
    var key = crypto.randomBytes(32)
    return key
}

function encrypt_key(key){
    var pubkey = get_pub_key()
    var encryptkey = btoa(String.fromCharCode.apply(null, crypto.publicEncrypt(pubkey, key)))
    return encryptkey
}

function encrypt_key_public(key, pubkey){
    var encryptkey = btoa(String.fromCharCode.apply(null, crypto.publicEncrypt(pubkey, key)))
    return encryptkey
}

function decrypt_key(key){
    var priv_key = get_priv_key()
    var decrypted_key = btoa(String.fromCharCode.apply(null, crypto.privateDecrypt(priv_key, key)))
    return decrypted_key
}

var base64Matcher = new RegExp("^(?:[A-Za-z0-9+/]{4})*(?:[A-Za-z0-9+/]{2}==|[A-Za-z0-9+/]{3}=|[A-Za-z0-9+/]{4})$");

function aes_encrypt(key, message){
    let cfg = {
    mode: cryptojs.mode.ECB
    };
    if(!base64Matcher.test(key)){
    key = btoa(String.fromCharCode.apply(null, key))}
    var encrypted = cryptojs.AES.encrypt(message, key, cfg).toString()
    console.log(encrypted)
    return encrypted
}

function base64ToArrayBuffer(base64) {
    var binary_string = atob(base64);
    var len = binary_string.length;
    var bytes = new Uint8Array(len);
    for (var i = 0; i < len; i++) {
        bytes[i] = binary_string.charCodeAt(i);
    }
    return bytes;
}
function aes_decrypt(key, message){
    let cfg = {
    mode: cryptojs.mode.ECB
    };
    var decryptedkey = cryptojs.AES.decrypt(message, key, cfg).toString(cryptojs.enc.Utf8)
    return decryptedkey
}
class newFolder_part {
    constructor(part_class, encrypt_key, content){
    this.part_class = part_class
    this.encrypted_key = encrypt_key
    this.content = content
    }
}

class License{
    constructor(licensearr){
        this.patient = licensearr[0]
        this.creator = licensearr[1]
        this.justified = licensearr[2]
        this.expdate = licensearr[3]
        this.permissions = licensearr[4]
        this.folderparts = licensearr[5]
        this.signature = licensearr[6]
        this.content_key = licensearr[7]
    }
}

class CreatePatientFolderButton extends React.Component {
async call_api (){
    const response = await fetch('http://192.168.192.75:8000/folderpartnames/')
    const myJason = await response.json()
    var data = {
    "part_class": "Röntgenbilder",
    "folder_id": "1",
    "part_context": "descht"
    }
    console.log(myJason)
    var jsonArr = []
    var testkeys = []
    console.log(myJason.part_name)
    var params = get_Params()
    var license = new License(params)
    license.serversign = params[8]
    jsonArr.push(license)
    for (var i = 0; i < myJason.results.length; i++){
        var key = get_random_key()
        var content = aes_encrypt(key, myJason.results[i].part_name)
        var part = new newFolder_part(myJason.results[i].part_name, encrypt_key(key), content)
        jsonArr.push(part)
        testkeys.push(part)
    }
    var response_create = await fetch('http://192.168.192.75:8000/folder/create/', {
    method: 'POST',
    body: JSON.stringify(jsonArr), // string or object
    headers: {
      'Content-Type': 'application/json'
    }
})}
render() {
    return (
      <button onClick={this.call_api}>CreateFolder</button>
    )
  }
}

var is_creating_folder = document.getElementById('create_patientfolder');
if (is_creating_folder) {
ReactDOM.render(<CreatePatientFolderButton />, document.getElementById('create_patientfolder'))
}

class UseLicenseButton extends React.Component {
async call_api (){
    var jsonArr = []
    var testkeys = []
    var license = new License(get_Params())
    folderparts = license.folderparts
    folderparts = folderparts.split(", ")
    print(folderparts)
    render_info = folderparts.map((part) => {
        return <button>{part}</button>})
    ReactDOM.render(render_info, document.getElementById('call_api'))
    jsonArr.push(license)
    var response_create = await fetch('http://192.168.192.75:8000/folder/create/', {
        method: 'POST',
        body: JSON.stringify(jsonArr), // string or object
        headers: {
            'Content-Type': 'application/json'
            }
        })
    }
render() {
    return (
      <button onClick={this.call_api}>UseLicense</button>
    )
  }
}

var needs_call_api = document.getElementById('call_api');
if (needs_call_api) {
    ReactDOM.render(<UseLicenseButton />, document.getElementById('call_api'))
}

class CreateLicenseButton extends React.Component {
async call_api (){
    var jsonArr = []
    var params = get_Params()
    var license = new License(params)
    license.serversign = params[8]
    jsonArr.push(license)
    console.log(license.folderparts)
    var folderparts = license.folderparts.split(",")
    for (var i = 0; i < folderparts.length; i++){
        var part = folderparts[i]
        jsonArr[1] = part
        jsonArr[2] = "get"
        var response_create = await fetch('http://192.168.192.75:8000/folder/read/', {
            method: 'POST',
            body: JSON.stringify(jsonArr), // string or object
            headers: {
              'Content-Type': 'application/json'
                }
        })
        var myJason = await response_create.json()
        var key = decrypt_key(base64ToArrayBuffer(myJason.key))
        var pubkey = myJason.pubkey
        pubkey = pubkey.replace("-----BEGIN PUBLIC KEY-----", "-----BEGINPUBLICKEY-----")
        pubkey = pubkey.replace("-----END PUBLIC KEY-----", "-----ENDPUBLICKEY-----")
        pubkey = pubkey.replaceAll(" ", "\n")
        pubkey = pubkey.replace("-----BEGINPUBLICKEY-----", "-----BEGIN PUBLIC KEY-----")
        pubkey = pubkey.replace("-----ENDPUBLICKEY-----", "-----END PUBLIC KEY-----")
        jsonArr[2] = encrypt_key_public(base64ToArrayBuffer(key), pubkey)
        var response_create = await fetch('http://192.168.192.75:8000/create/key/', {
            method: 'POST',
            body: JSON.stringify(jsonArr), // string or object
            headers: {
              'Content-Type': 'application/json'
            }
        })
    }
}
render() {
    return (
      <button onClick={this.call_api}>Create License</button>
    )
  }
}

var want_create_license = document.getElementById('call_api_button');
if (want_create_license) {
    ReactDOM.render(<CreateLicenseButton />, document.getElementById('call_api_button'))
}