@extends('layouts.app')
@section('title') App API Access @endsection
@section('content')


<div x-data="{ token: '', notification_success: true}" class="flex gap-3 flex-row max-lg:flex-col my-4 animate-slide-up-fade-in text-slate-900 dark:text-slate-200">
  <div x-data="notification()" x-init="init()">
    <div
      x-cloak
      x-show="isVisible"
      x-transition:enter="transition ease-out duration-300"
      x-transition:enter-start="opacity-0 transform translate-y-2"
      x-transition:enter-end="opacity-100 transform translate-y-0"
      x-transition:leave="transition ease-in duration-200"
      x-transition:leave-start="opacity-100 transform translate-y-0"
      x-transition:leave-end="opacity-0 transform translate-y-2"
      class="fixed inset-x-0 top-0 z-20 flex items-center justify-center px-4 py-6 pointer-events-none sm:p-6 sm:items-start sm:justify-center"
    >
      <div :class="notification_success ? 'bg-green-600' : 'bg-red-600'" class="max-w-sm w-full shadow-lg text-white rounded-lg pointer-events-auto">
        <div class="p-4">
          <p class="text-sm text-center" x-text="message"></p>
        </div>
      </div>
    </div>
  </div>
  <div class="flex-1 justify-between h-full border-s-2 border-indigo-400 flex-col bg-white dark:bg-slate-900  rounded-lg drop-shadow-md p-4 hover:shadow-lg hover:transition-all">
    <div class="text-2xl font-semibold mb-3">
      Active API tokens
    </div>
    <div class="grid lg:grid-cols-2 gap-3">
      <div id="token_list" class="overflow-x-auto grid gap-2">
      </div>
      <div>
        <label for="token"
             class="block mb-2 text-sm font-medium text-gray-900 dark:text-gray-300">Create a new access token</label>
        <div class="inline-flex items-center  block w-full">
          <input type="text"
                id="token"
                class="bg-gray-50 border-s border-y border-gray-300 text-gray-900 text-sm rounded-s-lg block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white"
                placeholder=""
                required
                :value="token"
                name="token"
                readonly>
          <button id="tokenGenerator"
                  type="button"
                  x-on:click="token=tokenGenerator();"
                  class="bg-gray-50 border-x border-y border-gray-300 text-gray-900 text-sm p-2.5 dark:bg-gray-600 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:hover:text-white dark:hover:bg-gray-700 hover:bg-gray-100">
            Generate
          </button>
          <button id="addToken"
                  type="button"
                  x-on:click="token = (addToken(token)) ? '' : token; console.log(token);"
                  class="bg-green-100 border-y border-e border-gray-300 text-gray-900 text-sm rounded-e-lg p-2.5 dark:bg-green-600 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:hover:text-white dark:hover:bg-green-700 hover:bg-green-200">
            Add
          </button>
        </div>
      </div>
    </div>
  </div>
</div>
<script type="text/javascript">
  const csrfToken = document.querySelector('meta[name="csrf-token"]').getAttribute('content');
  document.addEventListener('DOMContentLoaded', function () {
    document.getElementById('menu_app_api').classList.remove('text-gray-500');
    document.getElementById('menu_app_api').classList.remove('hover:bg-gray-700');
    document.getElementById('menu_app_api').classList.remove('hover:bg-opacity-25');
    document.getElementById('menu_app_api').classList.remove('hover:text-gray-100');
    document.getElementById('menu_app_api').classList.add('text-gray-100');
    document.getElementById('menu_app_api').classList.add('bg-opacity-25');
    document.getElementById('menu_app_api').classList.add('bg-gray-700');
    document.getElementById('menu_app_api').classList.add('border-e-2');
    document.getElementById('menu_app_api').classList.add('border-indigo-400');
    loadTokens();

});
document.body.addEventListener('click', function (evt) {
  if ( evt.target.className.includes('btnDelete') )
  {
    const btn = evt.target;
    const delete_token = btn.dataset.token;
    if ( removeToken(delete_token) )
    {
      document.getElementById(delete_token).remove();
    }
  }
});

