<script lang="ts">
import Spacer from "$lib/Layout/Spacer.svelte";
import { v6 as uuidv6 } from "uuid";
import { database, type TrackerEntry } from "$lib/Database/IDB/tracker";
import { onMount } from "svelte";
import Message from "$lib/Loading/Message.svelte";
import locale from "$stores/locale";
import { get } from "svelte/store";

let url = "";
let title = "";
let progress = 0;
let error = "";
let masterList: TrackerEntry[] | null = null;
let confirmDelete = 0;

$: listAccess = masterList || [];

onMount(async () => {
	masterList = await database.entries.toArray();
});

const adjustEntry = (id: string, to: number) => {
	const entry = listAccess.find((entry) => entry.id === id);

	if (!entry) return;

	entry.progress = Math.max(0, to);

	database.entries.update(id, { progress: entry.progress });

	masterList = listAccess.map((entry) =>
		entry.id === id ? { ...entry, progress: entry.progress } : entry,
	);
};

const addEntry = async (url: string, title: string, progress: number) => {
	if (!url || !title) {
		error =
			get(locale)().tools.tracker?.urlTitleRequired ??
			"URL and title are required fields";

		return;
	}

	if (listAccess.some((entry) => entry.url === url)) {
		const existing = listAccess.find((entry) => entry.url === url)?.title;

		error = (
			get(locale)().tools.tracker?.entryExists ?? "Entry with URL already exists: {url}"
		).replace("{url}", existing ?? "");

		return;
	}

	await database.entries.add({ url, title, progress, id: uuidv6() });

	masterList = await database.entries.toArray();
};

const deleteEntry = async (id: string) => {
	if (confirmDelete !== 1) {
		confirmDelete = 1;
		error =
			get(locale)().tools.tracker?.confirmDelete ??
			"Click again to confirm deletion";

		return;
	}

	await database.entries.delete(id);

	masterList = await database.entries.toArray();
	confirmDelete = 0;
	error = "";
};
</script>

<div class="card">
  {#if error}
    <p><b>Error</b>: {error}</p>
  {/if}

  <input type="url" placeholder={$locale().tools.tracker?.urlPlaceholder} bind:value={url} />
  <input type="text" placeholder={$locale().tools.tracker?.titlePlaceholder} bind:value={title} />
  <input
    type="number"
    placeholder={$locale().tools.tracker?.progressPlaceholder}
    bind:value={progress}
  />
  <button
    class="button-lined"
    onclick={() => addEntry(url, title, progress)}
    data-umami-event="Add Tracker Entry">{$locale().common?.add}</button
  >

  <Spacer />

  {#if masterList === null}
    <Message message="Loading entries ..." />
  {:else}
    <ul>
      {#each listAccess.sort((a, b) => a.title.localeCompare(b.title)) as entry}
        <li>
          <div class="entry" id={entry.id}>
            <a href={entry.url} title={entry.id}>
              {entry.title}
            </a>

            <span class="opaque">|</span>

            <input
              type="number"
              value={entry.progress}
              size={3}
              onchange={(e) =>
                adjustEntry(
                  entry.id,
                  e.target
                    ? Number((e.target as HTMLInputElement).value) || entry.progress
                    : entry.progress
                )}
            />

            <span class="entry-adjust">
              <span class="opaque">|</span>
              <button
                class="button-square button-action"
                onclick={() => adjustEntry(entry.id, entry.progress - 1)}
                data-umami-event="Decrement Tracker Progress"
                >-
              </button>
              <button
                class="button-square button-action"
                onclick={() => adjustEntry(entry.id, entry.progress + 1)}
                data-umami-event="Increment Tracker Progress"
              >
                +
              </button>
              <span class="opaque">|</span>
              <button onclick={() => deleteEntry(entry.id)} data-umami-event="Delete Tracker Entry"
                >{$locale().common?.remove}</button
              >
            </span>
          </div>
        </li>
      {/each}
    </ul>
  {/if}
</div>

<style>
  .entry {
    display: flex;
    align-items: center;
    gap: 0.25rem;
    width: 100%;
  }

  .entry-adjust {
    opacity: 0;
    transition: opacity 0.2s;
  }

  .entry:hover .entry-adjust {
    opacity: 1;
    transition: opacity 0.2s;
  }
</style>
