<script lang="ts">
  /*** UTILITY ------------------------------------------ ***/
  import type { HistoryEntry } from "../state/history.svelte.ts";

  type Props = {
    entries: HistoryEntry[];
    notice?: string | null;
    onClear: () => void;
    onDismissNotice?: () => void;
    onExport?: () => void;
    onFavorite: (id: string) => void;
    onImport?: (file: File) => void;
    onLoad: (id: string, inNewTab: boolean) => void;
    onRemove: (id: string) => void;
  };

  let {
    entries,
    notice = null,
    onClear,
    onDismissNotice,
    onExport,
    onFavorite,
    onImport,
    onLoad,
    onRemove
  }: Props = $props();

  let fileInput = $state<HTMLInputElement | null>(null);

  const sorted = $derived([...entries].sort((a, b) => {
    if (a.favorite !== b.favorite)
      return a.favorite ? -1 : 1;

    return b.timestamp - a.timestamp;
  }));

  /*** HELPER ------------------------------------------- ***/
  function formatTimestamp(ms: number): string {
    const d = new Date(ms);
    return d.toLocaleString();
  }

  function onEntryClick(event: MouseEvent, id: string) {
    onLoad(id, event.shiftKey);
  }

  function onEntryKey(event: KeyboardEvent, id: string) {
    if (event.key === "Enter" || event.key === " ") {
      event.preventDefault();
      onLoad(id, event.shiftKey);
    }
  }

  function onFileChange(event: Event) {
    const input = event.currentTarget as HTMLInputElement;
    const file = input.files?.[0];

    if (file)
      onImport?.(file);

    input.value = "";
  }

  function onImportClick() {
    fileInput?.click();
  }
</script>

<style lang="scss">
  .panel {
    background-color: var(--uchu-yin-9);
    color: var(--uchu-yin-1);
    display: grid;
    font-size: 0.8rem;
    grid-template-rows: auto 1fr;
    min-height: 0;
    height: 100%;
    overflow: hidden;
    z-index: 2;
  }

  .header,
  .notice {
    align-items: center;
    border-bottom: 1px solid var(--uchu-yin-8);
    display: flex;
    gap: 0.5rem;
    justify-content: space-between;
    padding: 0.5rem 0.75rem;
  }

  .title {
    font-weight: 600;
  }

  .actions {
    display: flex;
    gap: 0.5rem;

    .action {
      background: none;
      border: none;
      cursor: pointer;
      font-family: inherit;
      font-size: 0.75rem;
      padding: 0;
    }
  }

  .action,
  .notice-dismiss,
  .remove {
    &:not(:hover) {
      color: var(--uchu-yin-5);
    }

    &:hover {
      color: var(--uchu-yin-1);
    }
  }

  .hidden-input {
    display: none;
  }

  .notice-dismiss,
  .remove {
    background: none;
    border: none;
    cursor: pointer;
    font-size: 1rem;
    line-height: 1;
    padding: 0 0.25rem;
  }

  .list {
    display: grid;
    min-height: 0;
    overflow-y: auto;
  }

  .entry {
    align-items: flex-start;
    cursor: pointer;
    display: grid;
    gap: 0.125rem;
    grid-template-columns: auto 1fr auto;
    padding: 0.375rem 0.75rem;
    transition: opacity 0.1s;

    &:not(:last-of-type) {
      border-bottom: 1px solid var(--uchu-yin);
    }

    &:hover {
      background-color: var(--uchu-yin);
    }

    .list:has(.entry:hover) &:not(:hover) {
      opacity: 0.4;
    }

    &-title {
      font-size: 0.8rem;
      margin-bottom: 0.1rem;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
    }

    &-time {
      color: var(--uchu-yin-5);
      font-size: 0.7rem;
    }
  }

  .star {
    align-self: center;
    background: none;
    border: none;
    cursor: pointer;
    font-size: 0.8rem;
    padding: 0 0.375rem 0 0;

    &:not(.active) {
      color: var(--uchu-yin-5);
    }

    &.active {
      color: var(--uchu-orange-4);

      svg {
        fill: currentColor;
      }
    }

    svg {
      width: 1rem;
    }
  }

  .meta {
    align-self: center;
    min-width: 0;
  }

  .remove {
    align-self: center;
  }

  .empty {
    color: var(--uchu-yin-5);
    font-size: 0.8rem;
    padding: 0.75rem;
  }
</style>

<div class="panel">
  <div class="header">
    <span class="title">History</span>

    <div class="actions">
      {#if onExport}
        <button class="action" onclick={onExport} type="button">Export</button>
      {/if}

      {#if onImport}
        <button class="action" onclick={onImportClick} type="button">Import</button>
        <input
          accept="application/json"
          bind:this={fileInput}
          class="hidden-input"
          onchange={onFileChange}
          type="file"/>
      {/if}

      {#if entries.length > 0}
        <button class="action" onclick={onClear} type="button">Clear</button>
      {/if}
    </div>
  </div>

  {#if notice}
    <div class="notice">
      <span>{notice}</span>
      {#if onDismissNotice}
        <button
          aria-label="Dismiss notice"
          class="notice-dismiss"
          onclick={onDismissNotice}
          type="button">&times;</button>
      {/if}
    </div>
  {/if}

  <div class="list">
    {#if sorted.length === 0}
      <div class="empty">No history yet.</div>
    {:else}
      {#each sorted as entry (entry.id)}
        <div
          aria-label="Load history entry"
          class="entry"
          onclick={(e) => onEntryClick(e, entry.id)}
          onkeydown={(e) => onEntryKey(e, entry.id)}
          role="button"
          tabindex="0">
          <button
            aria-label={entry.favorite ? "Unfavorite" : "Favorite"}
            class="star"
            class:active={entry.favorite}
            onclick={(e) => { e.stopPropagation(); onFavorite(entry.id); }}
            type="button">
            {#if entry.favorite}
              <svg viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 2L14.9389 7.95492L21.5106 8.90983L16.7553 13.5451L17.8779 20.0902L12 17L6.12215 20.0902L7.24472 13.5451L2.48944 8.90983L9.06108 7.95492L12 2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
              </svg>
            {:else}
              <svg viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg">
                <path d="M12 2L14.9389 7.95492L21.5106 8.90983L16.7553 13.5451L17.8779 20.0902L12 17L6.12215 20.0902L7.24472 13.5451L2.48944 8.90983L9.06108 7.95492L12 2Z" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"/>
              </svg>
            {/if}
          </button>

          <div class="meta">
            <div class="entry-title">{entry.title}</div>
            <div class="entry-time">{formatTimestamp(entry.timestamp)}</div>
          </div>

          <button
            aria-label="Remove entry"
            class="remove"
            onclick={(e) => { e.stopPropagation(); onRemove(entry.id); }}
            type="button">&times;</button>
        </div>
      {/each}
    {/if}
  </div>
</div>
