<script>
  import { _ } from "svelte-i18n";
  import { DonorService } from "@odit/lfk-client-js";
  import store from "../../store";
  import DonorsEmptyState from "./DonorsEmptyState.svelte";
  import ConfirmDonorDeletion from "./ConfirmDonorDeletion.svelte";
  import TableBottom from "../shared/TableBottom.svelte";
  import {
    createSvelteTable,
    flexRender,
    getCoreRowModel,
    getFilteredRowModel,
    getPaginationRowModel,
    getSortedRowModel,
    renderComponent,
  } from "@tanstack/svelte-table";
  import { writable } from "svelte/store";
  import { onMount } from "svelte";
  import InputElement from "../shared/InputElement.svelte";
  import TableHeader from "../shared/TableHeader.svelte";
  import TableActions from "../shared/TableActions.svelte";
  import DonorAddress from "./DonorAddress.svelte";
  import DonorDonations from "./DonorDonations.svelte";
  import { filterAddress, filterName } from "../shared/tablefilters";
  import toast from "svelte-french-toast";
  $: searchvalue = "";
  $: active_deletes = [];
  $: selectedDonors =
    $table?.getSelectedRowModel().rows.map((row) => row.original) || [];
  $: selected =
    $table?.getSelectedRowModel().rows.map((row) => row.index) || [];

  $: dataLoaded = false;

  export let current_donors = [];
  export const addDonors = (donors) => {
    current_donors = current_donors.concat(...donors);
    options.update((options) => ({
      ...options,
      data: current_donors,
    }));
  };

  //Section table
  const columns = [
    {
      accessorKey: "id",
      header: () => "id",
      filterFn: `equalsString`,
    },
    {
      accessorKey: "name",
      header: () => $_("name"),
      cell: (info) => {
        const d = info.row.original;
        if (d.middlename) {
          return `${d.firstname} ${d.middlename} ${d.lastname}`;
        } else {
          return `${d.firstname} ${d.lastname}`;
        }
      },
      filterFn: `name`,
    },
    {
      accessorKey: "address",
      header: () => $_("contact-information"),
      cell: (info) => {
        return renderComponent(DonorAddress, { address: info.getValue() });
      },
      filterFn: `address`,
    },
    {
      accessorKey: "donations",
      header: () => $_("sponsorings"),
      cell: (info) => {
        return renderComponent(DonorDonations, { donations: info.getValue() });
      },
      enableColumnFilter: false,
    },
    {
      accessorKey: "donationAmount",
      header: () => $_("total-donation-amount"),
      cell: (info) => {
        return `${(info.getValue() / 100)
          .toFixed(2)
          .toLocaleString("de-DE", { valute: "EUR" })}€`;
      },
      enableColumnFilter: false,
    },
    {
      accessorKey: "paidDonationAmount",
      header: () => $_("total-paid-amount"),
      cell: (info) => {
        return `${(info.getValue() / 100)
          .toFixed(2)
          .toLocaleString("de-DE", { valute: "EUR" })}€`;
      },
      enableColumnFilter: false,
    },
    {
      accessorKey: "actions",
      header: () => $_("action"),
      cell: (info) => {
        return renderComponent(TableActions, {
          detailsLink: `./${info.row.original.id}`,
          deleteAction: () => {
            active_deletes = current_donors.filter(
              (r) => r.id == info.row.original.id
            );
          },
          deleteEnabled:
            store.state.jwtinfo.userdetails.permissions.includes(
              "DONOR:DELETE"
            ),
        });
      },
      enableColumnFilter: false,
      enableSorting: false,
    },
  ];
  const options = writable({
    data: [],
    columns: columns,
    initialState: {
      pagination: {
        pageSize: 50,
      },
    },
    filterFns: {
      name: filterName,
      address: filterAddress,
    },
    enableRowSelection: true,
    getCoreRowModel: getCoreRowModel(),
    getFilteredRowModel: getFilteredRowModel(),
    getPaginationRowModel: getPaginationRowModel(),
    getSortedRowModel: getSortedRowModel(),
  });
  const table = createSvelteTable(options);

  function should_display_based_on_id(id) {
    if (searchvalue.toString().slice(-1) === "*") {
      return id.toString().startsWith(searchvalue.replace("*", ""));
    }
    return id.toString() === searchvalue;
  }

  onMount(async () => {
    let page = 0;
    let pagesize = 300;
    while (page >= 0) {
      const donors = await DonorService.donorControllerGetAll(page, pagesize);
      if (donors.length == 0) {
        page = -2;
      }

      current_donors = current_donors.concat(...donors);
      options.update((options) => ({
        ...options,
        data: current_donors,
      }));

      dataLoaded = true;
      page++;
    }
  });
</script>

<ConfirmDonorDeletion
  on:cancelDelete={(event) => {
    active_deletes = active_deletes.filter((a) => a.id !== event.detail.id);
  }}
  on:delete={async (event) => {
    toast.loading($_("deleting-donor"));
    await DonorService.donorControllerRemove(event.detail.id, true);
    toast.dismiss();
    toast.success($_("donor-deleted"));
    current_donors = current_donors.filter((d) => d.id !== event.detail.id);
    active_deletes = active_deletes.filter((a) => a.id !== event.detail.id);
    options.update((options) => ({
      ...options,
      data: current_donors,
    }));
  }}
  modal_open={active_deletes.length > 0}
  delete_donor={active_deletes[0]}
/>
{#if store.state.jwtinfo.userdetails.permissions.includes("DONOR:GET")}
  {#if !dataLoaded}
    <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">{$_("donors-are-being-loaded")}</p>
      <p class="text-sm">{$_("this-might-take-a-moment")}</p>
    </div>
  {:else if current_donors.length === 0}
    <DonorsEmptyState />
  {:else}
    <input
      type="search"
      bind:value={searchvalue}
      placeholder={$_("datatable.search")}
      aria-label={$_("datatable.search")}
      class="mb-2 w-full sm:w-auto mt-1 sm:mt-0 p-2 rounded-md border"
    />
    <div
      class="shadow border-b border-gray-200 sm:rounded-lg overflow-x-scroll"
    >
      <table class="w-full">
        <thead class="border-b border-gray-400">
          {#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 class="odd:bg-white even:bg-gray-100">
              <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>
    </div>
    <div class="h-2" />
    <TableBottom {table} {selected} />
  {/if}
{/if}

<style>
  table tbody tr td:nth-child(2) {
    font-family: monospace;
  }
</style>