function appendToken(token)
{
  const token_list = document.getElementById('token_list');
  const div = document.createElement('div');
  div.id = token;
  div.classList.value = 'animate-slide-up-fade-in inline-flex items-center  block w-full p-2';
  
  const input = document.createElement('input');
  input.classList.value = 'bg-gray-50 border-s border-y border-gray-300 text-gray-900 rounded-s-lg block w-full py-1 px-2 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white';
  input.value = token;

  const revoke = document.createElement('button');
  revoke.classList.value = 'btnDelete bg-orange-100 border border-gray-300 text-gray-900 rounded-e-lg p-1 dark:bg-orange-600 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:hover:text-white dark:hover:bg-orange-700 hover:bg-orange-200';
  revoke.dataset.token = token;
  revoke.innerText = 'Revoke';
  
  div.appendChild(input);
  div.appendChild(revoke);
  token_list.appendChild(div);
}

async function loadTokens()
{
  await fetch('/app-api/fetch-tokens', {
      method: 'GET',
      headers: {
        'X-CSRF-TOKEN': csrfToken,
        'Content-Type': 'application/json'
      },
    })
      .then(response => response.json())
      .then(response => {
        if ( response.value_text == "" )
        {
          showNotification(`No active API tokens found!`, false); 
        }
        else
        {
          var api_tokens = response.value_text.split(" ");
          for(var i = 0; i < api_tokens.length; i++)
          {
            appendToken(api_tokens[i]);
          }
        }
      })
      .catch(error => {
        showNotification('Error: ' + error, false);
      });
}

async function addToken(token)
{
  if ( token != "" )
  {
   await fetch('/app-api/add-token', {
      method: 'POST',
      headers: {
        'X-CSRF-TOKEN': csrfToken,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ add_token: token })
    })
      .then(response => response.json())
      .then(response => {
        if (response.status)
        {
          console.log(`Token added successfully!`);
          showNotification(`Token added successfully!`, true);
          appendToken(token);
          return true;
        }
        else
        {
          console.log(`Token NOT added!`);
          showNotification(`Couldn't add token`, false);
          return false;
        }
      })
      .catch(error => {
        console.log(`Token NOT added!`);
        showNotification('Error: ' + error, false);
        return false;
      });
  }
  else
  {
    showNotification(`Token cannot be empty, please press the "Generate" button before adding a token.`, false);
    return false;
  }
}

async function removeToken(token)
{
  if ( token != "" )
  {
   await fetch('/app-api/remove-token', {
      method: 'POST',
      headers: {
        'X-CSRF-TOKEN': csrfToken,
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({remove_token: token})
    })
      .then(response => response.json())
      .then(response => {
        if (response.status)
        {
          showNotification(`Token deleted successfully!`, true);
          return true;
        }
        else
        {
          showNotification(`Couldn't remove token`, false);
          return false;
        }
      })
      .catch(error => {
        showNotification('Error: ' + error, false);
        return false;
      });
  }
}

function tokenGenerator ()
{
  var stringLength = 32;
  var stringArray = ['0','1','2','3','4','5','6','7','8','9','a','b','c','d','e','f','g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z'];

  var rndString = "";
  // build a string with random characters
  for (var i = 1; i < stringLength; i++)
  {
    var rndNum = Math.ceil(Math.random() * stringArray.length) - 1;
    rndString = rndString + stringArray[rndNum];
  }
  return rndString;
}

function notification() {
  return {
    isVisible: false,
    notification_status: true,
    message: '',
    init() {
      window.showNotification = this.show.bind(this);
    },
    show(msg, status) {
      this.message = msg;
      this.notification_success = status;
      this.isVisible = true;
      delay = status ? 3000 : 6000;
      setTimeout(() => {
        this.isVisible = false;
      }, delay);
    }
  }
}
</script>
@endsection
 
