"use client";

import { useEffect, useState } from "react";

type EventItem = {
  id: string;
  title: string;
  startAt: string;
  endAt: string;
  status: string;
  location?: string | null;
  locationPlaceId?: string | null;
  locationLat?: number | null;
  locationLng?: number | null;
  description?: string | null;
  category?: { id: string; name: string } | null;
};

export default function AdminPanel() {
  const [events, setEvents] = useState<EventItem[]>([]);
  const [allEvents, setAllEvents] = useState<EventItem[]>([]);
  const [error, setError] = useState<string | null>(null);
  const [categories, setCategories] = useState<{ id: string; name: string }[]>(
    []
  );
  const [categoryError, setCategoryError] = useState<string | null>(null);
  const [categoryStatus, setCategoryStatus] = useState<string | null>(null);
  const [categoryModalOpen, setCategoryModalOpen] = useState(false);
  const [categoryModalError, setCategoryModalError] = useState<string | null>(null);
  const [categoryModalStatus, setCategoryModalStatus] = useState<string | null>(null);
  const [editingCategory, setEditingCategory] = useState<{ id: string; name: string } | null>(null);
  const [editEvent, setEditEvent] = useState<EventItem | null>(null);
  const [editStatus, setEditStatus] = useState<string | null>(null);
  const [editError, setEditError] = useState<string | null>(null);
  const [isEditOpen, setIsEditOpen] = useState(false);
  const [importFile, setImportFile] = useState<File | null>(null);
  const [importCategoryId, setImportCategoryId] = useState("");
  const [importStatus, setImportStatus] = useState<string | null>(null);
  const [importError, setImportError] = useState<string | null>(null);

  const load = async () => {
    try {
      const response = await fetch("/api/events?status=PENDING");
      if (!response.ok) {
        throw new Error("Vorschläge konnten nicht geladen werden.");
      }
      setEvents(await response.json());
    } catch (err) {
      setError((err as Error).message);
    }
  };

  const loadAllEvents = async () => {
    try {
      const response = await fetch("/api/events");
      if (!response.ok) {
        throw new Error("Termine konnten nicht geladen werden.");
      }
      setAllEvents(await response.json());
    } catch (err) {
      setError((err as Error).message);
    }
  };

  const loadCategories = async () => {
    try {
      const response = await fetch("/api/categories");
      if (!response.ok) {
        throw new Error("Kategorien konnten nicht geladen werden.");
      }
      setCategories(await response.json());
    } catch (err) {
      setCategoryError((err as Error).message);
    }
  };

  useEffect(() => {
    load();
    loadCategories();
    loadAllEvents();
  }, []);

  const updateStatus = async (id: string, status: "APPROVED" | "REJECTED") => {
    await fetch(`/api/events/${id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ status })
    });
    load();
    loadAllEvents();
  };

  const deleteEvent = async (id: string) => {
    const ok = window.confirm("Termin wirklich löschen?");
    if (!ok) return;

    await fetch(`/api/events/${id}`, { method: "DELETE" });
    load();
    loadAllEvents();
  };

  const formatLocalDateTime = (value?: string | null) => {
    if (!value) return "";
    const date = new Date(value);
    const offset = date.getTimezoneOffset() * 60000;
    return new Date(date.getTime() - offset).toISOString().slice(0, 16);
  };

  const toIsoString = (value: FormDataEntryValue | null) => {
    if (!value) return null;
    const raw = String(value);
    if (!raw) return null;
    const date = new Date(raw);
    if (Number.isNaN(date.getTime())) return null;
    return date.toISOString();
  };

  const updateEvent = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setEditStatus(null);
    setEditError(null);

    if (!editEvent) return;
    const formData = new FormData(event.currentTarget);
    const payload = {
      title: formData.get("title"),
      description: formData.get("description"),
      location: formData.get("location"),
      locationPlaceId: formData.get("locationPlaceId"),
      locationLat: formData.get("locationLat"),
      locationLng: formData.get("locationLng"),
      startAt: toIsoString(formData.get("startAt")),
      endAt: toIsoString(formData.get("endAt")),
      categoryId: formData.get("categoryId")
    };

    const response = await fetch(`/api/events/${editEvent.id}`, {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload)
    });

    if (!response.ok) {
      const data = await response.json();
      setEditError(data.error || "Termin konnte nicht aktualisiert werden.");
      return;
    }

    const updated = await response.json();
    setEditStatus("Termin aktualisiert.");
    setEditEvent(updated);
    load();
    loadAllEvents();
    setIsEditOpen(false);
  };

  const createCategory = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setCategoryError(null);
    setCategoryStatus(null);
    const formData = new FormData(event.currentTarget);
    const rawName = String(formData.get("name") || "").trim();
    if (!rawName) {
      setCategoryError("Name erforderlich.");
      return;
    }

    const response = await fetch("/api/categories", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ name: rawName })
    });

    if (!response.ok) {
      const data = await response.json();
      setCategoryError(data.error || "Kategorie konnte nicht angelegt werden.");
      return;
    }

    const created = await response.json();
    setCategories((prev) => {
      if (prev.some((item) => item.id === created.id)) return prev;
      return [...prev, created].sort((a, b) => a.name.localeCompare(b.name));
    });
    event.currentTarget.reset();
    setCategoryStatus("Kategorie angelegt.");
  };

  const openCategoryModal = (category: { id: string; name: string }) => {
    setEditingCategory(category);
    setCategoryModalError(null);
    setCategoryModalStatus(null);
    setCategoryModalOpen(true);
  };

  const closeCategoryModal = () => {
    setEditingCategory(null);
    setCategoryModalOpen(false);
  };

  const updateCategory = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    if (!editingCategory) return;
    setCategoryModalError(null);
    setCategoryModalStatus(null);

    const formData = new FormData(event.currentTarget);
    const name = String(formData.get("name") || "").trim();
    if (!name) {
      setCategoryModalError("Name erforderlich.");
      return;
    }

    const response = await fetch("/api/categories", {
      method: "PATCH",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ id: editingCategory.id, name })
    });

    if (!response.ok) {
      const data = await response.json();
      setCategoryModalError(data.error || "Kategorie konnte nicht aktualisiert werden.");
      return;
    }

    const updated = await response.json();
    setCategories((prev) =>
      prev
        .map((item) => (item.id === updated.id ? updated : item))
        .sort((a, b) => a.name.localeCompare(b.name))
    );
    setCategoryModalStatus("Kategorie aktualisiert.");
    setCategoryModalOpen(false);
  };

  const deleteCategory = async (categoryId: string) => {
    const ok = window.confirm("Kategorie wirklich löschen? Zugeordnete Termine bleiben erhalten.");
    if (!ok) return;

    const response = await fetch(`/api/categories?id=${categoryId}`, {
      method: "DELETE"
    });

    if (!response.ok) {
      const data = await response.json();
      setCategoryError(data.error || "Kategorie konnte nicht gelöscht werden.");
      return;
    }

    setCategories((prev) => prev.filter((item) => item.id !== categoryId));
    setCategoryStatus("Kategorie gelöscht.");
  };

  const importIcal = async (event: React.FormEvent<HTMLFormElement>) => {
    event.preventDefault();
    setImportStatus(null);
    setImportError(null);

    if (!importFile) {
      setImportError("Bitte eine iCal-Datei auswählen.");
      return;
    }
    if (!importCategoryId) {
      setImportError("Bitte eine Kategorie auswählen.");
      return;
    }

    const formData = new FormData();
    formData.append("file", importFile);
    formData.append("categoryId", importCategoryId);

    const response = await fetch("/api/ical/import", {
      method: "POST",
      body: formData
    });

    if (!response.ok) {
      const data = await response.json();
      setImportError(data.error || "Import fehlgeschlagen.");
      return;
    }

    const data = await response.json();
    const details = [
      `${data.created || 0} importiert`,
      `${data.duplicates || 0} doppelt`,
      `${data.skipped || 0} übersprungen`
    ];
    if (data.recurringSkipped) {
      details.push(`${data.recurringSkipped} wiederkehrend`);
    }
    setImportStatus(`Import abgeschlossen: ${details.join(", ")}.`);
    setImportFile(null);
    setImportCategoryId("");
    load();
    loadAllEvents();
  };

  return (
    <section className="space-y-4 fade-up">
      <div>
        <p className="text-xs uppercase tracking-[0.2em] text-slate-500">Admin</p>
        <h1 className="text-2xl font-semibold">Offene Vorschläge</h1>
      </div>
      {error && <p className="text-sm text-red-600">{error}</p>}
      {events.length === 0 ? (
        <div className="card-muted">
          <p className="text-slate-600">Keine offenen Vorschläge.</p>
        </div>
      ) : (
        <div className="space-y-3">
          {events.map((event) => (
            <div key={event.id} className="card">
              <div className="flex flex-col gap-2 md:flex-row md:items-center md:justify-between">
                <div>
                  <h2 className="text-lg font-medium">{event.title}</h2>
                  <p className="text-sm text-slate-600">
                    {new Date(event.startAt).toLocaleString()} - {new Date(event.endAt).toLocaleString()}
                  </p>
                  {event.location && (
                    <p className="text-sm text-slate-600">Ort: {event.location}</p>
                  )}
                </div>
                <div className="flex gap-2">
                  <button
                    type="button"
                    onClick={() => updateStatus(event.id, "APPROVED")}
                    className="rounded-full bg-emerald-600 px-3 py-1.5 text-sm font-semibold text-white"
                  >
                    Freigeben
                  </button>
                  <button
                    type="button"
                    onClick={() => updateStatus(event.id, "REJECTED")}
                    className="rounded-full bg-red-600 px-3 py-1.5 text-sm font-semibold text-white"
                  >
                    Ablehnen
                  </button>
                </div>
              </div>
              {event.description && (
                <p className="mt-2 text-sm text-slate-700">{event.description}</p>
              )}
            </div>
          ))}
        </div>
      )}
      <section className="card space-y-4">
        <div>
          <p className="text-xs uppercase tracking-[0.2em] text-slate-500">
            Kategorien
          </p>
          <h2 className="text-lg font-semibold">Kategorien verwalten</h2>
        </div>
        <form onSubmit={createCategory} className="flex flex-wrap gap-2">
          <input
            name="name"
            required
            placeholder="z.B. Training"
            className="flex-1 rounded-xl border border-slate-300 px-3 py-2"
          />
          <button className="btn-accent" type="submit">
            Anlegen
          </button>
        </form>
        {categoryStatus && (
          <p className="text-sm text-emerald-600">{categoryStatus}</p>
        )}
        {categoryError && (
          <p className="text-sm text-red-600">{categoryError}</p>
        )}
        <div className="space-y-2">
          {categories.length === 0 ? (
            <span className="text-sm text-slate-600">
              Noch keine Kategorien.
            </span>
          ) : (
            categories.map((category) => (
              <div
                key={category.id}
                className="flex items-center justify-between rounded-xl border border-slate-200 px-3 py-2 text-sm text-slate-700"
              >
                <span>{category.name}</span>
                <div className="flex gap-2">
                  <button
                    type="button"
                    className="rounded-full border border-slate-200 px-3 py-1 text-xs text-slate-700"
                    onClick={() => openCategoryModal(category)}
                  >
                    Bearbeiten
                  </button>
                  <button
                    type="button"
                    className="rounded-full border border-red-200 px-3 py-1 text-xs text-red-600"
                    onClick={() => deleteCategory(category.id)}
                  >
                    Löschen
                  </button>
                </div>
              </div>
            ))
          )}
        </div>
      </section>
      {categoryModalOpen && editingCategory && (
        <div className="fixed inset-0 z-30 flex items-center justify-center bg-black/40 px-4 py-6">
          <div className="card w-full max-w-md">
            <div className="flex items-center justify-between">
              <h3 className="text-lg font-semibold">Kategorie bearbeiten</h3>
              <button
                type="button"
                className="text-sm text-slate-600"
                onClick={closeCategoryModal}
              >
                Schließen
              </button>
            </div>
            <form onSubmit={updateCategory} className="mt-4 space-y-3">
              <input
                name="name"
                defaultValue={editingCategory.name}
                required
                className="w-full rounded-xl border border-slate-300 px-3 py-2"
              />
              <button type="submit" className="btn-accent w-full">
                Speichern
              </button>
            </form>
            {categoryModalStatus && (
              <p className="mt-3 text-sm text-emerald-600">{categoryModalStatus}</p>
            )}
            {categoryModalError && (
              <p className="mt-3 text-sm text-red-600">{categoryModalError}</p>
            )}
          </div>
        </div>
      )}
      <section className="card space-y-4">
        <div>
          <p className="text-xs uppercase tracking-[0.2em] text-slate-500">
            iCal
          </p>
          <h2 className="text-lg font-semibold">iCal-Import</h2>
          <p className="text-sm text-slate-600">
            Lade eine iCal-Datei hoch, um Termine direkt zu importieren.
          </p>
        </div>
        <form onSubmit={importIcal} className="space-y-3">
          <div className="flex flex-wrap items-center gap-3">
            <input
              type="file"
              accept=".ics,text/calendar"
              onChange={(event) =>
                setImportFile(event.currentTarget.files?.[0] || null)
              }
              className="block text-sm text-slate-600"
            />
            <select
              value={importCategoryId}
              onChange={(event) => setImportCategoryId(event.target.value)}
              className="rounded-xl border border-slate-300 px-3 py-2 text-sm"
              required
            >
              <option value="" disabled>
                Kategorie wählen
              </option>
              {categories.map((category) => (
                <option key={category.id} value={category.id}>
                  {category.name}
                </option>
              ))}
            </select>
            <button type="submit" className="btn-accent">
              Import starten
            </button>
          </div>
          {importStatus && <p className="text-sm text-emerald-600">{importStatus}</p>}
          {importError && <p className="text-sm text-red-600">{importError}</p>}
        </form>
      </section>
      <section className="card space-y-4">
        <div>
          <p className="text-xs uppercase tracking-[0.2em] text-slate-500">
            Termine
          </p>
          <h2 className="text-lg font-semibold">Alle Termine verwalten</h2>
        </div>
        {isEditOpen && editEvent && (
          <div className="fixed inset-0 z-30 flex items-center justify-center bg-black/40 px-4 py-6">
            <div className="card w-full max-w-2xl max-h-[90vh] overflow-y-auto">
              <div className="flex items-center justify-between">
                <h3 className="text-lg font-semibold">Termin bearbeiten</h3>
                <button
                  type="button"
                  className="text-sm text-slate-600"
                  onClick={() => {
                    setEditEvent(null);
                    setEditError(null);
                    setEditStatus(null);
                    setIsEditOpen(false);
                  }}
                >
                  Schließen
                </button>
              </div>
              <form onSubmit={updateEvent} className="mt-4 space-y-3">
                <div className="grid gap-3 md:grid-cols-2">
                  <input
                    name="title"
                    required
                    defaultValue={editEvent.title}
                    className="rounded-xl border border-slate-300 px-3 py-2"
                    placeholder="Titel"
                  />
                  <input
                    name="location"
                    defaultValue={editEvent.location || ""}
                    className="rounded-xl border border-slate-300 px-3 py-2"
                    placeholder="Ort"
                  />
                  <input
                    type="hidden"
                    name="locationPlaceId"
                    value={editEvent.locationPlaceId || ""}
                  />
                  <input
                    type="hidden"
                    name="locationLat"
                    value={editEvent.locationLat ?? ""}
                  />
                  <input
                    type="hidden"
                    name="locationLng"
                    value={editEvent.locationLng ?? ""}
                  />
                  <input
                    name="startAt"
                    type="datetime-local"
                    required
                    defaultValue={formatLocalDateTime(editEvent.startAt)}
                    className="rounded-xl border border-slate-300 px-3 py-2"
                  />
                  <input
                    name="endAt"
                    type="datetime-local"
                    defaultValue={formatLocalDateTime(editEvent.endAt)}
                    className="rounded-xl border border-slate-300 px-3 py-2"
                  />
                  <select
                    name="categoryId"
                    required
                    defaultValue={editEvent.category?.id || ""}
                    className="rounded-xl border border-slate-300 px-3 py-2 md:col-span-2"
                  >
                    <option value="" disabled>
                      Kategorie waehlen
                    </option>
                    {categories.map((category) => (
                      <option key={category.id} value={category.id}>
                        {category.name}
                      </option>
                    ))}
                  </select>
                </div>
                <textarea
                  name="description"
                  defaultValue={editEvent.description || ""}
                  placeholder="Beschreibung"
                  className="min-h-[96px] rounded-xl border border-slate-300 px-3 py-2"
                />
                <button type="submit" className="btn-accent">
                  Speichern
                </button>
                {editStatus && <p className="text-sm text-emerald-600">{editStatus}</p>}
                {editError && <p className="text-sm text-red-600">{editError}</p>}
              </form>
            </div>
          </div>
        )}
        <div className="overflow-x-auto">
          <table className="min-w-full text-left text-sm">
            <thead className="text-xs uppercase tracking-[0.2em] text-slate-500">
              <tr>
                <th className="pb-2">Datum</th>
                <th className="pb-2">Titel</th>
                <th className="pb-2">Kategorie</th>
                <th className="pb-2">Status</th>
                <th className="pb-2">Aktion</th>
              </tr>
            </thead>
            <tbody>
              {allEvents.length === 0 ? (
                <tr>
                  <td colSpan={5} className="py-4 text-slate-600">
                    Keine Termine vorhanden.
                  </td>
                </tr>
              ) : (
                allEvents.map((event) => (
                  <tr key={event.id} className="border-t border-slate-200">
                    <td className="py-3 pr-3">
                      {new Date(event.startAt).toLocaleString("de-DE", {
                        dateStyle: "medium",
                        timeStyle: "short"
                      })}
                    </td>
                    <td className="py-3 pr-3 font-medium">{event.title}</td>
                    <td className="py-3 pr-3">
                      {event.category?.name || "Ohne Kategorie"}
                    </td>
                    <td className="py-3 pr-3">
                      <div className="flex items-center gap-2">
                        <StatusIcon status={event.status} />
                      </div>
                    </td>
                    <td className="py-3 pr-3">
                      <div className="flex flex-wrap gap-2">
                        <button
                          type="button"
                          className="rounded-full border border-slate-200 px-3 py-1 text-xs text-slate-700"
                          onClick={() => {
                            setEditEvent(event);
                            setIsEditOpen(true);
                          }}
                        >
                          Bearbeiten
                        </button>
                        <button
                          type="button"
                          className="rounded-full border border-red-200 px-3 py-1 text-xs text-red-600"
                          onClick={() => deleteEvent(event.id)}
                        >
                          Löschen
                        </button>
                      </div>
                    </td>
                  </tr>
                ))
              )}
            </tbody>
          </table>
        </div>
      </section>
    </section>
  );
}

function StatusIcon({ status }: { status: string }) {
  if (status === "APPROVED") {
    return (
      <span title="Freigegeben" aria-label="Freigegeben" className="text-emerald-600">
        <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" stroke="currentColor" strokeWidth="2">
          <path d="M5 12l4 4L19 6" strokeLinecap="round" strokeLinejoin="round" />
        </svg>
      </span>
    );
  }
  if (status === "REJECTED") {
    return (
      <span title="Abgelehnt" aria-label="Abgelehnt" className="text-red-600">
        <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" stroke="currentColor" strokeWidth="2">
          <path d="M6 6l12 12M18 6l-12 12" strokeLinecap="round" />
        </svg>
      </span>
    );
  }
  return (
    <span title="Offen" aria-label="Offen" className="text-amber-600">
      <svg viewBox="0 0 24 24" className="h-4 w-4" fill="none" stroke="currentColor" strokeWidth="2">
        <path d="M12 6v6l4 2" strokeLinecap="round" strokeLinejoin="round" />
        <circle cx="12" cy="12" r="9" />
      </svg>
    </span>
  );
}
