<!-- Fixed header that is shown when scrolling down -->
<script lang="ts">
  import LL from "$i18n/i18n-svelte";
  import { page } from "$app/stores";
  import { beforeNavigate } from "$app/navigation";
  import { mdiBellOutline, mdiClose, mdiHistory, mdiPlay } from "@mdi/js";
  import { kbd } from "@melt-ui/svelte/internal/helpers";

  import { clamp, isExcluded } from "$lib/util/functions";
  import { headerColor, headerHeight, searchTerm } from "$lib/stores/layout";
  import { iconSearch } from "$lib/util/icons";

  import IconButton from "$lib/components/ui/IconButton.svelte";
  import Icon from "$lib/components/ui/Icon.svelte";
  import { SearchCtx } from "$lib/util/types";
  import { CLEAR_SEARCH, registerHandler } from "$lib/util/events";
  import UserMenuButton from "./UserMenuButton.svelte";

  export let scrollPos = 0;

  let headerElm: HTMLElement;

  $: homeScreen = $page.route.id === "/" || $page.route.id === null;
  let title: string;
  $: {
    const t = $page.data.header?.title;
    if (typeof t === "function") {
      title = t();
    } else if (t) {
      title = t;
    } else {
      title = $LL.app_name();
    }
  }
  $: searchCtx = $page.data.header?.searchCtx;

  let fading = false;
  $: fading = $page.data.header?.fading;

  let hh = 0;
  $: hh = Math.max($headerHeight - 30, 0);
  let hthresh = 0;
  $: hthresh = hh / 2;

  let searchActivate = false;
  let searchShow = false;
  $: searchShow =
    Boolean($searchTerm) || searchActivate || searchCtx === SearchCtx.Global;

  let opacity = 0;
  $: opacity = fading
    ? Math.max(
        (clamp(scrollPos, hthresh, hh) - hthresh) / Math.max(hthresh, 1),
        Number(searchShow) * 0.5
      )
    : 1;

  let bgcolor = "oklch(var(--b2)";
  $: if ($headerColor) {
    bgcolor = `rgb(${$headerColor.r}, ${$headerColor.g}, ${$headerColor.b}, ${opacity})`;
  } else {
    bgcolor = `oklch(var(--b2) / ${opacity})`;
  }

  let inputElm: HTMLInputElement;

  $: if (inputElm && searchShow) inputElm.focus();

  let searchLabel: string;
  $: if (searchCtx) {
    if (searchCtx === SearchCtx.Global) searchLabel = $LL.search();
    else searchLabel = $LL.search_item(title);
  }

  function searchOnBlur(e: FocusEvent) {
    // Hide the search bar on unfocus, unless it is active or
    // the click happened within the header bar
    if (!$searchTerm && !isExcluded(e.relatedTarget, headerElm)) {
      searchActivate = false;
    }
  }

  function clearSearch() {
    $searchTerm = "";
    searchActivate = false;
  }

  beforeNavigate(clearSearch);

  registerHandler(CLEAR_SEARCH, () => clearSearch());
</script>

<svelte:head>
  <title>{title}</title>
</svelte:head>

<div
  class="w-full h-full px-2 flex gap-2 items-center relative"
  style="background-color: {bgcolor}"
  bind:this={headerElm}
>
  <div class="flex gap-2 items-center flex-grow">
    {#if searchShow}
      <Icon path={iconSearch} />
      <input
        type="text"
        placeholder={searchLabel}
        aria-label={searchLabel}
        bind:this={inputElm}
        bind:value={$searchTerm}
        on:keydown={(e) => {
          if (e.key === kbd.ESCAPE) {
            clearSearch();
          }
        }}
        on:blur={searchOnBlur}
      />
    {:else if !fading || scrollPos > 0.8 * hh}
      {#if $page.data.header?.playLink}
        <IconButton
          path={mdiPlay}
          ariaLabel={$LL.play_item(title)}
          color="primary"
          on:click={() => alert("Playing " + title)}
        />
      {/if}

      {#if homeScreen}
        <img src="/favicon.svg" alt="" height="32" width="32" />
      {/if}

      <h1 class="text-2xl font-bold ellipsis-ol">{title}</h1>
    {/if}
  </div>

  <div class="flex gap-1 items-center">
    {#if homeScreen}
      <IconButton path={mdiBellOutline} ariaLabel={$LL.notifications()} />
      <IconButton path={mdiHistory} ariaLabel={$LL.playback_history()} />
    {/if}
    {#if searchCtx}
      <IconButton
        path={searchShow ? mdiClose : iconSearch}
        ariaLabel={searchShow ? $LL.clear_search() : searchLabel}
        on:click={() => {
          if (searchShow) {
            clearSearch();
          } else {
            searchActivate = true;
          }
        }}
      />
    {/if}
    <UserMenuButton />
  </div>
</div>

<style lang="postcss">
  input {
    width: 100%;

    background-color: transparent;
    outline: none;
    border-bottom: solid 2px;
    @apply border-base-content;
  }

  ::placeholder {
    @apply text-base-content/70;
  }
</style>
