"use client";

import { useState, type FormEvent } from "react";
import { useRouter } from "next/navigation";
import type { EventCategory, KolaboraEvent } from "@/types/event";
import { Button } from "@/components/ui/button";
import { Input, Select, Textarea } from "@/components/ui/input";
import { useToast } from "@/components/ui/toast";
import { clientFetch } from "@/lib/api/client";

interface OrganizerOption {
  id: number;
  name: string;
  email: string;
}

function toDatetimeLocal(value: string | null | undefined) {
  if (!value) return "";
  const date = new Date(value);
  const pad = (n: number) => String(n).padStart(2, "0");
  return `${date.getFullYear()}-${pad(date.getMonth() + 1)}-${pad(date.getDate())}T${pad(date.getHours())}:${pad(date.getMinutes())}`;
}

export function EventForm({
  categories,
  organizers,
  event,
  basePath = "/admin/events",
  attachSignatureProfile = false,
}: {
  categories: EventCategory[];
  organizers: OrganizerOption[];
  event?: KolaboraEvent;
  /** Where to redirect after a successful save — lets `/admin/signature/events/*` reuse this form without landing back in the general Event admin. */
  basePath?: string;
  /**
   * On create only: also attach a blank `signature_profile` row right after
   * the event is created, so it immediately counts as a Signature Event
   * (`whereHas('signatureProfile')` — see Admin\EventController::index()'s
   * `signature` filter) instead of only becoming one the next time an admin
   * happens to save the dedicated Signature content form. `/admin/signature/
   * events/new` passes this; `/admin/events/new` does not.
   */
  attachSignatureProfile?: boolean;
}) {
  const router = useRouter();
  const isEdit = Boolean(event);

  const [organizerId, setOrganizerId] = useState(String(organizers[0]?.id ?? ""));
  const [categoryId, setCategoryId] = useState(String(event?.category?.id ?? categories[0]?.id ?? ""));
  const [title, setTitle] = useState(event?.title ?? "");
  const [description, setDescription] = useState(event?.description ?? "");
  const [location, setLocation] = useState(event?.location ?? "");
  const [address, setAddress] = useState(event?.address ?? "");
  const [gmapsUrl, setGmapsUrl] = useState(event?.gmaps_url ?? "");
  const [startDate, setStartDate] = useState(toDatetimeLocal(event?.start_date));
  const [endDate, setEndDate] = useState(toDatetimeLocal(event?.end_date));
  const [slug, setSlug] = useState(event?.slug ?? "");
  const [metaTitle, setMetaTitle] = useState(event?.meta_title ?? "");
  const [metaDescription, setMetaDescription] = useState(event?.meta_description ?? "");
  const [ogImage, setOgImage] = useState(event?.og_image ?? "");

  const [formError, setFormError] = useState<string | null>(null);
  const [fieldErrors, setFieldErrors] = useState<Record<string, string[]>>({});
  const [isSubmitting, setIsSubmitting] = useState(false);
  const { toast } = useToast();

  async function handleSubmit(formEvent: FormEvent<HTMLFormElement>) {
    formEvent.preventDefault();
    setFormError(null);
    setFieldErrors({});
    setIsSubmitting(true);

    const payload = {
      ...(isEdit ? {} : { organizer_id: Number(organizerId) }),
      category_id: Number(categoryId),
      title,
      description: description || null,
      location: location || null,
      address: address || null,
      gmaps_url: gmapsUrl || null,
      start_date: startDate ? new Date(startDate).toISOString() : null,
      end_date: endDate ? new Date(endDate).toISOString() : null,
      ...(isEdit
        ? {
            slug,
            meta_title: metaTitle || null,
            meta_description: metaDescription || null,
            og_image: ogImage || null,
          }
        : {}),
    };

    const res = await clientFetch(isEdit ? `/api/admin/events/${event!.id}` : "/api/admin/events", {
      method: isEdit ? "PUT" : "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify(payload),
    });

    setIsSubmitting(false);
    const body = await res.json().catch(() => null);

    if (!res.ok) {
      const message = body?.message ?? "Failed to save event.";
      setFormError(message);
      setFieldErrors(body?.errors ?? {});
      toast(message, "error");
      return;
    }

    if (!isEdit && attachSignatureProfile) {
      // Best-effort: the event itself was already created successfully, so
      // don't block navigation on this — worst case the admin just saves the
      // Signature content form once on the next page to attach it manually.
      await clientFetch(`/api/admin/events/${body.data.id}/signature-profile`, {
        method: "PUT",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({}),
      }).catch(() => null);
    }

    toast(isEdit ? "Event updated successfully." : "Event created successfully.", "success");
    router.push(`${basePath}/${body.data.id}`);
    router.refresh();
  }

  return (
    <form onSubmit={handleSubmit} className="mt-6 flex flex-col gap-4">
      {!isEdit && (
        <label className="flex flex-col gap-1 text-sm font-medium">
          Owning Organizer
          <Select required value={organizerId} onChange={(e) => setOrganizerId(e.target.value)}>
            {organizers.length === 0 && <option value="">No Organizer accounts yet</option>}
            {organizers.map((o) => (
              <option key={o.id} value={o.id}>
                {o.name} ({o.email})
              </option>
            ))}
          </Select>
          <span className="text-xs font-normal text-kolabora-neutral-dark/70">
            The event will show up in this Organizer account&apos;s analytics. Promote an account to
            Organizer first under Admin &gt; User if there&apos;s no option yet.
          </span>
          {fieldErrors.organizer_id && <p className="text-sm text-red-600">{fieldErrors.organizer_id[0]}</p>}
        </label>
      )}

      <label className="flex flex-col gap-1 text-sm font-medium">
        Category
        <Select required value={categoryId} onChange={(e) => setCategoryId(e.target.value)}>
          {categories.map((c) => (
            <option key={c.id} value={c.id}>
              {c.name}
            </option>
          ))}
        </Select>
        {fieldErrors.category_id && <p className="text-sm text-red-600">{fieldErrors.category_id[0]}</p>}
      </label>

      <label className="flex flex-col gap-1 text-sm font-medium">
        Event Title
        <Input required value={title} onChange={(e) => setTitle(e.target.value)} />
        {fieldErrors.title && <p className="text-sm text-red-600">{fieldErrors.title[0]}</p>}
      </label>

      <label className="flex flex-col gap-1 text-sm font-medium">
        Description
        <Textarea rows={4} value={description} onChange={(e) => setDescription(e.target.value)} />
      </label>

      <label className="flex flex-col gap-1 text-sm font-medium">
        Location (City)
        <Input value={location} onChange={(e) => setLocation(e.target.value)} />
      </label>

      <label className="flex flex-col gap-1 text-sm font-medium">
        Full Address
        <Input value={address} onChange={(e) => setAddress(e.target.value)} />
      </label>

      <label className="flex flex-col gap-1 text-sm font-medium">
        Google Maps Link
        <Input
          type="url"
          placeholder="https://www.google.com/maps?q=..."
          value={gmapsUrl}
          onChange={(e) => setGmapsUrl(e.target.value)}
        />
        <span className="text-xs font-normal text-kolabora-neutral-dark/70">
          Paste the link from Google Maps&apos; &quot;Share&quot; button — shown as an embedded map on the event detail page (FR-024).
        </span>
      </label>

      <div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
        <label className="flex flex-col gap-1 text-sm font-medium">
          Starts
          <Input type="datetime-local" required value={startDate} onChange={(e) => setStartDate(e.target.value)} />
          {fieldErrors.start_date && <p className="text-sm text-red-600">{fieldErrors.start_date[0]}</p>}
        </label>

        <label className="flex flex-col gap-1 text-sm font-medium">
          Ends
          <Input type="datetime-local" required value={endDate} onChange={(e) => setEndDate(e.target.value)} />
          {fieldErrors.end_date && <p className="text-sm text-red-600">{fieldErrors.end_date[0]}</p>}
        </label>
      </div>

      {isEdit && (
        <div className="mt-2 border-t border-kolabora-neutral-dark/10 pt-4">
          <p className="text-sm font-medium">SEO (FR-119–123)</p>
          <div className="mt-3 flex flex-col gap-3">
            <label className="flex flex-col gap-1 text-sm font-medium">
              Slug
              <Input required value={slug} onChange={(e) => setSlug(e.target.value)} className="font-mono" />
              <span className="text-xs font-normal text-kolabora-neutral-dark/70">
                The public page shows at <code>/events/{slug || "slug"}</code>. Automatically
                normalized to lowercase and hyphens.
              </span>
              {fieldErrors.slug && <p className="text-sm text-red-600">{fieldErrors.slug[0]}</p>}
            </label>
            <label className="flex flex-col gap-1 text-sm font-medium">
              Meta Title
              <Input value={metaTitle} onChange={(e) => setMetaTitle(e.target.value)} placeholder={title} />
            </label>
            <label className="flex flex-col gap-1 text-sm font-medium">
              Meta Description
              <Textarea rows={2} value={metaDescription} onChange={(e) => setMetaDescription(e.target.value)} />
            </label>
            <label className="flex flex-col gap-1 text-sm font-medium">
              Open Graph Image URL
              <Input
                value={ogImage}
                onChange={(e) => setOgImage(e.target.value)}
                placeholder="https://... (leave empty to use the banner/thumbnail)"
              />
              <span className="text-xs font-normal text-kolabora-neutral-dark/70">
                The image shown when the event link is shared on social media (FR-124).
              </span>
            </label>
          </div>
        </div>
      )}

      {formError && <p className="text-sm text-red-600">{formError}</p>}

      <Button type="submit" size="lg" loading={isSubmitting} className="mt-2 self-start">
        {isEdit ? "Save Changes" : "Create Event"}
      </Button>
    </form>
  );
}
