"use client";

import Link from "next/link";
import { useRouter } from "next/navigation";
import { useEffect, useMemo, useState } from "react";
import { useRooSports } from "./app-provider";
import { ChildAgeNotice, ChildProfileSuccess } from "./child-profile-feedback";
import { toast } from "./ui/toast";
import { getPublicChildDisplay } from "@/lib/privacy";
import {
  MEDICAL_ALERT_MAX_LENGTH,
  RegistrationError,
  firstChildFieldError,
  getChildDateOfBirthRange,
  validateChildInput,
  type ChildFieldErrors,
} from "@/lib/registration";
import type { SportName } from "@/lib/demo-data";

type Step = "details" | "payment";

const childDateOfBirthRange = getChildDateOfBirthRange();

const fieldClass = (hasError = false) =>
  `rs-field w-full rounded-2xl px-4 py-3 text-sm ${
    hasError
      ? "!border-[#9a4338]/55 !bg-[#fff5f5] focus:!shadow-[0_0_0_4px_rgba(154,67,56,0.12)]"
      : ""
  }`;

export function CheckoutFlow({ eventId }: { eventId: string }) {
  const router = useRouter();
  const {
    role,
    user,
    children,
    activeChildId,
    addChild,
    getLiveEvent,
    startRegistration,
    confirmPayment,
    participantDisplayName,
  } = useRooSports();

  const event = getLiveEvent(eventId);
  const [step, setStep] = useState<Step>("details");
  const [participantId, setParticipantId] = useState(
    role === "parent" ? activeChildId || children[0]?.id || "" : "self",
  );
  const [addingChild, setAddingChild] = useState(false);
  const [nickname, setNickname] = useState("");
  const [dateOfBirth, setDateOfBirth] = useState("");
  const [medicalAlert, setMedicalAlert] = useState("");
  const [accepted, setAccepted] = useState(false);
  const [pendingBookingId, setPendingBookingId] = useState("");
  const [childFieldErrors, setChildFieldErrors] = useState<ChildFieldErrors>({});
  const [savingChild, setSavingChild] = useState(false);
  const [savedChildName, setSavedChildName] = useState("");
  const [error, setError] = useState("");
  const [submitting, setSubmitting] = useState(false);

  const selectedChild = useMemo(
    () => children.find((child) => child.id === participantId),
    [children, participantId],
  );

  useEffect(() => {
    if (!savedChildName) return;
    const dismiss = window.setTimeout(() => setSavedChildName(""), 1100);
    return () => window.clearTimeout(dismiss);
  }, [savedChildName]);

  if (!event) {
    return <div className="rs-soft-panel rounded-[2rem] p-8 text-center">Activity not found.</div>;
  }

  if (role !== "parent" && role !== "player") {
    return (
      <div className="rs-soft-panel rounded-[2rem] p-8 text-center">
        <h1 className="text-2xl font-bold">Registration unavailable</h1>
        <p className="mt-2 text-sm text-[#657384]">Only parents and adult players can register for activities.</p>
        <Link href={`/events/${event.id}`} className="mt-5 inline-flex text-sm font-bold text-[#315f70]">
          Back to activity
        </Link>
      </div>
    );
  }

  const registrationBlocked = event.status === "cancelled";
  const spotsLeft = Math.max(event.capacity - event.joined, 0);
  const playerLabel =
    role === "parent"
      ? selectedChild
        ? getPublicChildDisplay(selectedChild)
        : "Select above"
      : user
        ? `${user.firstName} (me)`
        : "Me";

  const saveNewChild = async () => {
    setError("");
    const errors = validateChildInput({ nickname, dateOfBirth, medicalAlert });
    setChildFieldErrors(errors);
    const message = firstChildFieldError(errors);
    if (message) {
      setError(message);
      return;
    }

    try {
      setSavingChild(true);
      const child = await addChild({
        nickname,
        dateOfBirth,
        primarySport: event.sport as SportName,
        medicalAlert,
      });
      setParticipantId(child.id);
      setAddingChild(false);
      setNickname("");
      setDateOfBirth("");
      setMedicalAlert("");
      setChildFieldErrors({});
      setSavedChildName(getPublicChildDisplay(child));
    } catch (error) {
      setError(error instanceof Error ? error.message : "Unable to create child profile.");
    } finally {
      setSavingChild(false);
    }
  };

  const goToPayment = () => {
    setError("");
    if (registrationBlocked) {
      setError("This activity has been cancelled.");
      return;
    }
    if (role === "parent" && !participantId) {
      setError("Select an existing child or add a new profile.");
      return;
    }
    if (!accepted) {
      setError("Please accept the activity waiver to continue.");
      return;
    }
    setSubmitting(true);
    try {
      const booking = startRegistration({
        eventId: event.id,
        participantId: role === "parent" ? participantId : "self",
        waiverAccepted: accepted,
      });
      setPendingBookingId(booking.id);
      setStep("payment");
    } catch (err) {
      setError(err instanceof RegistrationError ? err.message : "Unable to continue to registration.");
    } finally {
      setSubmitting(false);
    }
  };

  const finalizeBooking = () => {
    setError("");
    if (!pendingBookingId) {
      setError("Start registration again to continue.");
      return;
    }

    setSubmitting(true);
    try {
      confirmPayment(pendingBookingId);
      toast.success("Registration confirmed!", {
        description: `You are booked in for ${event.title}.`,
      });
      router.push("/booking/success");
    } catch (err) {
      const msg =
        err instanceof RegistrationError
          ? err.message
          : "Registration could not be completed.";
      setError(msg);
      toast.error("Booking error", { description: msg });
      setSubmitting(false);
    }
  };

  return (
    <div className="mx-auto max-w-5xl">
      <Link href={`/events/${event.id}`} className="inline-flex items-center gap-1 text-sm font-bold text-[#536273]">
        <span className="material-symbols-outlined">arrow_back</span>
        Back to activity
      </Link>

      <div className="mt-5 grid gap-6 lg:grid-cols-[1fr_340px]">
        <section className="rs-soft-panel rounded-[2.25rem] p-5 sm:p-8">
          <p className="text-xs font-bold uppercase tracking-[0.14em] text-[#ef7d00]">
            Step {step === "details" ? "1" : "2"} of 2
          </p>
          <h1 className="mt-2 text-3xl font-bold tracking-[-0.045em]">
            {step === "details" ? "Choose participant" : "Confirm registration"}
          </h1>
          <p className="mt-2 text-sm leading-6 text-[#657384]">
            {step === "details"
              ? "Select who is playing, accept the waiver, then continue to confirm."
              : "Review your details and confirm your free booking."}
          </p>

          {registrationBlocked && (
            <div className="mt-6 flex gap-3 rounded-2xl bg-[#f8e2df] p-4 text-sm text-[#8a2f2f]">
              <span className="material-symbols-outlined">block</span>
              <p>This activity has been cancelled. Registration is not available.</p>
            </div>
          )}

          {step === "details" ? (
            <>
              <fieldset className="mt-8" disabled={registrationBlocked}>
                <legend className="text-sm font-bold">Who is playing?</legend>
                <div className="mt-3 grid gap-3">
                  {role === "parent" ? (
                    <>
                      {children.map((child) => (
                        <label
                          key={child.id}
                          className={`flex cursor-pointer items-center gap-4 rounded-2xl p-4 transition ${
                            participantId === child.id
                              ? "bg-[#dfecef] shadow-[inset_0_1px_0_rgba(255,255,255,0.75)]"
                              : "bg-white/42 hover:bg-white/68"
                          }`}
                        >
                          <input
                            type="radio"
                            name="participant"
                            value={child.id}
                            checked={participantId === child.id}
                            onChange={() => setParticipantId(child.id)}
                            className="accent-[#315f70]"
                          />
                          <span className="grid h-11 w-11 place-items-center rounded-full bg-[#0d1b2a] font-bold text-white">
                            {getPublicChildDisplay(child).charAt(0)}
                          </span>
                          <span>
                            <strong className="block text-sm">{getPublicChildDisplay(child)}</strong>
                            <span className="mt-0.5 block text-xs text-[#667586]">
                              {child.ageGroup} · ages {event.ageMin}–{event.ageMax} activity
                            </span>
                          </span>
                        </label>
                      ))}

                      {!addingChild ? (
                        <button
                          type="button"
                          onClick={() => setAddingChild(true)}
                          className="flex items-center justify-center gap-2 rounded-2xl bg-white/42 px-4 py-4 text-sm font-bold text-[#315f70] transition hover:bg-white/70"
                        >
                          <span className="material-symbols-outlined">person_add</span>
                          Add a new child profile
                        </button>
                      ) : (
                        <div className="rounded-2xl bg-[#edf5f8]/75 p-4">
                          <p className="text-sm font-bold">Minimum child details</p>
                          <p className="mt-1 text-xs text-[#667586]">Nickname and date of birth only. No full legal name.</p>
                          <div className="mt-4 space-y-3">
                            <div>
                              <label htmlFor="checkout-nickname" className="mb-1.5 block text-xs font-bold">
                                Public nickname
                              </label>
                              <input
                                id="checkout-nickname"
                                value={nickname}
                                onChange={(e) => {
                                  setNickname(e.target.value);
                                  setChildFieldErrors((current) => ({ ...current, nickname: undefined }));
                                  setError("");
                                }}
                                placeholder="e.g. SportyJoey #88"
                                aria-invalid={Boolean(childFieldErrors.nickname)}
                                className={fieldClass(Boolean(childFieldErrors.nickname))}
                              />
                              {childFieldErrors.nickname ? (
                                <p className="mt-1.5 text-sm font-semibold text-[#9a4338]">{childFieldErrors.nickname}</p>
                              ) : null}
                            </div>
                            <div>
                              <div className="mb-1.5 flex items-center justify-between gap-3">
                                <label htmlFor="checkout-dob" className="text-xs font-bold">
                                  Date of birth
                                </label>
                                <ChildAgeNotice compact />
                              </div>
                              <input
                                id="checkout-dob"
                                type="date"
                                min={childDateOfBirthRange.min}
                                max={childDateOfBirthRange.max}
                                value={dateOfBirth}
                                onChange={(e) => {
                                  setDateOfBirth(e.target.value);
                                  setChildFieldErrors((current) => ({ ...current, dateOfBirth: undefined }));
                                  setError("");
                                }}
                                aria-invalid={Boolean(childFieldErrors.dateOfBirth)}
                                className={fieldClass(Boolean(childFieldErrors.dateOfBirth))}
                              />
                              {childFieldErrors.dateOfBirth ? (
                                <p className="mt-1.5 text-sm font-semibold text-[#9a4338]">{childFieldErrors.dateOfBirth}</p>
                              ) : null}
                            </div>
                            <div>
                              <label htmlFor="checkout-medical" className="mb-1.5 block text-xs font-bold">
                                Essential medical alert <span className="font-normal text-[#758293]">(optional)</span>
                              </label>
                              <input
                                id="checkout-medical"
                                value={medicalAlert}
                                onChange={(e) => {
                                  setMedicalAlert(e.target.value);
                                  setChildFieldErrors((current) => ({ ...current, medicalAlert: undefined }));
                                  setError("");
                                }}
                                maxLength={MEDICAL_ALERT_MAX_LENGTH}
                                placeholder="e.g. Asthma inhaler"
                                aria-invalid={Boolean(childFieldErrors.medicalAlert)}
                                className={fieldClass(Boolean(childFieldErrors.medicalAlert))}
                              />
                              <div className="mt-1.5 flex justify-between gap-3 text-[11px] text-[#758293]">
                                <span className={childFieldErrors.medicalAlert ? "font-semibold text-[#9a4338]" : ""}>
                                  {childFieldErrors.medicalAlert || "Approved staff only."}
                                </span>
                                <span className="shrink-0 font-semibold tabular-nums">
                                  {medicalAlert.length}/{MEDICAL_ALERT_MAX_LENGTH}
                                </span>
                              </div>
                            </div>
                            <div className="flex gap-2">
                              <button
                                type="button"
                                onClick={saveNewChild}
                                disabled={savingChild}
                                className="rs-secondary-action rounded-full px-4 py-2.5 text-sm font-bold disabled:cursor-wait disabled:opacity-60"
                              >
                                {savingChild ? "Saving..." : "Save child"}
                              </button>
                              <button
                                type="button"
                                onClick={() => {
                                  setAddingChild(false);
                                  setChildFieldErrors({});
                                  setError("");
                                }}
                                className="rounded-full bg-white/65 px-4 py-2.5 text-sm font-bold transition hover:bg-white"
                              >
                                Cancel
                              </button>
                            </div>
                          </div>
                        </div>
                      )}
                    </>
                  ) : (
                    <label className="flex cursor-pointer items-center gap-4 rounded-2xl bg-[#dfecef] p-4">
                      <input type="radio" checked readOnly className="accent-[#315f70]" />
                      <span className="grid h-11 w-11 place-items-center rounded-full bg-[#0d1b2a] font-bold text-white">
                        {(user?.firstName || "A").charAt(0)}
                      </span>
                      <span>
                        <strong className="block text-sm">{user ? `${user.firstName} (me)` : "Me"}</strong>
                        <span className="mt-0.5 block text-xs text-[#667586]">Adult player · self registration</span>
                      </span>
                    </label>
                  )}
                </div>
              </fieldset>

              {selectedChild?.medicalAlert ? (
                <div className="mt-6 flex gap-3 rounded-2xl bg-[#fff0d9] p-4">
                  <span className="material-symbols-outlined text-[#b65c00]">health_and_safety</span>
                  <div>
                    <p className="text-sm font-bold">Essential safety note</p>
                    <p className="mt-1 text-xs leading-5 text-[#715f49]">
                      {selectedChild.medicalAlert}. Only approved staff can access this during the active session.
                    </p>
                  </div>
                </div>
              ) : null}

              <label className="mt-7 flex cursor-pointer items-start gap-3 rounded-2xl bg-white/44 p-4 text-sm leading-6 text-[#536273]">
                <input
                  type="checkbox"
                  checked={accepted}
                  onChange={(e) => setAccepted(e.target.checked)}
                  disabled={registrationBlocked}
                  className="mt-1 h-4 w-4 shrink-0 accent-[#315f70]"
                />
                <span>
                  I confirm the participant information is correct and accept the activity waiver for this session.
                </span>
              </label>
            </>
          ) : (
            <div className="mt-8 space-y-5">
              <div className="rounded-[1.6rem] bg-[#dfecef]/65 p-5">
                <div className="flex items-start justify-between gap-3">
                  <div>
                    <p className="text-xs font-bold uppercase tracking-[0.12em] text-[#6b7888]">Registration</p>
                    <p className="mt-2 text-sm leading-6 text-[#536273]">
                      This activity is free and open to everyone. No credit card or fee is required.
                    </p>
                  </div>
                  <span className="material-symbols-outlined text-[#315f70]">check_circle</span>
                </div>
                <div className="mt-4 flex items-end justify-between border-t border-[#adc0c8]/30 pt-4">
                  <span className="text-sm text-[#667586]">Amount due</span>
                  <strong className="text-3xl tracking-[-0.04em]">
                    Free
                  </strong>
                </div>
              </div>

              <div className="rounded-2xl bg-[#dcefe4] p-4 text-sm text-[#2f6b48]">
                This activity is free. Confirm below to complete your registration and secure your place.
              </div>

              <button
                type="button"
                onClick={() => setStep("details")}
                className="text-sm font-bold text-[#315f70]"
              >
                Back to participant details
              </button>
            </div>
          )}

          {error ? (
            <div className="mt-5 flex gap-2 rounded-2xl bg-[#f8e2df] px-4 py-3 text-sm font-semibold text-[#9a4338]">
              <span className="material-symbols-outlined text-[20px]">error</span>
              <p>{error}</p>
            </div>
          ) : null}
        </section>

        <aside className="relative h-fit overflow-hidden rounded-[2.25rem] bg-[#f6e8c4] p-6 text-[#0b0f12] lg:sticky lg:top-24">
          <span className="absolute -right-12 -top-14 h-36 w-36 rounded-full bg-[#ffd47e]/65" />
          <span className="absolute -right-2 top-4 h-24 w-24 rounded-full border-[16px] border-white/38" />
          <div className="relative">
          <p className="text-xs font-bold uppercase tracking-[0.12em] text-[#9a570f]">Booking summary</p>
          <h2 className="mt-3 text-xl font-bold">{event.title}</h2>
          <div className="mt-5 space-y-3 border-y border-[#8b6a51]/16 py-5 text-sm text-[#715f49]">
            <p className="flex justify-between gap-4">
              <span>Date</span>
              <strong className="text-right text-[#0b0f12]">{event.dateLabel}</strong>
            </p>
            <p className="flex justify-between gap-4">
              <span>Time</span>
              <strong className="text-right text-[#0b0f12]">{event.time}</strong>
            </p>
            <p className="flex justify-between gap-4">
              <span>Player</span>
              <strong className="text-right text-[#0b0f12]">{playerLabel}</strong>
            </p>
            <p className="flex justify-between gap-4">
              <span>Spots left</span>
              <strong className="text-right text-[#0b0f12]">{spotsLeft}</strong>
            </p>
            <p className="flex justify-between gap-4">
              <span>Venue</span>
              <strong className="text-right text-[#0b0f12]">{event.venue}</strong>
            </p>
          </div>
          <div className="mt-5 flex items-end justify-between">
            <span className="text-sm text-[#715f49]">Total</span>
            <strong className="text-3xl">Free</strong>
          </div>

          {step === "details" ? (
            <button
              type="button"
              onClick={goToPayment}
              disabled={registrationBlocked || submitting}
              className="rs-primary-action mt-6 flex w-full items-center justify-center gap-2 rounded-full px-5 py-3.5 text-sm font-bold disabled:cursor-not-allowed disabled:opacity-45"
            >
              {submitting ? "Checking..." : "Continue to confirm"}
              <span className="material-symbols-outlined">arrow_forward</span>
            </button>
          ) : (
            <div className="mt-6 space-y-3">
              <button
                type="button"
                onClick={() => finalizeBooking()}
                disabled={submitting}
                className="rs-primary-action flex w-full items-center justify-center gap-2 rounded-full px-5 py-3.5 text-sm font-bold disabled:cursor-not-allowed disabled:opacity-45"
              >
                {submitting
                  ? "Confirming..."
                  : "Confirm free place"}
                <span className="material-symbols-outlined">check_circle</span>
              </button>
            </div>
          )}
          <p className="mt-3 text-center text-[11px] leading-4 text-[#806f62]">
            {step === "details"
              ? "Select your participant and accept waiver to confirm."
              : "Click to complete your registration immediately."}
          </p>
          {pendingBookingId && step === "payment" ? (
            <p className="mt-2 text-center text-[11px] text-[#806f62]">
              Registering {participantDisplayName(participantId || "self")}
            </p>
          ) : null}
          </div>
        </aside>
      </div>
      {savedChildName ? <ChildProfileSuccess childName={savedChildName} /> : null}
    </div>
  );
}
