<script lang="ts">
  import { page } from "$app/state";
  import { goto } from "$app/navigation";
  import { createQuery, useQueryClient } from "@tanstack/svelte-query";
  import { createMealFromPreset } from "$lib/api/meals";
  import { offlineAddMeal } from "$lib/offline/mutations";
  import { network } from "$lib/offline/network.svelte";
  import { listPresets } from "$lib/api/presets";
  import type { Preset } from "$lib/types/api";
  import TopBar from "$lib/components/ui/TopBar.svelte";
  import { kcal, g } from "$lib/utils/format";
  import { today } from "$lib/utils/date";

  const date = $derived(
    page.params.date === "today" ? today() : page.params.date!,
  );
  const queryClient = useQueryClient();

  type Tab = "new" | "preset";
  let tab = $state<Tab>("new");
  let mealName = $state("");
  let presetQ = $state("");
  let presetDebounced = $state("");
  let presetTimer: ReturnType<typeof setTimeout>;
  let submitting = $state(false);
  let error = $state("");
  let mealNameInput = $state<HTMLInputElement | null>(null);
  let presetQInput = $state<HTMLInputElement | null>(null);

  $effect(() => {
    if (tab === "new") setTimeout(() => mealNameInput?.focus(), 50);
    else setTimeout(() => presetQInput?.focus(), 50);
  });

  function handlePresetSearch(v: string) {
    presetQ = v;
    clearTimeout(presetTimer);
    presetTimer = setTimeout(() => {
      presetDebounced = v;
    }, 300);
  }

  const presetsQuery = createQuery(() => ({
    queryKey: ["presets"],
    queryFn: () => listPresets(30),
  }));

  async function handleCreateNew(e: SubmitEvent) {
    e.preventDefault();
    submitting = true;
    try {
      await offlineAddMeal(queryClient, date, mealName);
      goto(`/diary/${date}`);
    } catch {
      // mutation was queued offline — navigate back anyway
      goto(`/diary/${date}`);
    } finally {
      submitting = false;
    }
  }

  async function handleFromPreset(preset: Preset) {
    submitting = true;
    error = "";
    try {
      await createMealFromPreset(date, preset.id, preset.name);
      await queryClient.invalidateQueries({ queryKey: ["diary", date] });
      goto(`/diary/${date}`);
    } catch {
      error = "Failed to add preset";
      submitting = false;
    }
  }
</script>

<div class="flex flex-col h-screen">
  <TopBar title="Add meal" back="/diary/{date}" />

  <!-- Tabs -->
  <div class="flex border-b border-zinc-800 bg-zinc-950">
    {#each [{ id: "new", label: "New meal" }, { id: "preset", label: "From preset", offlineDisabled: true }] as t}
      <button
        onclick={() => (tab = t.id as Tab)}
        disabled={t.offlineDisabled && !network.online}
        class="flex-1 py-3 text-sm font-medium transition-colors border-b-2 disabled:opacity-40 {tab ===
        t.id
          ? 'border-green-500 text-green-400'
          : 'border-transparent text-zinc-500 hover:text-zinc-300'}"
      >
        {t.label}
      </button>
    {/each}
  </div>

  <main class="flex-1 overflow-y-auto">
    {#if tab === "new"}
      <form onsubmit={handleCreateNew} class="px-4 py-6 space-y-4">
        <div>
          <label for="meal-name" class="block text-sm text-zinc-400 mb-2"
            >Meal name <span class="text-zinc-600">(optional)</span></label
          >
          <input
            bind:this={mealNameInput}
            id="meal-name"
            type="text"
            bind:value={mealName}
            placeholder="e.g. Breakfast, Lunch…"
            autofocus
            class="w-full bg-zinc-900 border border-zinc-700 rounded-xl px-4 py-3 text-zinc-100 placeholder-zinc-600 focus:outline-none focus:border-green-500 transition-colors"
          />
        </div>
        <button
          type="submit"
          disabled={submitting}
          class="w-full bg-green-600 hover:bg-green-500 disabled:opacity-50 rounded-xl py-3 font-semibold transition-colors"
        >
          {submitting
            ? "Creating…"
            : network.online
              ? "Create meal"
              : "Create meal (offline)"}
        </button>
      </form>
    {:else}
      <!-- Preset search -->
      <div class="px-4 py-3 border-b border-zinc-800">
        <input
          bind:this={presetQInput}
          type="search"
          placeholder="Search presets…"
          value={presetQ}
          oninput={(e) => handlePresetSearch(e.currentTarget.value)}
          autofocus
          class="w-full bg-zinc-900 border border-zinc-700 rounded-xl px-4 py-2.5 text-sm text-zinc-100 placeholder-zinc-500 focus:outline-none focus:border-green-500 transition-colors"
        />
      </div>

      {#if error}
        <p class="text-red-400 text-sm px-4 pt-3">{error}</p>
      {/if}

      {#if presetsQuery.isPending}
        <div class="space-y-2 p-4">
          {#each Array(4) as _}
            <div class="h-16 bg-zinc-900 rounded-xl animate-pulse"></div>
          {/each}
        </div>
      {:else if (presetsQuery.data ?? []).filter((p) => !presetDebounced || p.name
            .toLowerCase()
            .includes(presetDebounced.toLowerCase())).length === 0}
        <div class="text-center text-zinc-500 mt-16 px-6">
          <p>No presets yet</p>
          <p class="text-sm mt-1">Save a meal as preset from the diary view</p>
        </div>
      {:else}
        <ul class="divide-y divide-zinc-800/50">
          {#each (presetsQuery.data ?? []).filter((p) => !presetDebounced || p.name
                .toLowerCase()
                .includes(presetDebounced.toLowerCase())) as preset (preset.id)}
            <li>
              <button
                onclick={() => handleFromPreset(preset)}
                disabled={submitting}
                class="w-full flex items-center justify-between px-4 py-4 hover:bg-zinc-900 transition-colors text-left disabled:opacity-50"
              >
                <div>
                  <p class="font-medium">{preset.name}</p>
                  <p class="text-xs text-zinc-500 mt-0.5">
                    {kcal(preset.calories)} kcal · P {g(preset.protein)}g · C {g(
                      preset.carb,
                    )}g · F {g(preset.fat)}g
                  </p>
                </div>
                <svg
                  class="w-4 h-4 text-zinc-600 ml-3 shrink-0"
                  fill="none"
                  stroke="currentColor"
                  viewBox="0 0 24 24"
                >
                  <path
                    stroke-linecap="round"
                    stroke-linejoin="round"
                    stroke-width="2"
                    d="M12 4v16m8-8H4"
                  />
                </svg>
              </button>
            </li>
          {/each}
        </ul>
      {/if}
    {/if}
  </main>
</div>
