<script lang="ts">
  import { onMount } from 'svelte';
  import { goto } from '$app/navigation';
  import type { SearchHit } from '$lib/server/recipes/search-local';
  import type { WebHit } from '$lib/server/search/searxng';

  let query = $state('');
  let recent = $state<SearchHit[]>([]);
  let hits = $state<SearchHit[]>([]);
  let webHits = $state<WebHit[]>([]);
  let searching = $state(false);
  let webSearching = $state(false);
  let webError = $state<string | null>(null);
  let searchedFor = $state<string | null>(null);

  onMount(async () => {
    const res = await fetch('/api/recipes/search');
    const body = await res.json();
    recent = body.hits;
  });

  let debounceTimer: ReturnType<typeof setTimeout> | null = null;

  $effect(() => {
    const q = query.trim();
    if (debounceTimer) clearTimeout(debounceTimer);
    if (q.length <= 3) {
      hits = [];
      webHits = [];
      searchedFor = null;
      searching = false;
      webSearching = false;
      webError = null;
      return;
    }
    searching = true;
    webHits = [];
    webSearching = false;
    webError = null;
    debounceTimer = setTimeout(async () => {
      try {
        const res = await fetch(`/api/recipes/search?q=${encodeURIComponent(q)}`);
        const body = await res.json();
        if (query.trim() !== q) return;
        hits = body.hits;
        searchedFor = q;
        if (body.hits.length === 0) {
          webSearching = true;
          try {
            const wres = await fetch(`/api/recipes/search/web?q=${encodeURIComponent(q)}`);
            if (query.trim() !== q) return;
            if (!wres.ok) {
              const err = await wres.json().catch(() => ({}));
              webError = err.message ?? `HTTP ${wres.status}`;
            } else {
              const wbody = await wres.json();
              webHits = wbody.hits;
            }
          } finally {
            if (query.trim() === q) webSearching = false;
          }
        }
      } finally {
        if (query.trim() === q) searching = false;
      }
    }, 300);
  });

  function submit(e: SubmitEvent) {
    e.preventDefault();
    const q = query.trim();
    if (!q) return;
    void goto(`/search?q=${encodeURIComponent(q)}`);
  }

  const activeSearch = $derived(query.trim().length > 3);
</script>

<section class="hero">
  <h1>Kochwas</h1>
  <form onsubmit={submit}>
    <input
      type="search"
      bind:value={query}
      placeholder="Rezept suchen…"
      autocomplete="off"
      inputmode="search"
      aria-label="Suchbegriff"
    />
  </form>
</section>

