import { useMemo, useState } from "react";
import { Check } from "lucide-react";
import { addons, packages, policies, services, type Package } from "@/data/site";
import { Button } from "@/components/ui/button";
import { Field, Input, Select, Textarea } from "@/components/ui/field";
import { formatUsd, uid } from "@/lib/utils";
import { cn } from "@/lib/utils";

type Step = "service" | "package" | "details" | "policies" | "pay" | "done";

const steps: Step[] = ["service", "package", "details", "policies", "pay", "done"];

type Form = {
  serviceId: string;
  packageId: string;
  name: string;
  email: string;
  phone: string;
  date: string;
  location: string;
  budget: string;
  notes: string;
  agreed: boolean;
};

const empty: Form = {
  serviceId: "",
  packageId: "",
  name: "",
  email: "",
  phone: "",
  date: "",
  location: "",
  budget: "",
  notes: "",
  agreed: false,
};

function persistBooking(record: Record<string, unknown>) {
  try {
    const prev = JSON.parse(localStorage.getItem("ferrylore-bookings") || "[]") as unknown[];
    localStorage.setItem("ferrylore-bookings", JSON.stringify([record, ...prev].slice(0, 20)));
  } catch {
    /* ignore */
  }
}

export function BookingFlow({
  initialService,
  initialPackage,
}: {
  initialService?: string;
  initialPackage?: string;
}) {
  const [step, setStep] = useState<Step>(
    initialService ? "package" : "service",
  );
  const [form, setForm] = useState<Form>({
    ...empty,
    serviceId: initialService ?? "",
    packageId: initialPackage ?? "",
  });
  const [busy, setBusy] = useState(false);
  const [id, setId] = useState("");
  const [card, setCard] = useState({ name: "", number: "", expiry: "", cvc: "" });
  const [error, setError] = useState("");

  const pkg: Package | undefined = packages.find((p) => p.id === form.packageId);
  const service = services.find((s) => s.id === form.serviceId);
  const filtered = useMemo(
    () =>
      form.serviceId
        ? packages.filter((p) => p.serviceIds.includes(form.serviceId) || p.id === "signature")
        : packages,
    [form.serviceId],
  );

  const deposit = pkg
    ? pkg.priceValue
      ? Math.round((pkg.priceValue * pkg.depositPct) / 100)
      : 250
    : 0;

  const set = <K extends keyof Form>(key: K, value: Form[K]) =>
    setForm((f) => ({ ...f, [key]: value }));

  const go = (next: Step) => {
    setError("");
    setStep(next);
    window.scrollTo({ top: 0, behavior: "smooth" });
  };

  const today = new Date().toISOString().slice(0, 10);

  function validateDetails() {
    if (!form.name.trim() || !form.email.trim() || !form.date || !form.location.trim()) {
      setError("Please add your name, email, date, and location.");
      return false;
    }
    if (!form.email.includes("@")) {
      setError("Please enter a valid email.");
      return false;
    }
    return true;
  }

  function onPay() {
    if (card.name.trim().length < 2 || card.number.replace(/\s/g, "").length < 12) {
      setError("Enter the name and card number to place the deposit.");
      return;
    }
    setBusy(true);
    window.setTimeout(() => {
      const bookingId = uid("FL");
      setId(bookingId);
      persistBooking({
        id: bookingId,
        ...form,
        packageName: pkg?.name,
        deposit,
        createdAt: new Date().toISOString(),
      });
      setBusy(false);
      go("done");
    }, 1100);
  }

  const idx = steps.indexOf(step);

  return (
    <div className="mx-auto max-w-3xl">
      <ol className="mb-12 flex flex-wrap gap-2 text-[0.62rem] uppercase tracking-[0.18em] text-muted">
        {steps.slice(0, -1).map((s, i) => (
          <li
            key={s}
            className={cn(
              "rounded-full px-3 py-1.5",
              i === idx ? "bg-ivory text-ink" : i < idx ? "text-gold" : "text-muted",
            )}
          >
            {s}
          </li>
        ))}
      </ol>

      {step === "service" && (
        <div>
          <h2 className="font-serif text-4xl">What are we creating?</h2>
          <p className="mt-3 text-muted">Choose the story. Packages follow.</p>
          <div className="mt-8 grid gap-3">
            {services.map((s) => (
              <button
                key={s.id}
                type="button"
                onClick={() => {
                  set("serviceId", s.id);
                  go("package");
                }}
                className="flex items-center justify-between rounded-xl border border-line bg-ink-soft px-5 py-5 text-left transition-colors hover:border-gold/50"
              >
                <span>
                  <span className="block font-serif text-2xl">{s.title}</span>
                  <span className="mt-1 block text-sm text-muted">{s.from}</span>
                </span>
                <span className="text-[0.65rem] uppercase tracking-[0.18em] text-gold">
                  Select
                </span>
              </button>
            ))}
          </div>
        </div>
      )}

      {step === "package" && (
        <div>
          <h2 className="font-serif text-4xl">Choose a package</h2>
          <p className="mt-3 text-muted">
            {service ? service.title : "A FerryLore story"} — simple packages, beautiful results.
          </p>
          <div className="mt-8 grid gap-4">
            {filtered.map((p) => (
              <button
                key={p.id}
                type="button"
                onClick={() => {
                  set("packageId", p.id);
                  go("details");
                }}
                className={cn(
                  "rounded-xl border bg-ink-soft p-6 text-left transition-colors hover:border-gold/50",
                  p.popular ? "border-gold/60" : "border-line",
                )}
              >
                <div className="flex items-baseline justify-between gap-4">
                  <p className="font-serif text-2xl">{p.name}</p>
                  <p className="font-serif text-2xl text-gold">{p.price}</p>
                </div>
                {p.popular ? (
                  <p className="mt-2 text-[0.65rem] uppercase tracking-[0.2em] text-gold">
                    Most popular
                  </p>
                ) : null}
                <p className="mt-3 text-sm text-muted">{p.blurb}</p>
              </button>
            ))}
          </div>
          <button
            type="button"
            className="mt-6 text-sm text-muted hover:text-ivory"
            onClick={() => go("service")}
          >
            Back
          </button>
        </div>
      )}

      {step === "details" && (
        <div>
          <h2 className="font-serif text-4xl">Tell us about the day</h2>
          <p className="mt-3 text-muted">
            {pkg?.name} · {pkg?.price}
          </p>
          <div className="mt-8 grid gap-5 sm:grid-cols-2">
            <Field label="Name" htmlFor="name">
              <Input
                id="name"
                value={form.name}
                onChange={(e) => set("name", e.target.value)}
                autoComplete="name"
              />
            </Field>
            <Field label="Email" htmlFor="email">
              <Input
                id="email"
                type="email"
                value={form.email}
                onChange={(e) => set("email", e.target.value)}
                autoComplete="email"
              />
            </Field>
            <Field label="Phone" htmlFor="phone">
              <Input
                id="phone"
                type="tel"
                value={form.phone}
                onChange={(e) => set("phone", e.target.value)}
                autoComplete="tel"
              />
            </Field>
            <Field label="Date" htmlFor="date">
              <Input
                id="date"
                type="date"
                min={today}
                value={form.date}
                onChange={(e) => set("date", e.target.value)}
              />
            </Field>
            <Field label="Location" htmlFor="location">
              <Input
                id="location"
                value={form.location}
                onChange={(e) => set("location", e.target.value)}
                placeholder="City, venue, or neighborhood"
              />
            </Field>
            <Field label="Estimated budget" htmlFor="budget">
              <Select
                id="budget"
                value={form.budget}
                onChange={(e) => set("budget", e.target.value)}
              >
                <option value="">Select</option>
                <option>Under $500</option>
                <option>$500–$1,000</option>
                <option>$1,000–$2,500</option>
                <option>$2,500+</option>
                <option>Not sure yet</option>
              </Select>
            </Field>
            <div className="sm:col-span-2">
              <Field label="What are you looking for?" htmlFor="notes">
                <Textarea
                  id="notes"
                  value={form.notes}
                  onChange={(e) => set("notes", e.target.value)}
                  placeholder="The feeling, the people, the place."
                />
              </Field>
            </div>
          </div>
          {error ? <p className="mt-4 text-sm text-gold">{error}</p> : null}
          <div className="mt-8 flex flex-wrap gap-3">
            <Button
              onClick={() => {
                if (validateDetails()) go("policies");
              }}
            >
              Continue
            </Button>
            <Button variant="ghost" onClick={() => go("package")}>
              Back
            </Button>
          </div>
        </div>
      )}

      {step === "policies" && pkg && (
        <div>
          <h2 className="font-serif text-4xl">Before you reserve</h2>
          <p className="mt-3 text-muted">
            Payment structure and policies — please read them before the deposit.
          </p>
          <div className="mt-8 rounded-xl border border-line bg-ink-soft p-6">
            <p className="text-[0.68rem] uppercase tracking-[0.2em] text-gold">
              {pkg.depositPct}% deposit
            </p>
            <p className="mt-2 font-serif text-4xl">{formatUsd(deposit)}</p>
            <p className="mt-2 text-sm text-muted">
              Due now to hold {form.date} · Remaining balance per the schedule below.
            </p>
          </div>
          <ul className="mt-8 space-y-3 text-sm text-ivory/80">
            {(pkg.depositPct === 50 ? policies.small : policies.large).map((p) => (
              <li key={p} className="flex gap-3">
                <Check className="mt-0.5 size-4 shrink-0 text-gold" />
                {p}
              </li>
            ))}
            {policies.cancel.map((p) => (
              <li key={p} className="flex gap-3">
                <Check className="mt-0.5 size-4 shrink-0 text-gold" />
                {p}
              </li>
            ))}
          </ul>
          <label className="mt-8 flex items-start gap-3 text-sm text-ivory/80">
            <input
              type="checkbox"
              className="mt-1 size-4 accent-gold"
              checked={form.agreed}
              onChange={(e) => set("agreed", e.target.checked)}
            />
            I have read the cancellation, rescheduling, and delivery policies.
          </label>
          {error ? <p className="mt-4 text-sm text-gold">{error}</p> : null}
          <div className="mt-8 flex flex-wrap gap-3">
            <Button
              onClick={() => {
                if (!form.agreed) {
                  setError("Please confirm you’ve read the policies.");
                  return;
                }
                go("pay");
              }}
            >
              Continue to deposit
            </Button>
            <Button variant="ghost" onClick={() => go("details")}>
              Back
            </Button>
          </div>
        </div>
      )}

      {step === "pay" && pkg && (
        <div>
          <h2 className="font-serif text-4xl">Pay the deposit</h2>
          <p className="mt-3 text-muted">
            {formatUsd(deposit)} to reserve {form.date} · {pkg.name}
          </p>
          <div className="mt-8 grid gap-5">
            <Field label="Name on card" htmlFor="ccname">
              <Input
                id="ccname"
                value={card.name}
                onChange={(e) => setCard((c) => ({ ...c, name: e.target.value }))}
                autoComplete="cc-name"
              />
            </Field>
            <Field label="Card number" htmlFor="ccnum">
              <Input
                id="ccnum"
                inputMode="numeric"
                placeholder="4242 4242 4242 4242"
                value={card.number}
                onChange={(e) => setCard((c) => ({ ...c, number: e.target.value }))}
                autoComplete="cc-number"
              />
            </Field>
            <div className="grid grid-cols-2 gap-5">
              <Field label="Expiry" htmlFor="ccexp">
                <Input
                  id="ccexp"
                  placeholder="MM/YY"
                  value={card.expiry}
                  onChange={(e) => setCard((c) => ({ ...c, expiry: e.target.value }))}
                  autoComplete="cc-exp"
                />
              </Field>
              <Field label="CVC" htmlFor="cccvc">
                <Input
                  id="cccvc"
                  placeholder="123"
                  value={card.cvc}
                  onChange={(e) => setCard((c) => ({ ...c, cvc: e.target.value }))}
                  autoComplete="cc-csc"
                />
              </Field>
            </div>
          </div>
          <p className="mt-4 text-xs text-muted">
            Preview checkout — no live charge is processed here. Your reservation is stored so the studio can send a real invoice.
          </p>
          {error ? <p className="mt-4 text-sm text-gold">{error}</p> : null}
          <div className="mt-8 flex flex-wrap gap-3">
            <Button onClick={onPay} disabled={busy}>
              {busy ? "Reserving…" : `Pay ${formatUsd(deposit)} deposit`}
            </Button>
            <Button variant="ghost" onClick={() => go("policies")}>
              Back
            </Button>
          </div>
        </div>
      )}

      {step === "done" && (
        <div className="text-center">
          <p className="text-[0.7rem] uppercase tracking-[0.28em] text-gold">Reserved</p>
          <h2 className="mt-3 font-serif text-4xl sm:text-5xl">Your story is on the calendar.</h2>
          <p className="mx-auto mt-4 max-w-md text-muted">
            Confirmation {id}. We’ll email a questionnaire within a day, then prepare for{" "}
            {form.date} in {form.location}.
          </p>
          <div className="mx-auto mt-10 max-w-md rounded-xl border border-line bg-ink-soft p-6 text-left text-sm">
            <p>
              <span className="text-muted">Package</span> · {pkg?.name}
            </p>
            <p className="mt-2">
              <span className="text-muted">Deposit</span> · {formatUsd(deposit)}
            </p>
            <p className="mt-2">
              <span className="text-muted">Next</span> · Questionnaire, prep, shoot, edit, gallery,
              then a note asking for a review and a referral — if it felt like FerryLore.
            </p>
          </div>
          <div className="mt-10 flex flex-wrap justify-center gap-3">
            <Button to="/">Return home</Button>
            <Button to="/stories" variant="outline">
              View our stories
            </Button>
          </div>
        </div>
      )}

      {step !== "done" ? (
        <p className="mt-16 text-center text-xs text-muted">
          Add-ons such as drone, second shooter, or same-day preview can be arranged after we talk.
          {addons[0] ? ` Starting from ${addons[0].price}.` : ""}
        </p>
      ) : null}
    </div>
  );
}
