<script>
  import { getLocaleFromNavigator, json, _ } from "svelte-i18n";
  import InfiniteLoading from 'svelte-infinite-loading';
  import { RunnerCardService } from "@odit/lfk-client-js";
  import store from "../../store";
  import Toastify from "toastify-js";
  import CardsEmptyState from "./CardsEmptyState.svelte";
  import CardDetailModal from "./CardDetailModal.svelte";
  import GenerateRunnerCards from "../pdf_generation/GenerateRunnerCards.svelte";
  export let edit_modal_open = false;
  export let runner = {};
  export let editable = {};
  export let original_data = {};
  export let current_cards = [];
  $: filtered_cards = current_cards.filter(function (c) {
    if (
      c.code.toLowerCase().includes(searchvalue.toLowerCase()) ||
      c.runner?.firstname.toLowerCase().includes(searchvalue.toLowerCase()) ||
      c.runner?.middlename.toLowerCase().includes(searchvalue.toLowerCase()) ||
      c.runner?.lastname.toLowerCase().includes(searchvalue.toLowerCase()) ||
      should_display_based_on_id(c.id)
    ) {
      return true;
    }
  });
  $: searchvalue = "";
  $: active_deletes = [];
  $: cards_show = current_cards.some((r) => r.is_selected === true);
  $: generate_cards = current_cards.filter((r) => r.is_selected === true);
  const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
    (val) => {
      current_cards = val;
    }
  );
  function should_display_based_on_id(id) {
    if (searchvalue.toString().slice(-1) === "*") {
      return id.toString().startsWith(searchvalue.replace("*", ""));
    }
    return id.toString() === searchvalue;
  }
  const getRunnerLabel = (option) =>
    option?.firstname + " " + (option?.middlename || "") + " " + (option?.lastname || "{$_('non-blanko')}");
  function open_edit_modal(card) {
    if(card.runner?.id){
      runner = Object.assign(
        { runner },
        { label: getRunnerLabel(card.runner), value: card.runner }
      );
      card.runner = card.runner.id;
    }
    else{
      card.runner=null;
      runner = null
    }
    editable = Object.assign(editable, card);
    original_data = Object.assign(original_data, card);
    edit_modal_open = true;
  }
// -----------------
  export let wrapperHeight = "500px";
  export let wrapperWidth = "1000px";
  let scrollTop = 0;
  $: rendered = filtered_cards;
  let innerHeight = 0;
  let ele;
  $: updateSlice(scrollTop);
  $: innerHeight = `${filtered_cards.length * 25}px`;
  $: if (ele) updateSlice();
  function updateSlice() {
    const height = ele ? parseInt(ele.clientHeight) : 100;
    const init = scrollTop / 25;
    const end = Math.ceil((scrollTop + height) / 25);
    rendered = filtered_cards.slice(init, end + 15);
  }
  function updateScroll($event) {
    scrollTop = $event.target.scrollTop;
  }
</script>

<style>
  .virtual-wrapper {
    overflow-y: scroll;
    margin: 0 auto;
  }
  .inner-wrapper {
    overflow: hidden;
    position: relative;
    width: 100%;
  }
</style>

