<script lang="ts">
import { onMount } from "svelte";
import { browser } from "$app/environment";
import { page } from "$app/stores";
import RateLimitedError from "$lib/Error/RateLimited.svelte";
import Message from "$lib/Loading/Message.svelte";
import Skeleton from "$lib/Loading/Skeleton.svelte";
import tooltip from "$lib/Tooltip/tooltip";
import locale from "$stores/locale";
import settings from "$stores/settings";
import { clearAllParameters, parseOrDefault } from "../Utility/parameters";

interface Birthday {
	birth_day: number;
	birth_month: number;
	game_id: number;
	id: number;
	name_en: string;
	name_jp: string;
	preferred_url: string;
	sns_icon: string;
}

const urlParameters = browser
	? new URLSearchParams(window.location.search)
	: null;
let date = new Date();
let month = parseOrDefault(urlParameters, "month", date.getMonth() + 1);
let day = parseOrDefault(urlParameters, "day", date.getDate());
let umapyoi: Promise<Birthday[]>;

$: {
	month = Math.min(month, 12);
	month = Math.max(month, 1);
	day = Math.min(day, new Date(new Date().getFullYear(), month, 0).getDate());
	day = Math.max(day, 1);

	if (browser) {
		$page.url.searchParams.set("month", month.toString());
		$page.url.searchParams.set("day", day.toString());
		clearAllParameters(["month", "day"]);
		history.replaceState(null, "", `?${$page.url.searchParams.toString()}`);
	}
}

onMount(() => {
	clearAllParameters(["month", "day"]);

	umapyoi = fetch("https://umapyoi.net/api/v1/character/birthday").then((r) =>
		r.json(),
	);
});
</script>

{#await umapyoi}
  <Message message="Loading birthdays ..." />

  <Skeleton grid={true} count={100} width="150px" height="170px" />
{:then birthdays}
  {#if birthdays}
    {@const todaysBirthdays = birthdays.filter(
      (birthday) => birthday.birth_month === month && birthday.birth_day === day
    )}

    <p>
      <select bind:value={month}>
        {#each Array.from({ length: 12 }, (_, i) => i + 1) as month}
          <option value={month}>
            {new Date(0, month - 1).toLocaleString('default', { month: 'long' })}
          </option>
        {/each}
      </select>

      <select bind:value={day}>
        {#each Array.from({ length: new Date(new Date().getFullYear(), month, 0).getDate() }, (_, i) => i + 1) as day}
          <option value={day}>{day}</option>
        {/each}
      </select>
    </p>

    {#if todaysBirthdays.length === 0}
      <Message
        message={`No birthdays for ${$locale().dayFormatter(
          new Date(new Date().getFullYear(), month - 1, day)
        )}.`}
        fullscreen={false}
        loader="ripple"
      />
    {:else}
      <div class="characters">
        {#each todaysBirthdays as birthday}
          {@const name = $settings.displayLanguage === 'en' ? birthday.name_en : birthday.name_jp}
          {@const nameOther =
            $settings.displayLanguage === 'ja' ? birthday.name_en : birthday.name_jp}

          <div class="card card-small">
            <a
              href={`https://anilist.co/search/characters?search=${encodeURIComponent(
                birthday.name_en
              ).replace(/%20/g, '+')}`}
              target="_blank"
              title={nameOther}
              use:tooltip
            >
              {name}
              <img
                src={birthday.sns_icon}
                alt=""
                class="character-image"
                loading="lazy"
                decoding="async"
              />
            </a>
          </div>
        {/each}
      </div>
    {/if}
  {:else}
    <Message message="Validating birthdays ..." />

    <Skeleton grid={true} count={100} width="150px" height="170px" />
  {/if}
{:catch}
  <RateLimitedError type="Character" card />
{/await}

<style lang="scss">
  .characters {
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(9rem, 1fr));
    gap: 1rem;
    grid-row-gap: 1rem;
    align-items: start;

    img {
      width: 100%;
      height: auto;
      aspect-ratio: 300 / 413;
      object-fit: cover;
      object-position: top;
      border-radius: 8px;
      margin-top: 0.5rem;
      box-shadow: 0 4px 30px var(--base01);
    }
  }
</style>
