<script lang="ts">
  import { onMount } from 'svelte';
  import { Pencil, Check, X, Globe } from 'lucide-svelte';
  import type { AllowedDomain } from '$lib/types';
  import { confirmAction, alertAction } from '$lib/client/confirm.svelte';
  import { requireOnline } from '$lib/client/require-online';

  let domains = $state<AllowedDomain[]>([]);
  let loading = $state(true);
  let newDomain = $state('');
  let newLabel = $state('');
  let adding = $state(false);
  let errored = $state<string | null>(null);

  let editingId = $state<number | null>(null);
  let editDomain = $state('');
  let editLabel = $state('');
  let saving = $state(false);

  async function load() {
    const res = await fetch('/api/domains');
    domains = await res.json();
    loading = false;
  }

  async function add() {
    errored = null;
    if (!newDomain.trim()) return;
    if (!requireOnline('Das Hinzufügen')) return;
    adding = true;
    const res = await fetch('/api/domains', {
      method: 'POST',
      headers: { 'content-type': 'application/json' },
      body: JSON.stringify({
        domain: newDomain.trim(),
        display_name: newLabel.trim() || null
      })
    });
    adding = false;
    if (!res.ok) {
      const body = await res.json().catch(() => ({}));
      errored = body.message ?? `HTTP ${res.status}`;
      return;
    }
    newDomain = '';
    newLabel = '';
    await load();
  }

  function startEdit(d: AllowedDomain) {
    editingId = d.id;
    editDomain = d.domain;
    editLabel = d.display_name ?? '';
  }

  function cancelEdit() {
    editingId = null;
    editDomain = '';
    editLabel = '';
  }

  async function saveEdit(d: AllowedDomain) {
    if (!editDomain.trim()) return;
    if (!requireOnline('Das Speichern')) return;
    saving = true;
    try {
      const res = await fetch(`/api/domains/${d.id}`, {
        method: 'PATCH',
        headers: { 'content-type': 'application/json' },
        body: JSON.stringify({
          domain: editDomain.trim(),
          display_name: editLabel.trim() || null
        })
      });
      if (!res.ok) {
        const body = await res.json().catch(() => ({}));
        await alertAction({
          title: 'Speichern fehlgeschlagen',
          message: body.message ?? `HTTP ${res.status}`
        });
        return;
      }
      cancelEdit();
      await load();
    } finally {
      saving = false;
    }
  }

  async function remove(d: AllowedDomain) {
    const ok = await confirmAction({
      title: 'Domain entfernen?',
      message: `${d.domain} wird nicht mehr durchsucht. Gespeicherte Rezepte bleiben erhalten.`,
      confirmLabel: 'Entfernen',
      destructive: true
    });
    if (!ok) return;
    if (!requireOnline('Das Entfernen')) return;
    await fetch(`/api/domains/${d.id}`, { method: 'DELETE' });
    await load();
  }

  onMount(load);
</script>

<h1>Erlaubte Domains</h1>
<p class="intro">
  Nur Rezepte von diesen Domains können importiert werden. Jeder darf pflegen.
</p>

<form
  class="row"
  onsubmit={(e) => {
    e.preventDefault();
    void add();
  }}
>
  <input type="text" bind:value={newDomain} placeholder="chefkoch.de" required />
  <input type="text" bind:value={newLabel} placeholder="Anzeigename (optional)" />
  <button type="submit" class="btn primary" disabled={adding}>Hinzufügen</button>
</form>

