"use client";

import { useEffect, useMemo, useState } from 'react';
import { motion, AnimatePresence } from 'motion/react';
import { ToggleChipBar } from '@/components/toggle-chip-bar';
import { CUISINE_OPTIONS, guessCuisineChipsFromRaw } from '@/lib/cuisine';

interface Sponsor {
  id: number;
  restaurant_id: number | null;
  name: string;
  image_url: string | null;
  address: string | null;
  city: string | null;
  postal_code: string | null;
  lat: number | null;
  lon: number | null;
  filter_cuisine_tags: string | null;
  discount_text: string | null;
  priority: number;
  active: number;
  active_from: string | null;
  active_until: string | null;
}

interface SearchResult {
  restaurantId: number;
  name: string;
  address: string | null;
  postalCode: string | null;
  lat: number;
  lon: number;
  cuisine: string | null;
  phone: string | null;
  website: string | null;
  openingHoursRaw: string | null;
}

const DIET_OPTIONS = [
  { value: 'vegan', label: 'Vegan', variant: 'diet' as const },
  { value: 'vegetarian', label: 'Vegetarisch', variant: 'diet' as const },
  { value: 'gluten_free', label: 'Glutenfrei', variant: 'diet' as const },
  { value: 'halal', label: 'Halal', variant: 'diet' as const },
  { value: 'kosher', label: 'Koscher', variant: 'diet' as const },
];

const EMPTY_FORM = {
  id: null as number | null,
  name: '', imageUrl: '', address: '', city: '', postalCode: '',
  lat: '', lon: '', discountText: '', priority: 0,
  active: true, activeFrom: '', activeUntil: '',
  cuisineTags: [] as string[], dietTags: [] as string[],
  disclaimerText: '', openingHoursRaw: '',
  reservationUrl: '', lieferandoUrl: '',
  restaurantId: null as number | null,
};

function boostLabelFromPriority(priority: number): string {
  if (priority >= 8) return 'Boost 3x';
  if (priority >= 4) return 'Boost 2x';
  return 'Boost 1x';
}

const INPUT_CLS =
  'bg-[#f8f9fa] rounded-xl px-4 py-3 border border-[#e5e7eb] focus:border-yumder-pink focus:ring-2 focus:ring-pink-100 outline-none text-admintext transition-colors';

function FormSection({ title, children }: { title: string; children: React.ReactNode }) {
  return (
    <div className="flex flex-col gap-3">
      <p className="text-xs font-bold uppercase tracking-wide text-yumder-pink">{title}</p>
      <div className="flex flex-col gap-3">{children}</div>
    </div>
  );
}