{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:UPDATE')}
  <CardDetailModal
    bind:current_cards
    bind:edit_modal_open
    bind:runner
    bind:editable
    bind:original_data />
{/if}

{#if store.state.jwtinfo.userdetails.permissions.includes('CARD:GET')}
  {#await cards_promise}
    <div
      class="bg-teal-lightest border-t-4 border-teal rounded-b text-teal-darkest px-4 py-3 shadow-md my-2"
      role="alert">
      <p class="font-bold">{$_('loading-cards')}</p>
      <p class="text-sm">{$_('this-might-take-a-moment')}</p>
    </div>
  {:then}
    {#if current_cards.length === 0}
      <CardsEmptyState />
    {:else}
      <input
        type="search"
        bind:value={searchvalue}
        placeholder={$_('datatable.search')}
        aria-label={$_('datatable.search')}
        class="gridjs-input gridjs-search-input mb-4" />
        <div class="h-12">
          <GenerateRunnerCards
            bind:cards_show
            bind:generate_cards />
        </div>
        {rendered.length}
      <div
        class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll">
        <table class="divide-y divide-gray-200 w-full">
          <thead class="bg-gray-50">
            <tr>
              <th
                scope="col"
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                <span
                  on:click={() => {
                    const newstate = !current_cards.some((r) => r.is_selected === true);
                    current_cards = current_cards.map((r) => {
                      r.is_selected = newstate;
                      return r;
                    });
                  }}
                  class="underline cursor-pointer select-none">{#if current_cards.some((r) => r.is_selected === true)}
                    {$_('deselect-all')}
                  {:else}{$_('select-all')}{/if}
                </span>
              </th>
              <th
                scope="col"
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                {$_('code')}
              </th>
              <th
                scope="col"
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                {$_('runner')}
              </th>
              <th
                scope="col"
                class="px-6 py-3 text-left text-xs font-medium text-gray-500 uppercase tracking-wider">
                {$_('status')}
              </th>
              <th scope="col" class="relative px-6 py-3">
                <span class="sr-only">{$_('action')}</span>
              </th>
            </tr>
          </thead>
          <tbody class="divide-y divide-gray-200">
            <!-- //// -->
            <div
  class="virtual-wrapper"
  on:scroll={updateScroll}
  style="height: {wrapperHeight}; width: {wrapperWidth}"
  bind:this={ele}>
  <div class="inner-wrapper" style="height: {innerHeight}">
    {#each filtered_cards as card, index}
    {#if card.code
      .toLowerCase()
      .includes(
        searchvalue.toLowerCase()
      ) || card.runner?.firstname
        .toLowerCase()
        .includes(
          searchvalue.toLowerCase()
        ) || card.runner?.middlename
        .toLowerCase()
        .includes(
          searchvalue.toLowerCase()
        ) || card.runner?.lastname
        .toLowerCase()
        .includes(
          searchvalue.toLowerCase()
        ) || should_display_based_on_id(card.id)}
      <tr data-rowid="card_{card.id}">
        <td class="px-6 py-4 whitespace-nowrap">
          <input
            bind:checked={card.is_selected}
            type="checkbox"
            class="focus:ring-indigo-500 h-4 w-4 text-indigo-600 border-gray-300 rounded" />
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <div class="flex items-center">{card.code}</div>
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <div class="flex items-center">
            {#if card.runner}
              <a
                href="../runners/{card.runner.id}"
                class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-gray-100 text-gray-800">{card.runner.firstname}
                {card.runner.middlename || ''}
                {card.runner.lastname}</a>
            {:else}{$_('non-blanko')}{/if}
          </div>
        </td>
        <td class="px-6 py-4 whitespace-nowrap">
          <div class="flex items-center">
            {#if card.enabled}
              <span
                class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-green-100 text-green-800">{$_('enabled')}</span>
            {:else}
              <span
                class="px-2 inline-flex text-xs leading-5 font-semibold rounded-full bg-red-100 text-red-800">{$_('disabled')}</span>
            {/if}
          </div>
        </td>

        {#if active_deletes[card.id] === true}
          <td
            class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
            <button
              on:click={() => {
                active_deletes[card.id] = false;
              }}
              tabindex="0"
              class="ml-4 text-indigo-600 hover:text-indigo-900 cursor-pointer">{$_('cancel-delete')}</button>
            <button
              on:click={() => {
                RunnerCardService.runnerCardControllerRemove(card.id, false).then(
                  (resp) => {
                    current_cards = current_cards.filter(
                      (obj) => obj.id !== card.id
                    );
                    Toastify({
                      text: $_('card-deleted'),
                      duration: 500,
                      backgroundColor:
                        'linear-gradient(to right, #00b09b, #96c93d)',
                    }).showToast();
                  }
                );
              }}
              tabindex="0"
              class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('confirm-delete')}</button>
          </td>
        {:else}
          <td
            class="px-6 py-4 whitespace-nowrap text-right text-sm font-medium">
            <button
              on:click={() => {
                open_edit_modal(card);
              }}
              class="text-indigo-600 hover:text-indigo-900">{$_('details')}</button>
            {#if store.state.jwtinfo.userdetails.permissions.includes('CARD:DELETE')}
              <button
                on:click={() => {
                  active_deletes[card.id] = true;
                }}
                tabindex="0"
                class="ml-4 text-red-600 hover:text-red-900 cursor-pointer">{$_('delete')}</button>
            {/if}
          </td>
        {/if}
      </tr>
    {/if}
    {/each}
  </div>
</div>
          </tbody>
        </table>
      </div>
    {/if}
  {:catch error}
    <div class="text-white px-6 py-4 border-0 rounded relative mb-4 bg-red-500">
      <span class="inline-block align-middle mr-8">
        <b class="capitalize">{$_('general_promise_error')}</b>
        {error}
      </span>
    </div>
  {/await}
{/if}
