"use client";

import { useEffect, useRef, useState, type FormEvent } from "react";
import { Button } from "@/components/ui/button";
import { formatBallboxDateTime } from "@/lib/ballbox-datetime";

type ClassAtcSlot = {
  start: string;
  durationMinutes: number;
  priceMinor: number | null;
  currency: string | null;
  sportclubId: string | null;
  courtId: string | null;
  courtName: string | null;
};

type ClassesRequestFormProps = {
  classOfferId: string;
  slots: ClassAtcSlot[];
  loadingSlots?: boolean;
  initialSelectedSlot?: ClassAtcSlot | null;
};

function formatMoney(value: number | null, currency: string | null) {
  if (value === null || !currency) return "Precio a confirmar";

  return new Intl.NumberFormat("es-AR", {
    style: "currency",
    currency,
    maximumFractionDigits: 0,
  }).format(value / 100);
}

function slotKey(slot: ClassAtcSlot) {
  return [
    slot.start,
    slot.durationMinutes,
    slot.priceMinor ?? "null",
    slot.currency ?? "null",
    slot.sportclubId ?? "null",
    slot.courtId ?? "null",
  ].join("|");
}

function resolveInitialSelection(slots: ClassAtcSlot[], initialSelectedSlot: ClassAtcSlot | null) {
  if (initialSelectedSlot) {
    const matchedSlot = slots.find((slot) => slotKey(slot) === slotKey(initialSelectedSlot));
    if (matchedSlot) {
      return {
        selectionMode: "slot" as const,
        selectedSlotKey: slotKey(matchedSlot),
      };
    }
  }

  return {
    selectionMode: slots.length === 0 ? ("flexible" as const) : null,
    selectedSlotKey: "",
  };
}