export function SponsorFormModal({
  sponsorToEdit,
  onClose,
  onSaved,
}: {
  sponsorToEdit: Sponsor | null;
  onClose: () => void;
  onSaved: () => void;
}) {
  const [form, setForm] = useState(EMPTY_FORM);
  const [saving, setSaving] = useState(false);
  const [uploading, setUploading] = useState(false);
  const [previewUrl, setPreviewUrl] = useState<string | null>(null);
  const [imageBroken, setImageBroken] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const [searchCity, setSearchCity] = useState('');
  const [searchRadiusKm, setSearchRadiusKm] = useState(5);
  const [searchResults, setSearchResults] = useState<SearchResult[]>([]);
  const [searching, setSearching] = useState(false);
  const [searchError, setSearchError] = useState<string | null>(null);
  const [linkedName, setLinkedName] = useState<string | null>(null);
  const [nameFilter, setNameFilter] = useState('');
  const [linkedPhone, setLinkedPhone] = useState<string | null>(null);
  const [linkedWebsite, setLinkedWebsite] = useState<string | null>(null);

  useEffect(() => {
    if (!sponsorToEdit) {
      setForm(EMPTY_FORM);
      setSearchCity('');
      setLinkedName(null);
    } else {
      const allTags: string[] = sponsorToEdit.filter_cuisine_tags ? JSON.parse(sponsorToEdit.filter_cuisine_tags) : [];
      const dietValues = DIET_OPTIONS.map((d) => d.value);
      setForm({
        id: sponsorToEdit.id,
        name: sponsorToEdit.name,
        imageUrl: sponsorToEdit.image_url || '',
        address: sponsorToEdit.address || '',
        city: sponsorToEdit.city || '',
        postalCode: sponsorToEdit.postal_code || '',
        lat: sponsorToEdit.lat?.toString() || '',
        lon: sponsorToEdit.lon?.toString() || '',
        discountText: sponsorToEdit.discount_text || '',
        priority: sponsorToEdit.priority,
        active: sponsorToEdit.active === 1,
        activeFrom: sponsorToEdit.active_from || '',
        activeUntil: sponsorToEdit.active_until || '',
        cuisineTags: allTags.filter((t) => !dietValues.includes(t)),
        dietTags: allTags.filter((t) => dietValues.includes(t)),
        disclaimerText: (sponsorToEdit as any).disclaimer_text || '',
        openingHoursRaw: (sponsorToEdit as any).opening_hours_raw || '',
        reservationUrl: (sponsorToEdit as any).reservation_url || '',
        lieferandoUrl: (sponsorToEdit as any).lieferando_url || '',
        restaurantId: sponsorToEdit.restaurant_id ?? null,
      });
      setSearchCity(sponsorToEdit.city || '');
      setLinkedName(sponsorToEdit.restaurant_id ? sponsorToEdit.name : null);
    }
    setPreviewUrl(null);
    setImageBroken(false);
    setSearchRadiusKm(5);
    setSearchResults([]);
    setSearchError(null);
    setLinkedPhone(null);
    setLinkedWebsite(null);
    setNameFilter('');
    setError(null);
  }, [sponsorToEdit]);

  useEffect(() => {
    document.body.style.overflow = 'hidden';
    return () => { document.body.style.overflow = ''; };
  }, []);

  useEffect(() => {
    return () => { if (previewUrl) URL.revokeObjectURL(previewUrl); };
  }, [previewUrl]);

  const filteredResults = useMemo(() => {
    if (!nameFilter.trim()) return searchResults;
    const q = nameFilter.trim().toLowerCase();
    return searchResults.filter((r) => r.name.toLowerCase().includes(q));
  }, [searchResults, nameFilter]);

  function toggleCuisine(value: string) {
    setForm((f) => ({
      ...f,
      cuisineTags: f.cuisineTags.includes(value)
        ? f.cuisineTags.filter((v) => v !== value)
        : [...f.cuisineTags, value],
    }));
  }

  function toggleDiet(value: string) {
    setForm((f) => ({
      ...f,
      dietTags: f.dietTags.includes(value)
        ? f.dietTags.filter((v) => v !== value)
        : [...f.dietTags, value],
    }));
  }

  async function handleSearch() {
    if (!searchCity.trim()) {
      setSearchError('Bitte eine Stadt eingeben.');
      return;
    }
    setSearching(true);
    setSearchError(null);
    setSearchResults([]);
    setNameFilter('');
    try {
      const params = new URLSearchParams({ city: searchCity.trim(), radiusKm: String(searchRadiusKm) });
      const res = await fetch(`/api/admin/restaurants/search?${params.toString()}`);
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Suche fehlgeschlagen');
      setSearchResults(data.results || []);
      if ((data.results || []).length === 0) {
        setSearchError('Keine Restaurants in diesem Umkreis gefunden.');
      }
    } catch (e: any) {
      setSearchError(e.message);
    } finally {
      setSearching(false);
    }
  }

  function handleSelectSearchResult(r: SearchResult) {
    const guessedCuisine = guessCuisineChipsFromRaw(r.cuisine);
    setForm((f) => ({
      ...f,
      name: f.name || r.name,
      address: r.address || f.address,
      city: searchCity.trim() || f.city,
      postalCode: r.postalCode || f.postalCode,
      lat: String(r.lat),
      lon: String(r.lon),
      restaurantId: r.restaurantId,
      cuisineTags: guessedCuisine.length > 0 ? guessedCuisine : f.cuisineTags,
      openingHoursRaw: f.openingHoursRaw || r.openingHoursRaw || '',
    }));
    setLinkedName(r.name);
    setLinkedPhone(r.phone);
    setLinkedWebsite(r.website);
    setSearchResults([]);
    setNameFilter('');
  }

  function handleUnlink() {
    setForm((f) => ({ ...f, restaurantId: null }));
    setLinkedName(null);
    setLinkedPhone(null);
    setLinkedWebsite(null);
  }

  async function handleImageUpload(file: File) {
    const localPreview = URL.createObjectURL(file);
    setPreviewUrl(localPreview);
    setImageBroken(false);
    setUploading(true);
    setError(null);
    try {
      const fd = new FormData();
      fd.append('image', file);
      const res = await fetch('/api/admin/upload', { method: 'POST', body: fd });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Upload fehlgeschlagen');
      setForm((f) => ({ ...f, imageUrl: data.url }));
    } catch (e: any) {
      setError(e.message);
    } finally {
      setUploading(false);
    }
  }

  async function handleSave() {
    if (!form.name || !form.city) {
      setError('Name und Stadt sind Pflichtfelder.');
      return;
    }
    setSaving(true);
    setError(null);
    try {
      const payload = {
        name: form.name,
        imageUrl: form.imageUrl || null,
        address: form.address || null,
        city: form.city,
        postalCode: form.postalCode || null,
        lat: form.lat ? Number(form.lat) : null,
        lon: form.lon ? Number(form.lon) : null,
        discountText: form.discountText || null,
        priority: Number(form.priority) || 0,
        active: form.active,
        activeFrom: form.activeFrom || null,
        activeUntil: form.activeUntil || null,
        filterCuisineTags: [...form.cuisineTags, ...form.dietTags],
        disclaimerText: form.disclaimerText || null,
        openingHoursRaw: form.openingHoursRaw || null,
        reservationUrl: form.reservationUrl || null,
        lieferandoUrl: form.lieferandoUrl || null,
        restaurantId: form.restaurantId,
      };

      const url = form.id ? `/api/admin/sponsors/${form.id}` : '/api/admin/sponsors';
      const method = form.id ? 'PATCH' : 'POST';
      const res = await fetch(url, {
        method,
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify(payload),
      });
      const data = await res.json();
      if (!res.ok) throw new Error(data.error || 'Speichern fehlgeschlagen');
      onSaved();
      onClose();
    } catch (e: any) {
      setError(e.message);
    } finally {
      setSaving(false);
    }
  }

  const displayImage = previewUrl || form.imageUrl;

  return (
    <AnimatePresence>
      <motion.div
        initial={{ opacity: 0 }}
        animate={{ opacity: 1 }}
        exit={{ opacity: 0 }}
        className="fixed inset-0 z-50 flex items-center justify-center p-4 bg-black/60"
        style={{ backdropFilter: 'blur(4px)' }}
        onClick={onClose}
      >
        <motion.div
          initial={{ opacity: 0, y: 20, scale: 0.98 }}
          animate={{ opacity: 1, y: 0, scale: 1 }}
          exit={{ opacity: 0, y: 20, scale: 0.98 }}
          onClick={(e) => e.stopPropagation()}
          className="w-full max-w-5xl max-h-[88vh] overflow-hidden rounded-3xl bg-white shadow-2xl flex flex-col"
        >
          <div className="flex items-center justify-between px-8 py-5 border-b border-adminborder shrink-0">
            <h3 className="text-lg font-bold text-admintext m-0">
              {form.id ? 'Sponsor bearbeiten' : 'Sponsoring-Karte anlegen'}
            </h3>
            <button
              onClick={onClose}
              className="text-2xl text-adminmuted hover:text-admintext leading-none w-8 h-8 flex items-center justify-center rounded-full hover:bg-adminbg transition-colors"
            >
              ×
            </button>
          </div>

          <div className="flex-1 overflow-y-auto px-8 py-6">
            <div className="grid lg:grid-cols-2 gap-x-10 gap-y-7">
              <div className="flex flex-col gap-7">
                <FormSection title="Restaurant verknüpfen (optional)">
                  {linkedName ? (
                    <div className="flex flex-col gap-2 bg-teal-50 border border-yumder-teal/30 rounded-xl px-4 py-3">
                      <div className="flex items-center justify-between">
                        <span className="text-sm text-admintext">
                          Verknüpft mit <strong>{linkedName}</strong>
                        </span>
                        <button
                          type="button"
                          onClick={handleUnlink}
                          className="text-xs text-adminmuted hover:text-admindanger underline"
                        >
                          Trennen
                        </button>
                      </div>
                      {(linkedPhone || linkedWebsite) && (
                        <p className="text-xs text-adminmuted leading-relaxed">
                          Wird automatisch in der Swipe-Karte angezeigt:
                          {linkedPhone && <> {linkedPhone}</>}
                          {linkedPhone && linkedWebsite && ' · '}
                          {linkedWebsite && <> {linkedWebsite}</>}
                        </p>
                      )}
                    </div>
                  ) : (
                    <>
                      <div className="flex gap-2">
                        <input
                          placeholder="Stadt für die Suche"
                          value={searchCity}
                          onChange={(e) => setSearchCity(e.target.value)}
                          className={`flex-1 ${INPUT_CLS}`}
                        />
                        <button
                          type="button"
                          onClick={handleSearch}
                          disabled={searching}
                          className="px-4 py-3 bg-yumder-pink text-white rounded-xl text-sm font-semibold disabled:opacity-50 hover:opacity-90 transition-opacity whitespace-nowrap"
                        >
                          {searching ? 'Suche...' : 'Suchen'}
                        </button>
                      </div>
                      <div>
                        <label className="text-xs text-adminmuted font-semibold block mb-1.5">
                          Suchradius: {searchRadiusKm} km
                        </label>
                        <input
                          type="range" min={1} max={15} value={searchRadiusKm}
                          onChange={(e) => setSearchRadiusKm(Number(e.target.value))}
                          className="w-full accent-yumder-pink"
                        />
                      </div>
                      {searchError && <p className="text-xs text-admindanger">{searchError}</p>}

                      {searchResults.length > 0 && (
                        <>
                          <input
                            placeholder={`Nach Namen filtern (${searchResults.length} Treffer)...`}
                            value={nameFilter}
                            onChange={(e) => setNameFilter(e.target.value)}
                            className={INPUT_CLS}
                            autoFocus
                          />
                          <div className="max-h-56 overflow-y-auto flex flex-col gap-1.5 border border-adminborder rounded-xl p-2">
                            {filteredResults.length === 0 ? (
                              <p className="text-xs text-adminmuted px-3 py-2">
                                Kein Treffer für "{nameFilter}".
                              </p>
                            ) : (
                              filteredResults.map((r) => (
                                <button
                                  key={r.restaurantId}
                                  type="button"
                                  onClick={() => handleSelectSearchResult(r)}
                                  className="text-left px-3 py-2 rounded-lg hover:bg-pink-50 transition-colors text-sm"
                                >
                                  <span className="font-semibold text-admintext block">{r.name}</span>
                                  <span className="text-xs text-adminmuted">
                                    {r.address || 'Adresse unbekannt'}{r.cuisine ? ` · ${r.cuisine}` : ''}
                                  </span>
                                </button>
                              ))
                            )}
                          </div>
                        </>
                      )}
                      <p className="text-xs text-adminmuted leading-relaxed">
                        Wähle ein Ergebnis, um Name/Adresse/Koordinaten, Küche und Öffnungszeiten automatisch
                        zu übernehmen (bleibt danach frei editierbar) und Swipes/Matches korrekt zuzuordnen.
                        Ohne Verknüpfung bleibt die Kampagne rein manuell — Live-Stats bleiben dann 0.
                      </p>
                    </>
                  )}
                </FormSection>

                <FormSection title="Grunddaten">
                  <input
                    placeholder="Name *"
                    value={form.name}
                    onChange={(e) => setForm((f) => ({ ...f, name: e.target.value }))}
                    className={INPUT_CLS}
                  />

                  <div>
                    {displayImage && !imageBroken && (
                      <img
                        src={displayImage}
                        alt="Vorschau"
                        className="w-full h-40 object-cover rounded-xl mb-2"
                        onError={() => setImageBroken(true)}
                      />
                    )}
                    {imageBroken && (
                      <p className="text-xs text-admindanger mb-2">
                        Bild konnte nicht geladen werden. URL: {form.imageUrl || '(keine)'}
                      </p>
                    )}
                    <label className="flex flex-col items-center justify-center gap-1 text-sm bg-[#f8f9fa] border-2 border-dashed border-[#e5e7eb] rounded-xl px-4 py-6 cursor-pointer hover:border-yumder-pink hover:text-yumder-pink hover:bg-white transition-colors text-adminmuted text-center">
                      {uploading ? 'Lade hoch...' : 'Klicken oder Bild hierher ziehen'}
                      <span className="text-xs opacity-80">Empfohlen: 1080×1920px im Hochformat</span>
                      <input
                        type="file"
                        accept="image/jpeg,image/png,image/webp"
                        className="hidden"
                        onChange={(e) => {
                          setImageBroken(false);
                          if (e.target.files?.[0]) handleImageUpload(e.target.files[0]);
                        }}
                      />
                    </label>
                  </div>
                </FormSection>

                <FormSection title="Standort">
                  <input
                    placeholder="Stadt *"
                    value={form.city}
                    onChange={(e) => setForm((f) => ({ ...f, city: e.target.value }))}
                    className={INPUT_CLS}
                  />
                  <input
                    placeholder="Postleitzahl"
                    value={form.postalCode}
                    onChange={(e) => setForm((f) => ({ ...f, postalCode: e.target.value }))}
                    className={INPUT_CLS}
                  />
                  <input
                    placeholder="Adresse"
                    value={form.address}
                    onChange={(e) => setForm((f) => ({ ...f, address: e.target.value }))}
                    className={INPUT_CLS}
                  />
                  <div className="flex gap-3">
                    <input
                      placeholder="Latitude (optional)"
                      value={form.lat}
                      onChange={(e) => setForm((f) => ({ ...f, lat: e.target.value }))}
                      className={`flex-1 ${INPUT_CLS}`}
                    />
                    <input
                      placeholder="Longitude (optional)"
                      value={form.lon}
                      onChange={(e) => setForm((f) => ({ ...f, lon: e.target.value }))}
                      className={`flex-1 ${INPUT_CLS}`}
                    />
                  </div>
                </FormSection>

                <FormSection title="Filter & Kategorien">
                  <div>
                    <p className="text-sm font-semibold text-adminmuted mb-1.5">Ernährungsform</p>
                    <ToggleChipBar options={DIET_OPTIONS} selected={form.dietTags} onToggle={toggleDiet} />
                  </div>
                  <div>
                    <p className="text-sm font-semibold text-adminmuted mb-1.5">
                      Küche {form.cuisineTags.length > 0 && (
                        <span className="text-yumder-teal font-normal">
                          (automatisch übernommen, editierbar)
                        </span>
                      )}
                    </p>
                    <ToggleChipBar options={CUISINE_OPTIONS} selected={form.cuisineTags} onToggle={toggleCuisine} searchable />
                  </div>
                </FormSection>
              </div>

              <div className="flex flex-col gap-7">
                <FormSection title="Marketing & Links">
                  <input
                    placeholder="Rabatt-Text (z.B. 20% auf Hauptgerichte)"
                    value={form.discountText}
                    onChange={(e) => setForm((f) => ({ ...f, discountText: e.target.value }))}
                    className={INPUT_CLS}
                  />
                  <div>
                    <p className="text-xs text-adminmuted font-semibold mb-1.5">Reservierungslink</p>
                    <input
                      placeholder="https://www.bookatable.de/..."
                      value={form.reservationUrl}
                      onChange={(e) => setForm((f) => ({ ...f, reservationUrl: e.target.value }))}
                      className={`w-full text-sm ${INPUT_CLS}`}
                    />
                  </div>
                  <div>
                    <p className="text-xs text-adminmuted font-semibold mb-1.5">
                      Lieferando-Link (für "Direkt bestellen")
                    </p>
                    <input
                      placeholder="https://www.lieferando.de/speisekarte/restaurantname"
                      value={form.lieferandoUrl}
                      onChange={(e) => setForm((f) => ({ ...f, lieferandoUrl: e.target.value }))}
                      className={`w-full text-sm ${INPUT_CLS}`}
                    />
                  </div>
                  <div>
                    <p className="text-xs text-adminmuted font-semibold mb-1.5">Sternchentext</p>
                    <textarea
                      placeholder="Sternchentext"
                      value={form.disclaimerText}
                      onChange={(e) => setForm((f) => ({ ...f, disclaimerText: e.target.value }))}
                      rows={2}
                      className={`w-full resize-none text-sm ${INPUT_CLS}`}
                    />
                  </div>
                  <div>
                    <p className="text-xs text-adminmuted font-semibold mb-1.5">
                      Öffnungszeiten (OSM-Format) {form.openingHoursRaw && linkedName && (
                        <span className="text-yumder-teal font-normal">(automatisch übernommen, editierbar)</span>
                      )}
                    </p>
                    <input
                      placeholder="Öffnungszeiten"
                      value={form.openingHoursRaw}
                      onChange={(e) => setForm((f) => ({ ...f, openingHoursRaw: e.target.value }))}
                      className={`w-full text-sm ${INPUT_CLS}`}
                    />
                  </div>
                </FormSection>

                <FormSection title="Zeitraum & Sichtbarkeit">
                  <div className="flex gap-3">
                    <div className="flex-1">
                      <label className="text-sm font-semibold text-adminmuted block mb-1.5">Startdatum</label>
                      <input
                        type="date"
                        value={form.activeFrom}
                        onChange={(e) => setForm((f) => ({ ...f, activeFrom: e.target.value }))}
                        className={`w-full text-sm ${INPUT_CLS}`}
                      />
                    </div>
                    <div className="flex-1">
                      <label className="text-sm font-semibold text-adminmuted block mb-1.5">Enddatum</label>
                      <input
                        type="date"
                        value={form.activeUntil}
                        onChange={(e) => setForm((f) => ({ ...f, activeUntil: e.target.value }))}
                        className={`w-full text-sm ${INPUT_CLS}`}
                      />
                    </div>
                  </div>

                  <div>
                    <label className="text-sm font-semibold text-adminmuted block mb-1.5">
                      Boost-Faktor (Sichtbarkeit im Stapel)
                    </label>
                    <div className="flex items-center gap-3 bg-[#f8f9fa] rounded-xl px-4 py-3 border border-[#e5e7eb]">
                      <input
                        type="range" min={0} max={10} value={form.priority}
                        onChange={(e) => setForm((f) => ({ ...f, priority: Number(e.target.value) }))}
                        className="flex-1 accent-yumder-pink"
                      />
                      <span className="text-sm w-24 text-right text-yumder-pink font-semibold">
                        {boostLabelFromPriority(form.priority)}
                      </span>
                    </div>
                    <p className="text-xs text-adminmuted mt-1.5 leading-relaxed">
                      Bestimmt, wie oft diese Karte organischen Nutzern im Vergleich zu nicht-gesponserten
                      Restaurants eingespielt wird (Priorität {form.priority}/10).
                    </p>
                  </div>

                  <div className="flex items-center justify-between bg-[#f8f9fa] rounded-xl px-4 py-3 border border-[#e5e7eb]">
                    <span className="text-sm text-adminmuted font-semibold">Aktiv</span>
                    <button
                      type="button"
                      onClick={() => setForm((f) => ({ ...f, active: !f.active }))}
                      className={`relative h-6 w-11 rounded-full transition-colors ${
                        form.active ? 'bg-yumder-pink' : 'bg-adminborder'
                      }`}
                    >
                      <motion.div
                        animate={{ x: form.active ? 20 : 0 }}
                        transition={{ type: 'spring', stiffness: 500, damping: 30 }}
                        className="absolute top-0.5 left-0.5 h-5 w-5 rounded-full bg-white shadow"
                      />
                    </button>
                  </div>
                </FormSection>

                {error && <p className="text-admindanger text-sm">{error}</p>}
              </div>
            </div>
          </div>

          <div className="flex justify-end gap-3 px-8 py-5 border-t border-adminborder shrink-0 bg-white">
            <button
              onClick={onClose}
              className="px-5 py-3 text-adminmuted font-semibold text-sm hover:text-admintext transition-colors"
            >
              Abbrechen
            </button>
            <button
              onClick={handleSave}
              disabled={saving}
              className="bg-yumder-pink text-white font-bold px-6 py-3 rounded-xl text-sm disabled:opacity-50 hover:opacity-90 transition-opacity"
            >
              {saving ? 'Speichere...' : '+ Karte aktivieren'}
            </button>
          </div>
        </motion.div>
      </motion.div>
    </AnimatePresence>
  );
}
