<script lang="ts">
  import { folders } from "$lib/stores/folders.svelte";

  interface Tab {
    id: number | null;
    title: string;
  }

  const tabs = $derived<Tab[]>([
    { id: null, title: "All Chats" },
    ...folders.list.map((folder) => ({
      id: folder.folder_id,
      title: folder.title,
    })),
  ]);

  const activeTab = $derived(
    Math.max(
      0,
      tabs.findIndex((tab) => tab.id === folders.selectedId)
    )
  );

  let containerEl = $state<HTMLDivElement>();
  let indicatorEl = $state<HTMLDivElement>();
  let clipPath = $state("");

  function updateClipPath() {
    const indicator = indicatorEl;
    const activeEl = indicator?.children[activeTab] as HTMLElement | undefined;
    if (!(indicator && activeEl) || indicator.offsetWidth === 0) {
      return;
    }
    const { offsetLeft, offsetWidth } = activeEl;
    const width = indicator.offsetWidth;
    const left = ((offsetLeft / width) * 100).toFixed(1);
    const right = (
      ((width - (offsetLeft + offsetWidth)) / width) *
      100
    ).toFixed(1);
    clipPath = `inset(0.25rem ${right}% 0.25rem ${left}% round var(--tab-radius))`;
  }

  $effect(() => {
    const index = activeTab;
    const total = tabs.length;
    updateClipPath();
    const baseEl =
      total > 0
        ? (containerEl?.children[index] as HTMLElement | undefined)
        : undefined;
    baseEl?.scrollIntoView({ block: "nearest", inline: "nearest" });
  });

  $effect(() => {
    if (!indicatorEl) {
      return;
    }
    const observer = new ResizeObserver(() => updateClipPath());
    observer.observe(indicatorEl);
    return () => observer.disconnect();
  });
</script>

<div bind:this={containerEl} class="container" class:ready={clipPath !== ""}>
  {#each tabs as tab (tab.id)}
    <button type="button" class="tab" onclick={() => folders.select(tab.id)}>
      {tab.title}
    </button>
  {/each}

  <div
    bind:this={indicatorEl}
    class="active-indicator"
    style={clipPath ? `clip-path: ${clipPath}` : undefined}
    aria-hidden="true"
  >
    {#each tabs as tab (tab.id)}
      <button type="button" class="tab" tabindex="-1">{tab.title}</button>
    {/each}
  </div>
</div>

<style lang="scss">
  .container,
  .active-indicator {
    display: flex;
    flex-shrink: 0;
    flex-wrap: nowrap;
    align-items: center;

    padding-block: 0.375rem;
    padding-inline: 0.25rem;
  }

  .container {
    --tab-radius: 1.25rem;

    user-select: none;
    scrollbar-width: none;

    position: relative;

    overflow-x: auto;

    border-radius: 1.5rem;

    opacity: 0;
    background-color: var(--color-background);
    box-shadow: 0 1px 8px 0 rgba(0, 0, 0, 0.1);

    transition: opacity 150ms;

    &::-webkit-scrollbar {
      display: none;
    }

    &.ready {
      opacity: 1;
    }
  }

  .active-indicator {
    pointer-events: none;
    will-change: clip-path;

    isolation: isolate;
    position: absolute;
    z-index: 10;
    inset: 0;

    contain: layout style paint;
    overflow: hidden;

    width: fit-content;

    background-color: var(--color-primary-opacity);

    transition: clip-path var(--slide-transition);
  }

  .tab {
    cursor: var(--custom-cursor, pointer);

    display: flex;
    flex-shrink: 0;
    gap: 0.25rem;
    align-items: center;

    padding: 0.375rem 1rem;
    border: none;
    border-radius: var(--tab-radius);

    font-family: inherit;
    font-size: 1rem;
    font-weight: var(--font-weight-medium);
    color: var(--color-text-secondary);
    white-space: nowrap;

    appearance: none;
    background: none;

    &:hover {
      opacity: 0.85;
    }

    .active-indicator & {
      color: var(--color-primary);
    }
  }
</style>