{#if errored}
  <p class="error">{errored}</p>
{/if}

{#if loading}
  <p class="muted">Lädt…</p>
{:else if domains.length === 0}
  <p class="muted">Noch keine Domains. Füge Chefkoch, Emmi kocht einfach o.ä. hinzu.</p>
{:else}
  <ul class="list">
    {#each domains as d (d.id)}
      <li>
        {#if d.favicon_path}
          <img class="fav" src={`/images/${d.favicon_path}`} alt="" loading="lazy" />
        {:else}
          <span class="fav fallback" aria-hidden="true"><Globe size={18} strokeWidth={1.8} /></span>
        {/if}
        {#if editingId === d.id}
          <div class="edit-fields">
            <input
              type="text"
              bind:value={editDomain}
              placeholder="chefkoch.de"
              aria-label="Domain"
            />
            <input
              type="text"
              bind:value={editLabel}
              placeholder="Anzeigename (optional)"
              aria-label="Anzeigename"
            />
          </div>
          <div class="actions">
            <button
              class="btn primary icon-btn"
              aria-label="Speichern"
              disabled={saving}
              onclick={() => saveEdit(d)}
            >
              <Check size={18} strokeWidth={2} />
            </button>
            <button
              class="btn icon-btn"
              aria-label="Abbrechen"
              onclick={cancelEdit}
            >
              <X size={18} strokeWidth={2} />
            </button>
          </div>
        {:else}
          <div class="info">
            <div class="dom">{d.domain}</div>
            {#if d.display_name}<div class="label">{d.display_name}</div>{/if}
          </div>
          <div class="actions">
            <button
              class="btn icon-btn"
              aria-label="Bearbeiten"
              onclick={() => startEdit(d)}
            >
              <Pencil size={16} strokeWidth={2} />
            </button>
            <button class="btn danger" onclick={() => remove(d)}>Löschen</button>
          </div>
        {/if}
      </li>
    {/each}
  </ul>
{/if}

<style>
  h1 {
    font-size: 1.3rem;
    margin: 0 0 0.5rem;
  }
  .intro {
    color: #666;
    margin: 0 0 1rem;
    font-size: 0.95rem;
  }
  .row {
    display: flex;
    gap: 0.5rem;
    margin-bottom: 1rem;
    flex-wrap: wrap;
  }
  .row input {
    flex: 1;
    min-width: 140px;
    padding: 0.7rem 0.85rem;
    border: 1px solid #cfd9d1;
    border-radius: 10px;
    min-height: 44px;
    font-size: 1rem;
  }
  .btn {
    padding: 0.7rem 1rem;
    min-height: 44px;
    border-radius: 10px;
    border: 1px solid #cfd9d1;
    background: white;
    cursor: pointer;
    font-size: 0.95rem;
  }
  .btn.primary {
    background: #2b6a3d;
    color: white;
    border: 0;
  }
  .btn.primary:disabled {
    opacity: 0.6;
  }
  .btn.danger {
    color: #c53030;
    border-color: #f1b4b4;
  }
  .list {
    list-style: none;
    padding: 0;
    margin: 0;
    display: flex;
    flex-direction: column;
    gap: 0.5rem;
  }
  .list li {
    display: flex;
    align-items: center;
    gap: 0.75rem;
    background: white;
    border: 1px solid #e4eae7;
    border-radius: 12px;
    padding: 0.7rem 0.85rem;
  }
  .info {
    flex: 1;
    min-width: 0;
  }
  .dom {
    font-weight: 600;
  }
  .label {
    color: #888;
    font-size: 0.85rem;
  }
  .fav {
    width: 24px;
    height: 24px;
    border-radius: 4px;
    object-fit: contain;
    flex-shrink: 0;
  }
  .fav.fallback {
    background: #eef3ef;
    color: #8fb097;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .edit-fields {
    flex: 1;
    display: flex;
    gap: 0.5rem;
    min-width: 0;
    flex-wrap: wrap;
  }
  .edit-fields input {
    flex: 1;
    min-width: 120px;
    padding: 0.5rem 0.7rem;
    border: 1px solid #cfd9d1;
    border-radius: 8px;
    font-size: 0.95rem;
    min-height: 40px;
  }
  .actions {
    display: flex;
    gap: 0.4rem;
    flex-shrink: 0;
  }
  .icon-btn {
    min-width: 40px;
    padding: 0.5rem;
    display: inline-flex;
    align-items: center;
    justify-content: center;
  }
  .error {
    color: #c53030;
    margin-bottom: 1rem;
  }
  .muted {
    color: #888;
    text-align: center;
    padding: 2rem 0;
  }
</style>
