"use client";

import { useRouter } from "next/navigation";
import { useEffect, useState } from "react";
import { reachGoal } from "@/lib/analytics";
import { useCart, useCartTotals } from "./cart-provider";

type Info = { hours?: { orders?: { start?: string; end?: string; note?: string } }; delivery?: { enabled?: boolean }; pickup?: { enabled?: boolean }; zones?: { name: string; min_order: number }[] } | null;

const CHECKOUT_ERRORS: Record<string, string> = {
  min_sum: "Сумма заказа меньше минимальной. Добавьте позиции или выберите самовывоз.",
  offhours: "Ресторан сейчас закрыт. Выберите другое время или самовывоз в рабочие часы.",
  zone_unknown: "По этому адресу доставка недоступна. Проверьте адрес или выберите самовывоз.",
  datetime_past: "Выбранное время уже прошло. Выберите другое время.",
  datetime_invalid: "Проверьте дату и время заказа.",
  pickup_disabled: "Самовывоз временно недоступен. Оформите доставку или позвоните в ресторан.",
  deferred_disabled: "Отложенные заказы временно недоступны. Оформите заказ на ближайшее время.",
  client_ref_conflict: "Эта заявка уже отправлена. Откроем её статус."
};

export function CheckoutForm({ ordersEnabled = true, pickupEnabled = true, deferredEnabled = true }: { ordersEnabled?: boolean; pickupEnabled?: boolean; deferredEnabled?: boolean }) {
  const router = useRouter();
  const { items, clear, updatePriceSnapshots, orderComment, setOrderComment } = useCart();
  const totals = useCartTotals();
  const [status, setStatus] = useState<"idle" | "loading" | "error">("idle");
  const [message, setMessage] = useState("");
  const [method, setMethod] = useState<"delivery" | "pickup">("delivery");
  const [info, setInfo] = useState<Info>(null);
  const [customerName, setCustomerName] = useState("");
  const [customerPhone, setCustomerPhone] = useState("");
  useEffect(() => { fetch("/api/info").then((response) => response.ok ? response.json() : null).then((body) => setInfo(body?.ok ? body : null)).catch(() => setInfo(null)); }, []);
  useEffect(() => {
    fetch("/api/auth/me", { cache: "no-store" }).then((response) => response.ok ? response.json() : null).then((body) => {
      if (!body?.user) return;
      setCustomerName((value) => value || body.user.name || "");
      setCustomerPhone((value) => value || (body.user.phone ? `+${body.user.phone}` : ""));
    }).catch(() => undefined);
  }, []);
  // SBIS can disable a receive type dynamically (bot /api/info); combine with local flags.
  const deliveryAllowed = info?.delivery?.enabled !== false;
  const pickupAllowed = pickupEnabled && info?.pickup?.enabled !== false;
  useEffect(() => {
    if (method === "pickup" && !pickupAllowed) setMethod("delivery");
    if (method === "delivery" && !deliveryAllowed && pickupAllowed) setMethod("pickup");
  }, [method, pickupAllowed, deliveryAllowed]);
  if (!ordersEnabled) return <div className="card p-6"><h2 className="text-2xl">Приём заказов временно отключён</h2><p className="mt-3 muted">Мы скоро включим онлайн-заказ. Пока можно позвонить в ресторан или забронировать стол.</p></div>;

  async function submit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    if (status === "loading") return;
    setStatus("loading");
    reachGoal("begin_checkout");
    const form = new FormData(event.currentTarget);
    const clientRefKey = "kiln-order-client-ref-v1";
    const clientRef = sessionStorage.getItem(clientRefKey) || crypto.randomUUID();
    sessionStorage.setItem(clientRefKey, clientRef);
    const payload = {
      clientRef,
      name: String(form.get("name") || ""),
      phone: String(form.get("phone") || ""),
      email: String(form.get("email") || ""),
      method,
      address: String(form.get("address") || ""),
      apartment: String(form.get("apartment") || ""),
      floor: String(form.get("floor") || ""),
      intercom: String(form.get("intercom") || ""),
      courierComment: String(form.get("courierComment") || ""),
      orderComment,
      desiredTime: String(form.get("desiredTime") || ""),
      offerConsent: form.get("offerConsent") === "on",
      personalDataConsent: form.get("personalDataConsent") === "on",
      marketingConsent: form.get("marketingConsent") === "on",
      items
    };
    const response = await fetch("/api/order", { method: "POST", body: JSON.stringify(payload) });
    const data = (await response.json()) as { paymentUrl?: string | null; trackUrl?: string; clientRef?: string; orderId?: string; status?: string; message?: string; error?: string; items_actual?: { sbis_id: string; price: number; available?: boolean }[] };
    if (response.ok) { if (!["pending_confirmation", "processing"].includes(data.status || "")) { clear(); sessionStorage.removeItem(clientRefKey); } router.push(`/order/${encodeURIComponent(data.clientRef || clientRef)}`); }
    else {
      setStatus("error");
      if (data.error === "price_mismatch" && data.items_actual?.length) {
        updatePriceSnapshots(data.items_actual);
        setMessage("Цена или наличие изменились. Данные корзины обновлены — проверьте состав и подтвердите заказ ещё раз.");
      } else if (data.error === "client_ref_conflict") {
        setMessage(CHECKOUT_ERRORS.client_ref_conflict);
        setTimeout(() => router.push(`/order/${encodeURIComponent(clientRef)}`), 1200);
      } else setMessage(data.message || CHECKOUT_ERRORS[data.error || ""] || "Заказ не создан. Проверьте данные и доступность позиций.");
    }
  }

  return (
    <form className="grid gap-6 lg:grid-cols-[1fr_360px]" onSubmit={submit}>
      <div className="card grid gap-4 p-5">
        <div className="rounded-md border border-kiln-flame/30 bg-kiln-flame/10 p-3 text-sm text-kiln-milk">Заказ создаётся в кассе ресторана. Ссылка на оплату появится после подтверждения заказа.</div>
        <h2 className="text-2xl">1. Контактные данные</h2>
        <div className="grid gap-4 sm:grid-cols-2">
          <label><span className="mb-1 block text-sm">Имя</span><input className="input" name="name" required minLength={2} value={customerName} onChange={(event) => setCustomerName(event.target.value)} /></label>
          <label><span className="mb-1 block text-sm">Телефон</span><input className="input" name="phone" type="tel" required inputMode="tel" pattern={"^[0-9+()\\-\\s]{10,32}$"} placeholder="+7 (___) ___-__-__" value={customerPhone} onChange={(event) => setCustomerPhone(event.target.value)} /></label>
        </div>
        <label><span className="mb-1 block text-sm">Email для чека (необязательно)</span><input className="input" name="email" type="email" /></label>
        <h2 className="pt-2 text-2xl">2. Способ получения</h2>
        <div className="grid gap-2 sm:grid-cols-2">
          <label className={`button button-secondary ${deliveryAllowed ? "cursor-pointer" : "cursor-not-allowed opacity-50"}`}><input type="radio" name="method" disabled={!deliveryAllowed} checked={method === "delivery"} onChange={() => deliveryAllowed && setMethod("delivery")} /> Доставка{deliveryAllowed ? "" : " — недоступна"}</label>
          <label className={`button button-secondary ${pickupAllowed ? "cursor-pointer" : "cursor-not-allowed opacity-50"}`}><input type="radio" name="method" disabled={!pickupAllowed} checked={method === "pickup"} onChange={() => pickupAllowed && setMethod("pickup")} /> Самовывоз{pickupAllowed ? "" : " — недоступен"}</label>
        </div>
        {info?.hours?.orders?.start && info?.hours?.orders?.end ? <p className="text-sm text-kiln-milk/60">Приём заказов: {info.hours.orders.start}–{info.hours.orders.end}{info.hours.orders.note ? ` · ${info.hours.orders.note}` : ""}.</p> : null}
        {method === "delivery" && info?.zones?.length ? <p className="text-sm text-kiln-milk/60">Зоны доставки: {info.zones.map((zone) => `${zone.name} — от ${zone.min_order} ₽`).join(" · ")}.</p> : null}
        {method === "delivery" ? (
          <>
          <label><span className="mb-1 block text-sm">Адрес</span><input className="input" name="address" required={method === "delivery"} /></label>
            <div className="grid gap-4 sm:grid-cols-3">
              <input className="input" name="apartment" placeholder="Квартира" />
              <input className="input" name="floor" placeholder="Этаж" />
              <input className="input" name="intercom" placeholder="Домофон" />
            </div>
          <label><span className="mb-1 block text-sm">Комментарий курьеру</span><textarea className="input min-h-24" name="courierComment" /></label>
          </>
        ) : null}
        <h2 className="pt-2 text-2xl">3. Время и комментарий</h2>
        <label><span className="mb-1 block text-sm">Комментарий</span><textarea className="input min-h-24" name="orderComment" maxLength={160} value={orderComment} onChange={(event) => setOrderComment(event.target.value)} /><span className="mt-1 block text-right text-xs muted">{orderComment.length}/160</span></label>
        {deferredEnabled ? <label><span className="mb-1 block text-sm">Желаемое время (необязательно)</span><input className="input" name="desiredTime" type="datetime-local" /></label> : null}
        <label className="flex items-start gap-3 text-sm"><input className="mt-1 h-4 w-4" type="checkbox" name="offerConsent" required /> <span>Согласен с публичной офертой.</span></label>
        <label className="flex items-start gap-3 text-sm"><input className="mt-1 h-4 w-4" type="checkbox" name="personalDataConsent" required /> <span>Согласен на обработку персональных данных.</span></label>
        <label className="flex items-start gap-3 text-sm"><input className="mt-1 h-4 w-4" type="checkbox" name="marketingConsent" /> <span>Хочу получать новости и предложения КИЛН.</span></label>
      </div>
      <aside className="card h-fit p-5">
        <h2 className="text-2xl">4. Состав и оплата</h2>
        <div className="mt-4 grid gap-2 text-sm">
          {totals.lines.map((line) => line ? <div key={line.dish.id} className="flex justify-between gap-3"><span>{line.quantity} × {line.dish.name}</span><strong>{line.lineTotal} ₽</strong></div> : null)}
        </div>
        <div className="mt-4 grid gap-2 text-sm">
          <div className="flex justify-between"><span>Блюда</span><strong>{totals.subtotal} ₽</strong></div>
          <div className="flex justify-between"><span>Доставка</span><strong>{totals.delivery} ₽</strong></div>
          <div className="flex justify-between border-t border-white/10 pt-3 text-lg"><span>Итого</span><strong>{totals.total} ₽</strong></div>
        </div>
        <p className="mt-4 text-sm text-kiln-milk/64">Сервер повторно проверит цены, доступность блюд, часы работы и доставку.</p>
        <button className="button button-primary mt-5 w-full" disabled={status === "loading" || !items.length}>
          {status === "loading" ? "Переходим к оплате..." : "Перейти к оплате"}
        </button>
        {status === "error" ? <p className="mt-3 text-sm text-kiln-flame">{message}</p> : null}
      </aside>
    </form>
  );
}