export function ClassesRequestForm({ classOfferId, slots, loadingSlots = false, initialSelectedSlot = null }: ClassesRequestFormProps) {
  const errorId = "classes-request-error";
  const successId = "classes-request-success";
  const matchedInitialSlot = initialSelectedSlot
    ? slots.find((slot) => slotKey(slot) === slotKey(initialSelectedSlot))
      ?? slots.find(
          (slot) =>
            slot.start === initialSelectedSlot.start
            && slot.durationMinutes === initialSelectedSlot.durationMinutes
            && (initialSelectedSlot.sportclubId ? slot.sportclubId === initialSelectedSlot.sportclubId : true)
        )
      ?? initialSelectedSlot
    : null;
  const displaySlots = matchedInitialSlot ? [matchedInitialSlot] : slots;
  const showFlexibleOption = !matchedInitialSlot;
  const initialSelection = resolveInitialSelection(displaySlots, matchedInitialSlot);
  const [pending, setPending] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [success, setSuccess] = useState<string | null>(null);
  const [selectionMode, setSelectionMode] = useState<"slot" | "flexible" | null>(initialSelection.selectionMode);
  const [selectedSlotKey, setSelectedSlotKey] = useState<string>(initialSelection.selectedSlotKey);
  const studentNameInputRef = useRef<HTMLInputElement | null>(null);

  useEffect(() => {
    if (selectionMode !== "slot" || selectedSlotKey.length === 0) {
      return;
    }

    studentNameInputRef.current?.focus();
  }, [selectedSlotKey, selectionMode]);

  async function handleSubmit(event: FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const form = event.currentTarget;
    setPending(true);
    setError(null);
    setSuccess(null);

    if (!selectionMode) {
      setError("Elige un horario visible o marca cualquier horario / lugar.");
      setPending(false);
      return;
    }

    const selectedSlot = selectionMode === "slot" ? displaySlots.find((slot) => slotKey(slot) === selectedSlotKey) ?? null : null;
    if (selectionMode === "slot" && !selectedSlot) {
      setError("Elige un horario valido antes de enviar la solicitud.");
      setPending(false);
      return;
    }

    const formData = new FormData(form);
    const payload = {
      classOfferId,
      studentName: String(formData.get("studentName") ?? ""),
      studentEmail: String(formData.get("studentEmail") ?? ""),
      studentPhone: String(formData.get("studentPhone") ?? ""),
      message: String(formData.get("message") ?? ""),
      selectionMode,
      ...(selectedSlot
        ? {
            selectedSlotStart: selectedSlot.start,
            selectedSlotDurationMinutes: selectedSlot.durationMinutes,
            selectedSlotPriceMinor: selectedSlot.priceMinor,
            selectedSlotCurrency: selectedSlot.currency,
            selectedAtcSportclubId: selectedSlot.sportclubId,
            selectedAtcCourtId: selectedSlot.courtId,
          }
        : {}),
    };

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

    const body = (await response.json().catch(() => null)) as { ok?: boolean; error?: string; item?: { id: string } } | null;

    if (!response.ok || !body || body.ok !== true) {
      setError(
        body?.error === "SLOT_NOT_AVAILABLE"
          ? "Ese horario ya no aparece disponible. Elige otro o usa cualquier horario / lugar."
          : "No pudimos guardar la solicitud. Revisa los datos e intenta de nuevo."
      );
      setPending(false);
      return;
    }

    form.reset();
    setSelectionMode(slots.length === 0 ? "flexible" : null);
    setSelectedSlotKey("");
    setSuccess(
      selectionMode === "slot"
        ? "Solicitud enviada con el horario elegido. Ballbox la guardo como lead local para seguimiento."
        : "Solicitud enviada con preferencia flexible. Ballbox la guardo como lead local para seguimiento."
    );
    setPending(false);
  }

  return (
    <form
      id="request-form"
      onSubmit={handleSubmit}
      data-local-submit="true"
      className="space-y-4 rounded-[1.75rem] border border-white/10 bg-[#101510]/95 p-6 shadow-[0_24px_60px_-35px_rgba(0,0,0,0.55)]"
    >
      <div>
        <p className="text-xs uppercase tracking-[0.22em] text-[#c4d600]">Solicitar</p>
        <h2 className="mt-2 text-2xl font-semibold text-white">Elige horario y deja tus datos</h2>
        <p className="mt-2 text-sm leading-6 text-white/65">
          Elige uno de los horarios visibles o usa cualquier horario / lugar como fallback. Ballbox guarda la solicitud localmente; no hay booking ATC automatico en este MVP.
        </p>
      </div>

      <fieldset className="space-y-3 rounded-[1.5rem] border border-white/10 bg-black/20 p-4">
        <legend className="px-2 text-sm font-medium text-white">Horario preferido</legend>
        {loadingSlots ? (
          <p className="text-sm text-white/65">Buscando horarios visibles de ATC...</p>
        ) : null}
        {displaySlots.length > 0 ? (
          <div className="space-y-3">
            {displaySlots.map((slot) => {
              const key = slotKey(slot);
              const checked = selectionMode === "slot" && selectedSlotKey === key;

              return (
                <label
                  key={key}
                  className={`flex cursor-pointer items-start gap-3 rounded-2xl border px-4 py-3 text-sm transition ${
                    checked ? "border-[#c4d600]/50 bg-[#c4d600]/10 text-white" : "border-white/10 bg-black/10 text-white/80"
                  }`}
                >
                  <input
                    type="radio"
                    name="slotSelection"
                    className="mt-1"
                    checked={checked}
                    onChange={() => {
                      setSelectionMode("slot");
                      setSelectedSlotKey(key);
                    }}
                  />
                  <div className="space-y-1">
                    <p className="font-medium text-white">{formatBallboxDateTime(slot.start)}</p>
                    <p className="text-white/65">
                      {slot.durationMinutes} min{slot.courtName ? ` - ${slot.courtName}` : ""}
                    </p>
                    <p className="text-[#d8ea57]">{formatMoney(slot.priceMinor, slot.currency)}</p>
                  </div>
                </label>
              );
            })}
          </div>
        ) : !loadingSlots ? (
          <p className="text-sm text-white/65">No hay horarios visibles ahora mismo. Puedes enviar la solicitud como cualquier horario / lugar.</p>
        ) : null}

        {showFlexibleOption ? (
          <label className="flex cursor-pointer items-start gap-3 rounded-2xl border border-dashed border-white/15 bg-black/10 px-4 py-3 text-sm text-white/80">
            <input
              type="radio"
              name="slotSelection"
              className="mt-1"
              checked={selectionMode === "flexible"}
              onChange={() => {
                setSelectionMode("flexible");
                setSelectedSlotKey("");
              }}
            />
            <div>
              <p className="font-medium text-white">Cualquier horario / lugar</p>
              <p className="mt-1 text-white/60">Usa esta opcion si las alternativas visibles no te sirven. Luego aclara tus condiciones en el mensaje.</p>
            </div>
          </label>
        ) : null}
      </fieldset>

      <div className="grid gap-4 sm:grid-cols-2">
        <label className="space-y-2 text-sm text-white/80">
          <span>Nombre</span>
          <input
            ref={studentNameInputRef}
            name="studentName"
            required
            aria-invalid={error ? true : undefined}
            aria-describedby={error ? errorId : success ? successId : undefined}
            className="h-11 w-full rounded-xl border border-white/15 bg-black/20 px-4 text-white outline-none focus:border-[#c4d600]/50"
          />
        </label>
        <label className="space-y-2 text-sm text-white/80">
          <span>Email</span>
          <input
            name="studentEmail"
            type="email"
            required
            aria-invalid={error ? true : undefined}
            aria-describedby={error ? errorId : success ? successId : undefined}
            className="h-11 w-full rounded-xl border border-white/15 bg-black/20 px-4 text-white outline-none focus:border-[#c4d600]/50"
          />
        </label>
      </div>

      <label className="space-y-2 text-sm text-white/80">
        <span>Telefono</span>
        <input
          name="studentPhone"
          aria-invalid={error ? true : undefined}
          aria-describedby={error ? errorId : success ? successId : undefined}
          className="h-11 w-full rounded-xl border border-white/15 bg-black/20 px-4 text-white outline-none focus:border-[#c4d600]/50"
        />
      </label>

      <label className="space-y-2 text-sm text-white/80">
        <span>Mensaje</span>
        <textarea
          name="message"
          rows={4}
          aria-invalid={error ? true : undefined}
          aria-describedby={error ? errorId : success ? successId : undefined}
          className="w-full rounded-xl border border-white/15 bg-black/20 px-4 py-3 text-white outline-none focus:border-[#c4d600]/50"
          placeholder="Objetivo, nivel y condiciones. Ejemplo: me sirven martes o jueves despues de las 19, o sedes Palermo/Belgrano."
        />
      </label>

      {error ? <p id={errorId} role="alert" className="rounded-xl border border-red-500/30 bg-red-500/10 px-4 py-3 text-sm text-red-200">{error}</p> : null}
      {success ? <p id={successId} role="status" aria-live="polite" className="rounded-xl border border-[#c4d600]/25 bg-[#c4d600]/10 px-4 py-3 text-sm text-[#d8ea57]">{success}</p> : null}

      <Button
        type="submit"
        loading={pending}
        disabled={pending}
        className="h-11 w-full rounded-xl text-sm font-medium disabled:cursor-not-allowed disabled:bg-[#7f9012] disabled:text-[#0b0e09]"
      >
        {pending ? "Enviando..." : "Solicitar clase"}
      </Button>
    </form>
  );
}