{#if activeSearch}
  <section class="results">
    {#if searching && hits.length === 0}
      <p class="muted">Suche läuft …</p>
    {:else if hits.length > 0}
      <ul class="cards">
        {#each hits as r (r.id)}
          <li>
            <a href={`/recipes/${r.id}`} class="card">
              {#if r.image_path}
                <img src={`/images/${r.image_path}`} alt="" loading="lazy" />
              {:else}
                <div class="placeholder">🥘</div>
              {/if}
              <div class="card-body">
                <div class="title">{r.title}</div>
                {#if r.source_domain}
                  <div class="domain">{r.source_domain}</div>
                {/if}
              </div>
            </a>
          </li>
        {/each}
      </ul>
      <a class="web-more" href={`/search/web?q=${encodeURIComponent(query.trim())}`}>
        🌐 Im Internet weitersuchen
      </a>
    {:else if searchedFor === query.trim()}
      <p class="muted no-local-msg">Keine lokalen Rezepte für „{searchedFor}" — Ergebnisse aus dem Internet:</p>
      {#if webSearching}
        <p class="muted">Suche im Internet läuft …</p>
      {:else if webError}
        <p class="error">Internet-Suche zurzeit nicht möglich: {webError}</p>
      {:else if webHits.length > 0}
        <ul class="cards">
          {#each webHits as w (w.url)}
            <li>
              <a class="card" href={`/preview?url=${encodeURIComponent(w.url)}`}>
                {#if w.thumbnail}
                  <img src={w.thumbnail} alt="" loading="lazy" />
                {:else}
                  <div class="placeholder">🍽️</div>
                {/if}
                <div class="card-body">
                  <div class="title">{w.title}</div>
                  <div class="domain">{w.domain}</div>
                </div>
              </a>
            </li>
          {/each}
        </ul>
      {:else}
        <p class="muted">Auch im Internet nichts gefunden.</p>
      {/if}
    {/if}
  </section>
{:else if recent.length > 0}
  <section class="recent">
    <h2>Zuletzt hinzugefügt</h2>
    <ul class="cards">
      {#each recent as r (r.id)}
        <li>
          <a href={`/recipes/${r.id}`} class="card">
            {#if r.image_path}
              <img src={`/images/${r.image_path}`} alt="" loading="lazy" />
            {:else}
              <div class="placeholder">🥘</div>
            {/if}
            <div class="card-body">
              <div class="title">{r.title}</div>
              {#if r.source_domain}
                <div class="domain">{r.source_domain}</div>
              {/if}
            </div>
          </a>
        </li>
      {/each}
    </ul>
  </section>
{/if}

<style>
  .hero {
    text-align: center;
    padding: 3rem 0 1.5rem;
  }
  .hero h1 {
    font-size: clamp(2.2rem, 8vw, 3.5rem);
    margin: 0 0 1.5rem;
    color: #2b6a3d;
    letter-spacing: -0.02em;
  }
  form {
    display: flex;
    gap: 0.5rem;
  }
  input[type='search'] {
    flex: 1;
    padding: 0.9rem 1rem;
    font-size: 1.1rem;
    border: 1px solid #cfd9d1;
    border-radius: 10px;
    background: white;
    min-height: 48px;
  }
  input[type='search']:focus {
    outline: 2px solid #2b6a3d;
    outline-offset: 1px;
  }
  .results,
  .recent {
    margin-top: 1.5rem;
  }
  .recent h2 {
    font-size: 1.05rem;
    color: #444;
    margin: 0 0 0.75rem;
  }
  .muted {
    color: #888;
    text-align: center;
    padding: 1rem 0;
  }
  .no-local-msg {
    font-size: 0.95rem;
    padding: 0.25rem 0 1rem;
  }
  .error {
    color: #c53030;
    text-align: center;
    padding: 1rem 0;
  }
  .cards {
    list-style: none;
    padding: 0;
    margin: 0;
    display: grid;
    grid-template-columns: repeat(auto-fill, minmax(220px, 1fr));
    gap: 0.75rem;
  }
  .card {
    display: block;
    background: white;
    border: 1px solid #e4eae7;
    border-radius: 14px;
    overflow: hidden;
    text-decoration: none;
    color: inherit;
    transition: transform 0.1s;
  }
  .card:active {
    transform: scale(0.98);
  }
  .card img,
  .placeholder {
    width: 100%;
    aspect-ratio: 4 / 3;
    object-fit: cover;
    background: #eef3ef;
    display: grid;
    place-items: center;
    font-size: 2rem;
  }
  .card-body {
    padding: 0.6rem 0.75rem 0.75rem;
  }
  .title {
    font-weight: 600;
    font-size: 0.95rem;
    line-height: 1.25;
  }
  .domain {
    font-size: 0.8rem;
    color: #888;
    margin-top: 0.25rem;
  }
  .web-more {
    display: inline-block;
    margin-top: 1rem;
    padding: 0.7rem 1.1rem;
    border: 1px solid #b7d6c2;
    border-radius: 10px;
    text-decoration: none;
    color: #2b6a3d;
    background: #eaf4ed;
    font-size: 0.95rem;
  }
  .web-more:hover {
    background: #d8e8df;
  }
</style>
