<script>
  import { _ } from "svelte-i18n";
  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";
  import InputElement from "../shared/InputElement.svelte";
  import { groupFilter } from "../shared/tablefilters";
  import {
    createSvelteTable,
    flexRender,
    getCoreRowModel,
    getFilteredRowModel,
    getPaginationRowModel,
    getSortedRowModel,
    renderComponent,
  } from "@tanstack/svelte-table";
  import { writable } from "svelte/store";
  import TableBottom from "../shared/TableBottom.svelte";
  import TableActions from "../shared/TableActions.svelte";
  import TableHeader from "../shared/TableHeader.svelte";
  import CardStatus from "./CardStatus.svelte";
  import CardRunner from "./CardRunner.svelte";

  export let edit_modal_open = false;
  export let runner = {};
  export let editable = {};
  export let original_data = {};
  export let current_cards = [];

  $: selected =
    $table?.getSelectedRowModel().rows.map((row) => row.index) || [];
  $: selectedCards =
    $table?.getSelectedRowModel().rows.map((row) => row.original) || [];
  $: active_delete = undefined;
  $: cards_show = generate_cards.length > 0;
  $: generate_cards = [];

  const cards_promise = RunnerCardService.runnerCardControllerGetAll().then(
    (val) => {
      current_cards = val;
      options.update((options) => ({
        ...options,
        data: current_cards,
      }));
    }
  );

  const columns = [
    {
      accessorKey: "id",
      header: () => "id",
      filterFn: `equalsString`,
    },
    {
      accessorKey: "runner",
      header: () => $_("name"),
      cell: (info) => {
        return renderComponent(CardRunner, { runner: info.getValue() });
      },
      filterFn: `includesString`,
    },
    {
      accessorKey: "enabled",
      cell: (info) => {
        return renderComponent(CardStatus, { enabled: info.getValue() });
      },
      header: () => $_("status"),
      filterFn: `includesString`,
    },
    {
      accessorKey: "actions",
      header: () => $_("action"),
      cell: (info) => {
        return renderComponent(TableActions, {
          detailsAction: () => {
            open_edit_modal(
              current_cards[
                current_cards.findIndex((r) => r.id == info.row.original.id)
              ]
            );
          },
          deleteAction: () => {
            active_delete =
              current_cards[
                current_cards.findIndex((r) => r.id == info.row.original.id)
              ];
          },
          deleteEnabled:
            store.state.jwtinfo.userdetails.permissions.includes("CARD:DELETE"),
        });
      },
      enableColumnFilter: false,
      enableSorting: false,
    },
  ];
  const options = writable({
    data: [],
    columns: columns,
    filterFns: {
      group: groupFilter,
    },
    initialState: {
      pagination: {
        pageSize: 50,
      },
    },
    enableRowSelection: true,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
  });
  const table = createSvelteTable(options);

  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;
  }
</script>

{#if store.state.jwtinfo.userdetails.permissions.includes("CARD:UPDATE")}
  <CardDetailModal
    bind:current_cards
    bind:edit_modal_open
    bind:runner
    bind:editable
    bind:original_data
    on:dataUpdated={() => {
      //TODO:
    }}
  />
{/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}
      <div class="h-12 mt-1">
        {#if cards_show}
          <button
            type="button"
            class="w-full justify-center rounded-md border border-transparent shadow-sm px-4 py-2 bg-red-600 text-base font-medium text-white hover:bg-red-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-red-500 sm:ml-3 sm:w-auto sm:text-sm inline-flex"
            id="options-menu"
            on:click={async () => {
              const prom = [];
              for (const card of generate_cards) {
                prom.push(
                  RunnerCardService.runnerCardControllerRemove(card.id, true)
                );
              }
              await Promise.all(prom);
              Toastify({
                text: $_("cards-deleted"),
                duration: 3500,
                backgroundColor: "linear-gradient(to right, #00b09b, #96c93d)",
              }).showToast();
              //TODO: Delete cards from table
            }}
          >
            {$_("delete-cards")}
            <svg
              xmlns="http://www.w3.org/2000/svg"
              fill="none"
              viewBox="0 0 24 24"
              stroke-width="1.5"
              stroke="currentColor"
              class="w-5 h-5"
            >
              <path
                stroke-linecap="round"
                stroke-linejoin="round"
                d="M14.74 9l-.346 9m-4.788 0L9.26 9m9.968-3.21c.342.052.682.107 1.022.166m-1.022-.165L18.16 19.673a2.25 2.25 0 01-2.244 2.077H8.084a2.25 2.25 0 01-2.244-2.077L4.772 5.79m14.456 0a48.108 48.108 0 00-3.478-.397m-12 .562c.34-.059.68-.114 1.022-.165m0 0a48.11 48.11 0 013.478-.397m7.5 0v-.916c0-1.18-.91-2.164-2.09-2.201a51.964 51.964 0 00-3.32 0c-1.18.037-2.09 1.022-2.09 2.201v.916m7.5 0a48.667 48.667 0 00-7.5 0"
              />
            </svg>
          </button>
        {/if}
        <GenerateRunnerCards bind:cards_show bind:generate_cards />
      </div>
      <table class="w-full">
        <thead>
          {#each $table.getHeaderGroups() as headerGroup}
            <tr class="select-none">
              <th class="inset-y-0 left-0 px-4 py-2 text-left w-px">
                <InputElement
                  type="checkbox"
                  checked={$table.getIsAllRowsSelected()}
                  indeterminate={$table.getIsSomeRowsSelected()}
                  on:change={() => $table.toggleAllRowsSelected()}
                />
              </th>
              {#each headerGroup.headers as header}
                <TableHeader {header} />
              {/each}
            </tr>
          {/each}
        </thead>
        <tbody>
          {#each $table.getRowModel().rows as row}
            <tr>
              <td class="inset-y-0 left-0 px-4 py-2 text-center w-px">
                <InputElement
                  type="checkbox"
                  checked={row.getIsSelected()}
                  on:change={() => row.toggleSelected()}
                />
              </td>
              {#each row.getVisibleCells() as cell}
                <td>
                  <svelte:component
                    this={flexRender(
                      cell.column.columnDef.cell,
                      cell.getContext()
                    )}
                  />
                </td>
              {/each}
            </tr>
          {/each}
        </tbody>
      </table>
      <TableBottom {table} {selected} />
    {/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}

<style>
  table tbody {
    display: block;
    overflow-y: scroll;
  }

  table thead,
  table tbody tr {
    display: table;
    width: 100%;
    table-layout: fixed;
  }
</style>
