"use client";
import { useEffect, useState } from "react";
import {
  Check,
  ChevronLeft,
  ChevronRight,
  ImageIcon,
  Search,
  X,
} from "lucide-react";
import Button from "@/components/ui/Button";
import ImagePicker from "@/components/ui/ImagePicker";
import Input from "@/components/ui/Input";
import Modal from "@/components/ui/Modal";
import type { EventRow } from "@/components/business/BusinessPanelEvents";
type Props = {
  businessId: string;
  event: EventRow | null;
  locations: {
    id: string;
    name: string;
  }[];
  onClose(): void;
  onSave(): void;
};
const STEPS = ["Details", "Venue", "Schedule", "Review"];
const localDateTime = (value?: string | null) =>
  value ? new Date(value).toISOString().slice(0, 16) : "";
type Category = { id: string; name: string; slug: string };
export default function EventFormModal({
  businessId,
  event,
  locations,
  onClose,
  onSave,
}: Props) {
  const [step, setStep] = useState(0);
  const [title, setTitle] = useState(event?.title ?? "");
  const [description, setDescription] = useState(event?.description ?? "");
  const [imageUrl, setImageUrl] = useState(event?.imageUrl ?? "");
  const [locationIds, setLocationIds] = useState<string[]>(
    event?.hostingLocations?.map(({ location }) => location.id) ??
      (event?.locationId ? [event.locationId] : locations[0]?.id ? [locations[0].id] : []),
  );
  const [venueMode, setVenueMode] = useState<"HOST_LOCATION" | "ON_SITE">(
    event?.venueMode ?? "HOST_LOCATION",
  );
  const [venueName, setVenueName] = useState(event?.venueName ?? "");
  const [venueAddress, setVenueAddress] = useState(event?.venueAddress ?? "");
  const [startsAt, setStartsAt] = useState(localDateTime(event?.startsAt));
  const [endsAt, setEndsAt] = useState(localDateTime(event?.endsAt));
  const [capacity, setCapacity] = useState(event?.capacity?.toString() ?? "");
  const [status, setStatus] = useState<string>(event?.status ?? "DRAFT");
  const [recurrence, setRecurrence] = useState<string>(
    event?.recurrence ?? "NONE",
  );
  const [recurrenceEndsAt, setRecurrenceEndsAt] = useState(
    event?.recurrenceEndsAt?.slice(0, 10) ?? "",
  );
  const [saving, setSaving] = useState(false);
  const [error, setError] = useState("");
  const [categoryQuery, setCategoryQuery] = useState("");
  const [categoryResults, setCategoryResults] = useState<Category[]>([]);
  const [selectedCategory, setSelectedCategory] = useState<Category | null>(
    event?.categories[0]?.category ?? null,
  );

  useEffect(() => {
    const controller = new AbortController();
    const timer = setTimeout(async () => {
      try {
        const res = await fetch(
          `/api/businesses/${businessId}/event-categories?q=${encodeURIComponent(categoryQuery)}`,
          { signal: controller.signal },
        );
        if (res.ok) setCategoryResults(await res.json());
      } catch (error) {
        if (!(error instanceof DOMException && error.name === "AbortError")) {
          setCategoryResults([]);
        }
      }
    }, 200);

    return () => {
      controller.abort();
      clearTimeout(timer);
    };
  }, [businessId, categoryQuery]);
  function validateStep() {
    if (step === 0 && !title.trim()) return "Enter an event title.";
    if (step === 1 && locationIds.length === 0) return "Select at least one hosting location.";
    if (
      step === 1 &&
      venueMode === "ON_SITE" &&
      !venueName.trim() &&
      !venueAddress.trim()
    )
      return "Enter an outdoor venue name or address.";
    if (step === 2 && !startsAt) return "Select the event start date and time.";
    if (step === 2 && endsAt && new Date(endsAt) <= new Date(startsAt))
      return "End time must be after start time.";
    if (step === 2 && recurrence !== "NONE" && !recurrenceEndsAt)
      return "Select when this recurring event ends.";
    return "";
  }
  function next() {
    const message = validateStep();
    if (message) {
      setError(message);
      return;
    }
    setError("");
    setStep((value) => Math.min(value + 1, STEPS.length - 1));
  }
  function previous() {
    setError("");
    setStep((value) => Math.max(value - 1, 0));
  }
  async function submit() {
    const message = validateStep();
    if (message) {
      setError(message);
      return;
    }
    setSaving(true);
    setError("");
    const payload = {
      title,
      description: description || null,
      locationId: locationIds[0] ?? "",
      locationIds,
      venueMode,
      venueName: venueMode === "ON_SITE" ? venueName || null : null,
      venueAddress: venueMode === "ON_SITE" ? venueAddress || null : null,
      imageUrl: imageUrl || null,
      startsAt,
      endsAt: endsAt || null,
      capacity: capacity ? Number(capacity) : null,
      status,
      recurrence,
      recurrenceEndsAt: recurrence === "NONE" ? null : recurrenceEndsAt || null,
      categoryIds: selectedCategory ? [selectedCategory.id] : [],
      timezone: Intl.DateTimeFormat().resolvedOptions().timeZone || "UTC",
    };
    try {
      const res = await fetch(
        event
          ? `/api/businesses/${businessId}/events/${event.id}`
          : `/api/businesses/${businessId}/events`,
        {
          method: event ? "PATCH" : "POST",
          headers: { "Content-Type": "application/json" },
          body: JSON.stringify(payload),
        },
      );
      if (!res.ok) {
        const body = await res.json();
        setError(
          typeof body.error === "string"
            ? body.error
            : "Please review the event details.",
        );
        return;
      }
      onSave();
    } catch {
      setError("Unable to save the event.");
    } finally {
      setSaving(false);
    }
  }
  const selectedLocation =
    locations.find((location) => location.id === locationIds[0])?.name ??
    "Not selected";
  return (
    <Modal
      wide
      title={event ? "Edit event" : "Create event"}
      description="Complete each step to save your business event."
      onClose={onClose}
    >
      <div className="shrink-0 px-5 pt-5 sm:px-6">
        <ol className="grid grid-cols-4 gap-2">
          {STEPS.map((label, index) => (
            <li key={label} className="min-w-0">
              <div
                className={`flex items-center gap-2 text-xs font-medium ${index <= step ? "text-[var(--accent)]" : "text-[var(--text-faint)]"}`}
              >
                <span
                  className={`flex h-6 w-6 shrink-0 items-center justify-center rounded-full border ${index < step ? "border-[var(--accent)] bg-[var(--accent)] text-white" : index === step ? "border-[var(--accent)]" : "border-[var(--border)]"}`}
                >
                  {index < step ? <Check className="h-3.5 w-3.5" /> : index + 1}
                </span>
                <span className="truncate">{label}</span>
              </div>
            </li>
          ))}
        </ol>
      </div>
      <div className="min-h-0 flex-1 overflow-y-auto px-5 py-6 sm:px-6">
        {step === 0 && (
          <div className="space-y-5">
            <ImagePicker
              label="Event image"
              hint="Upload an image or use an image URL."
              value={imageUrl}
              uploadUrl={`/api/businesses/${businessId}/events/upload`}
              onChange={setImageUrl}
            />
            <Input
              label="Event title"
              value={title}
              onChange={(e) => setTitle(e.target.value)}
              required
              autoFocus
            />
            <label className="block text-sm font-medium text-[var(--text)]">
              Description
              <textarea
                value={description}
                onChange={(e) => setDescription(e.target.value)}
                className="mt-1.5 min-h-28 w-full rounded-lg border border-[var(--border)] bg-[var(--bg-elevated)] px-3 py-2.5 text-sm text-[var(--text)]"
                placeholder="What should the business team know about this event?"
              />
            </label>
            <div>
              <p className="text-sm font-medium text-[var(--text)]">
                Categories
              </p>
              <p className="mt-1 text-xs text-[var(--text-faint)]">
                Search saved categories and select one.
              </p>
              <div className="relative mt-2">
                <Search className="pointer-events-none absolute start-3 top-3 h-4 w-4 text-[var(--text-faint)]" />
                <input
                  value={categoryQuery}
                  onChange={(e) => setCategoryQuery(e.target.value)}
                  placeholder="Search categories…"
                  className="w-full rounded-lg border border-[var(--border)] bg-[var(--bg-elevated)] py-2.5 pe-3 ps-9 text-sm text-[var(--text)]"
                />
                {categoryQuery && (
                  <div className="absolute z-10 mt-1 max-h-40 w-full overflow-y-auto rounded-lg border border-[var(--border)] bg-[var(--bg-surface)] p-1 shadow-xl">
                    {categoryResults
                      .filter(
                        (category) =>
                          category.id !== selectedCategory?.id,
                      )
                      .map((category) => (
                        <button
                          key={category.id}
                          type="button"
                          onClick={() => {
                            setSelectedCategory(category);
                            setCategoryQuery("");
                          }}
                          className="flex w-full rounded-md px-3 py-2 text-left text-sm text-[var(--text)] hover:bg-[var(--bg-hover)]"
                        >
                          {category.name}
                        </button>
                      ))}
                  </div>
                )}
              </div>
              {selectedCategory && (
                <div className="mt-3 flex flex-wrap gap-2">
                  <span className="inline-flex items-center gap-1 rounded-full bg-[var(--accent-muted)] px-2.5 py-1 text-xs font-medium text-[var(--accent-hover)]">
                    {selectedCategory.name}
                    <button type="button" onClick={() => setSelectedCategory(null)} aria-label={`Remove ${selectedCategory.name}`}>
                      <X className="h-3.5 w-3.5" />
                    </button>
                  </span>
                </div>
              )}
            </div>
          </div>
        )}
        {step === 1 && (
          <div className="space-y-5">
            <div>
              <p className="text-sm font-medium text-[var(--text)]">
                Event venue
              </p>
              <p className="mt-1 text-xs text-[var(--text-faint)]">
                Choose whether this event is held indoors or at an outdoor venue.
              </p>
              <div className="mt-3 flex flex-wrap gap-4 text-sm text-[var(--text-muted)]">
                <label className="flex cursor-pointer items-center gap-2">
                  <input
                    type="radio"
                    checked={venueMode === "HOST_LOCATION"}
                    onChange={() => setVenueMode("HOST_LOCATION")}
                  />
                  Indoor event
                </label>
                <label className="flex cursor-pointer items-center gap-2">
                  <input
                    type="radio"
                    checked={venueMode === "ON_SITE"}
                    onChange={() => setVenueMode("ON_SITE")}
                  />
                  Outdoor event
                </label>
              </div>
            </div>
            {venueMode === "HOST_LOCATION" && (
            <fieldset>
              <legend className="text-sm font-medium text-[var(--text)]">
                Hosting locations
              </legend>
              <div className="mt-2 flex items-center justify-between gap-3">
                <p className="text-xs text-[var(--text-faint)]">
                  Select every location hosting this event.
                </p>
                <span className="shrink-0 text-xs font-medium text-[var(--accent)]">
                  {locationIds.length} selected
                </span>
              </div>
              <div className="mt-3 grid max-h-52 gap-2 overflow-y-auto rounded-xl border border-[var(--border)] bg-[var(--bg)]/40 p-2 sm:grid-cols-2">
                {locations.map((location) => (
                  <label
                    key={location.id}
                    className={`flex cursor-pointer items-center gap-3 rounded-lg border px-3 py-2.5 text-sm font-medium transition-colors ${locationIds.includes(location.id) ? "border-[var(--accent)]/40 bg-[var(--accent-muted)] text-[var(--accent-hover)]" : "border-transparent text-[var(--text)] hover:bg-[var(--bg-hover)]"}`}
                  >
                    <input
                      type="checkbox"
                      checked={locationIds.includes(location.id)}
                      onChange={() => setLocationIds((selected) => selected.includes(location.id) ? selected.filter((id) => id !== location.id) : [...selected, location.id])}
                      className="h-4 w-4 accent-[var(--accent)]"
                    />
                    {location.name}
                  </label>
                ))}
              </div>
            </fieldset>
            )}
            {venueMode === "ON_SITE" && (
              <div className="grid gap-4 sm:grid-cols-2">
                <Input
                  label="Outdoor venue name"
                  value={venueName}
                  onChange={(e) => setVenueName(e.target.value)}
                  placeholder="Park, hall, venue…"
                />
                <Input
                  label="Outdoor venue address"
                  value={venueAddress}
                  onChange={(e) => setVenueAddress(e.target.value)}
                  placeholder="Full address"
                />
              </div>
            )}
          </div>
        )}
        {step === 2 && (
          <div className="space-y-5">
            <div className="grid gap-4 sm:grid-cols-2">
              <Input
                label="Starts"
                type="datetime-local"
                value={startsAt}
                onChange={(e) => setStartsAt(e.target.value)}
                required
              />
              <Input
                label="Ends (optional)"
                type="datetime-local"
                value={endsAt}
                onChange={(e) => setEndsAt(e.target.value)}
              />
            </div>
            <div className="grid gap-4 sm:grid-cols-3">
              <Input
                label="Capacity (optional)"
                type="number"
                min="1"
                value={capacity}
                onChange={(e) => setCapacity(e.target.value)}
              />
              <label className="block text-sm font-medium text-[var(--text)]">
                Status
                <select
                  value={status}
                  onChange={(e) => setStatus(e.target.value)}
                  className="mt-1.5 w-full rounded-lg border border-[var(--border)] bg-[var(--bg-elevated)] px-3 py-2.5 text-sm text-[var(--text)]"
                >
                  <option value="DRAFT">Draft</option>
                  <option value="PUBLISHED">Published</option>
                  <option value="CANCELLED">Cancelled</option>
                  <option value="ARCHIVED">Archived</option>
                </select>
              </label>
              <label className="block text-sm font-medium text-[var(--text)]">
                Repeat
                <select
                  value={recurrence}
                  onChange={(e) => setRecurrence(e.target.value)}
                  className="mt-1.5 w-full rounded-lg border border-[var(--border)] bg-[var(--elevated)] px-3 py-2.5 text-sm text-[var(--text)]"
                >
                  <option value="NONE">Does not repeat</option>
                  <option value="DAILY">Daily</option>
                  <option value="WEEKLY">Weekly</option>
                  <option value="MONTHLY">Monthly</option>
                </select>
              </label>
            </div>
            {recurrence !== "NONE" && (
              <Input
                label="Repeat until"
                type="date"
                value={recurrenceEndsAt}
                onChange={(e) => setRecurrenceEndsAt(e.target.value)}
                required
              />
            )}
          </div>
        )}
        {step === 3 && (
          <div className="space-y-5">
            <div className="overflow-hidden rounded-xl border border-[var(--border)] bg-[var(--bg)]">
              <div className="flex min-h-36">
                <div className="flex h-36 w-36 shrink-0 items-center justify-center bg-[var(--bg-hover)]">
                  {imageUrl ? (
                    <img
                      src={imageUrl}
                      alt="Event preview"
                      className="h-full w-full object-cover"
                    />
                  ) : (
                    <ImageIcon className="h-8 w-8 text-[var(--text-faint)]" />
                  )}
                </div>
                <div className="min-w-0 p-4">
                  <p className="text-xs font-medium uppercase tracking-wide text-[var(--accent)]">
                    Ready to {event ? "update" : "create"}
                  </p>
                  <h3 className="mt-1 truncate text-lg font-semibold text-[var(--text)]">
                    {title}
                  </h3>
                  {description && (
                    <p className="mt-2 line-clamp-3 text-sm leading-relaxed text-[var(--text-muted)]">
                      {description}
                    </p>
                  )}
                </div>
              </div>
            </div>
            <div className="grid gap-3 sm:grid-cols-2">
              <div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-3">
                <p className="text-xs text-[var(--text-faint)]">When</p>
                <p className="mt-1 text-sm font-medium text-[var(--text)]">
                  {new Date(startsAt).toLocaleString()}
                </p>
                {endsAt && (
                  <p className="mt-1 text-xs text-[var(--text-muted)]">
                    Ends {new Date(endsAt).toLocaleString()}
                  </p>
                )}
              </div>
              <div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-3">
                <p className="text-xs text-[var(--text-faint)]">Where</p>
                <p className="mt-1 text-sm font-medium text-[var(--text)]">
                  {venueMode === "ON_SITE"
                    ? venueName || venueAddress
                    : selectedLocation}
                </p>
                {venueMode === "ON_SITE" && venueAddress && venueName && (
                  <p className="mt-1 text-xs text-[var(--text-muted)]">
                    {venueAddress}
                  </p>
                )}
              </div>
              <div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-3">
                <p className="text-xs text-[var(--text-faint)]">Organized by</p>
                <p className="mt-1 text-sm font-medium text-[var(--text)]">
                  {selectedLocation}
                </p>
              </div>
              <div className="rounded-xl border border-[var(--border)] bg-[var(--bg)] p-3">
                <p className="text-xs text-[var(--text-faint)]">Publishing</p>
                <p className="mt-1 text-sm font-medium capitalize text-[var(--text)]">
                  {status.toLowerCase()} · {recurrence.toLowerCase()}
                </p>
                {capacity && (
                  <p className="mt-1 text-xs text-[var(--text-muted)]">
                    Capacity: {capacity}
                  </p>
                )}
              </div>
            </div>
          </div>
        )}
        {error && (
          <p className="mt-5 rounded-lg bg-red-500/10 px-3 py-2 text-sm text-red-500">
            {error}
          </p>
        )}
      </div>
      <div className="flex shrink-0 items-center justify-between border-t border-[var(--border)] px-5 py-4 sm:px-6">
        <Button
          type="button"
          variant="secondary"
          onClick={step === 0 ? onClose : previous}
          disabled={saving}
        >
          {step === 0 ? (
            "Cancel"
          ) : (
            <>
              <ChevronLeft className="h-4 w-4" />
              Back
            </>
          )}
        </Button>
        {step < STEPS.length - 1 ? (
          <Button type="button" onClick={next}>
            Next
            <ChevronRight className="h-4 w-4" />
          </Button>
        ) : (
          <Button type="button" onClick={submit} disabled={saving}>
            {saving ? "Saving…" : event ? "Update event" : "Create event"}
          </Button>
        )}
      </div>
    </Modal>
  );
}
