<script lang="ts">
  import { goto } from '$app/navigation';
  import {
    Camera,
    Loader2,
    Wand2,
    AlertTriangle,
    RotateCw,
    FilePlus,
    X
  } from 'lucide-svelte';
  import RecipeEditor from '$lib/components/RecipeEditor.svelte';
  import { PhotoUploadStore } from '$lib/client/photo-upload.svelte';
  import { alertAction } from '$lib/client/confirm.svelte';
  import { network } from '$lib/client/network.svelte';
  import type { Recipe, Ingredient, Step } from '$lib/types';

  const store = new PhotoUploadStore();
  let saving = $state(false);
  let fileInput = $state<HTMLInputElement | null>(null);

  function onPick(e: Event) {
    const file = (e.target as HTMLInputElement).files?.[0];
    if (file) void store.upload(file);
  }

  type SavePatch = {
    title: string;
    description: string | null;
    servings_default: number | null;
    prep_time_min: number | null;
    cook_time_min: number | null;
    total_time_min: number | null;
    ingredients: Ingredient[];
    steps: Step[];
  };

  async function onSave(patch: SavePatch) {
    if (!store.recipe) return;
    saving = true;
    try {
      const body = {
        title: patch.title,
        description: patch.description,
        servings_default: patch.servings_default,
        servings_unit: store.recipe.servings_unit,
        prep_time_min: patch.prep_time_min,
        cook_time_min: patch.cook_time_min,
        total_time_min: patch.total_time_min,
        ingredients: patch.ingredients,
        steps: patch.steps
      };
      const res = await fetch('/api/recipes', {
        method: 'POST',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify(body)
      });
      if (!res.ok) {
        const err = await res.json().catch(() => ({}));
        await alertAction({
          title: 'Speichern fehlgeschlagen',
          message: err.message ?? `HTTP ${res.status}`
        });
        return;
      }
      const { id } = await res.json();
      await goto(`/recipes/${id}`);
    } finally {
      saving = false;
    }
  }

  function onCancel() {
    history.back();
  }
</script>

<svelte:head><title>Rezept aus Foto — Kochwas</title></svelte:head>

{#if store.status === 'idle'}
  <section class="picker">
    <Camera size={48} strokeWidth={1.5} />
    <h1>Rezept aus Foto</h1>
    <p class="hint">
      Fotografiere ein gedrucktes oder handgeschriebenes Rezept. Eine Seite,
      scharf, gut ausgeleuchtet.
    </p>
    <button
      type="button"
      class="btn primary"
      onclick={() => fileInput?.click()}
      disabled={!network.online}
    >
      <Camera size={18} strokeWidth={2} />
      <span>Foto wählen oder aufnehmen</span>
    </button>
    <!-- Ohne `capture`-Attribut: Browser zeigt auf Mobile die volle Auswahl
         (Kamera / Fotomediathek / Datei), statt direkt die Kamera zu oeffnen. -->
    <input
      bind:this={fileInput}
      type="file"
      accept="image/*"
      hidden
      onchange={onPick}
    />
    {#if !network.online}
      <p class="offline">Offline — diese Funktion braucht Internet.</p>
    {/if}
  </section>
{:else if store.status === 'loading'}
  <section class="state" aria-live="polite">
    <div class="spin"><Loader2 size={48} /></div>
    <p>Lese das Rezept…</p>
    <button type="button" class="btn ghost" onclick={() => store.abort()}>
      <X size={18} /><span>Abbrechen</span>
    </button>
  </section>
{:else if store.status === 'error'}
  {#if store.errorCode === 'NO_RECIPE_IN_IMAGE'}
    <section class="state yellow" role="alert">
      <AlertTriangle size={40} />
      <h2>Kein Rezept im Bild</h2>
      <p>Ich konnte auf dem Foto kein Rezept erkennen.</p>
      <div class="row">
        <button
          type="button"
          class="btn primary"
          onclick={() => {
            store.reset();
            fileInput?.click();
          }}
        >
          <Camera size={18} /><span>Anderes Foto</span>
        </button>
        <a class="btn ghost" href="/">
          <FilePlus size={18} /><span>Startseite</span>
        </a>
      </div>
    </section>
  {:else}
    <section class="state red" role="alert">
      <AlertTriangle size={40} />
      <h2>Fehler</h2>
      <p>{store.errorMessage ?? 'Unbekannter Fehler.'}</p>
      <div class="row">
        <button type="button" class="btn primary" onclick={() => store.retry()}>
          <RotateCw size={18} /><span>Nochmal versuchen</span>
        </button>
        <button type="button" class="btn ghost" onclick={() => store.reset()}>
          <Camera size={18} /><span>Anderes Foto</span>
        </button>
      </div>
    </section>
  {/if}
{:else if store.status === 'success' && store.recipe}
  <div class="banner">
    <Wand2 size={18} />
    <span>Aus Foto erstellt — bitte prüfen und ggf. korrigieren.</span>
  </div>
  <RecipeEditor
    recipe={store.recipe as Recipe}
    {saving}
    onsave={onSave}
    oncancel={onCancel}
  />
{/if}

<style>
  .picker,
  .state {
    text-align: center;
    padding: 3rem 1rem;
    display: flex;
    flex-direction: column;
    align-items: center;
    gap: 1rem;
  }
  .hint {
    color: #666;
    max-width: 400px;
    line-height: 1.45;
  }
  .btn {
    padding: 0.8rem 1.1rem;
    min-height: 48px;
    border-radius: 10px;
    cursor: pointer;
    font-size: 1rem;
    border: 0;
    text-decoration: none;
    display: inline-flex;
    align-items: center;
    gap: 0.4rem;
  }
  .btn.primary {
    background: #2b6a3d;
    color: white;
  }
  .btn.primary:disabled {
    opacity: 0.6;
    cursor: not-allowed;
  }
  .btn.ghost {
    background: white;
    color: #444;
    border: 1px solid #cfd9d1;
  }
  .row {
    display: flex;
    gap: 0.5rem;
    flex-wrap: wrap;
    justify-content: center;
  }
  .state.yellow {
    background: #fff6d7;
    border: 1px solid #e6d48a;
    border-radius: 12px;
  }
  .state.red {
    background: #fde4e4;
    border: 1px solid #e6a0a0;
    border-radius: 12px;
  }
  .banner {
    display: flex;
    align-items: center;
    gap: 0.5rem;
    padding: 0.7rem 1rem;
    background: #eef8ef;
    border: 1px solid #b7d9c0;
    border-radius: 10px;
    margin: 0.75rem 0 1rem;
    color: #2b6a3d;
  }
  .spin {
    animation: spin 1s linear infinite;
    display: inline-flex;
  }
  @keyframes spin {
    to {
      transform: rotate(360deg);
    }
  }
  .offline {
    color: #a05b00;
    font-size: 0.9rem;
  }
</style>
