"use client";

import Link from "next/link";
import { FormEvent, useEffect, useMemo, useRef, useState } from "react";
import { useCart } from "@/context/CartContext";
import { useAuth } from "@/context/AuthContext";
import { formatCop } from "@/data/products";
import { COLOMBIA_DEPARTMENTS, shippingFieldClass } from "@/lib/colombia";
import {
  addressToForm,
  createCustomerAddress,
  formatAddressLabel,
  listCustomerAddresses,
  pickDefaultAddress,
  updateCustomerAddress,
  type SavedAddress,
} from "@/lib/customer-addresses";

const FREE_SHIPPING_FROM = 200000;
const SHIPPING_FEE = 15000;

type WompiSession = {
  publicKey: string;
  currency: string;
  amountInCents: number;
  reference: string;
  integrity: string;
  redirectUrl: string;
  customerEmail: string;
  customerName: string;
  customerPhone: string;
};

type FormState = {
  name: string;
  email: string;
  phone: string;
  address: string;
  address2: string;
  city: string;
  province: string;
  notes: string;
};

function phoneDigits(raw: string) {
  const digits = raw.replace(/\D/g, "");
  if (digits.startsWith("57") && digits.length > 10) return digits.slice(2);
  return digits;
}

function redirectToWompiCheckout(
  session: WompiSession,
  shipping: {
    fullName: string;
    phone: string;
    address: string;
    city: string;
    province: string;
  }
) {
  const form = document.createElement("form");
  form.method = "GET";
  form.action = "https://checkout.wompi.co/p/";

  const phone = phoneDigits(shipping.phone);
  const fields: Record<string, string> = {
    "public-key": session.publicKey,
    currency: session.currency,
    "amount-in-cents": String(session.amountInCents),
    reference: session.reference,
    "signature:integrity": session.integrity,
    "redirect-url": session.redirectUrl,
    "customer-data:email": session.customerEmail,
    "customer-data:full-name": session.customerName || shipping.fullName,
    "customer-data:phone-number": phone,
    "customer-data:phone-number-prefix": "+57",
    "shipping-address:address-line-1": shipping.address,
    "shipping-address:city": shipping.city,
    "shipping-address:region": shipping.province,
    "shipping-address:country": "CO",
    "shipping-address:phone-number": phone,
    "shipping-address:name": shipping.fullName,
  };

  for (const [name, value] of Object.entries(fields)) {
    if (!value) continue;
    const input = document.createElement("input");
    input.type = "hidden";
    input.name = name;
    input.value = value;
    form.appendChild(input);
  }

  document.body.appendChild(form);
  form.submit();
}

function emptyForm(email = "", name = ""): FormState {
  return {
    name,
    email,
    phone: "",
    address: "",
    address2: "",
    city: "",
    province: "",
    notes: "",
  };
}

export default function CheckoutPage() {
  const {
    items,
    subtotal,
    loading: cartLoading,
    cartId,
    saveShipping,
    removeItem,
  } = useCart();
  const { customer } = useAuth();
  const [loading, setLoading] = useState(false);
  const [removingId, setRemovingId] = useState<string | null>(null);
  const [saved, setSaved] = useState(false);
  const [error, setError] = useState<string | null>(null);
  const [addresses, setAddresses] = useState<SavedAddress[]>([]);
  const [selectedId, setSelectedId] = useState<string | "new">("new");
  const [saveToAccount, setSaveToAccount] = useState(true);
  const [form, setForm] = useState<FormState>(() =>
    emptyForm(
      customer?.email || "",
      [customer?.first_name, customer?.last_name].filter(Boolean).join(" ")
    )
  );
  const [addrLoading, setAddrLoading] = useState(Boolean(customer));
  const paying = useRef(false);

  const shipping = subtotal >= FREE_SHIPPING_FROM ? 0 : SHIPPING_FEE;
  const total = subtotal + shipping;

  useEffect(() => {
    if (!customer) {
      setAddrLoading(false);
      return;
    }
    let cancelled = false;
    (async () => {
      setAddrLoading(true);
      try {
        const list = await listCustomerAddresses();
        if (cancelled) return;
        setAddresses(list);
        const preferred = pickDefaultAddress(list);
        if (preferred) {
          setSelectedId(preferred.id);
          const mapped = addressToForm(preferred);
          setForm({
            name: mapped.name,
            email: customer.email,
            phone: mapped.phone,
            address: mapped.address,
            address2: mapped.address2,
            city: mapped.city,
            province: mapped.province,
            notes: mapped.notes,
          });
          setSaveToAccount(false);
        } else {
          setSelectedId("new");
          setForm(
            emptyForm(
              customer.email,
              [customer.first_name, customer.last_name].filter(Boolean).join(" ")
            )
          );
          setSaveToAccount(true);
        }
      } catch {
        if (!cancelled) setAddresses([]);
      } finally {
        if (!cancelled) setAddrLoading(false);
      }
    })();
    return () => {
      cancelled = true;
    };
  }, [customer]);

  const summary = useMemo(
    () =>
      items.map((i) => ({
        key: i.id,
        name: i.name,
        meta: `${i.color} · Talla ${i.size}`,
        image: i.image,
        qty: i.qty,
        total: i.price * i.qty,
      })),
    [items]
  );

  const applyAddress = (addr: SavedAddress | null) => {
    if (!addr) {
      setSelectedId("new");
      setForm(
        emptyForm(
          customer?.email || form.email,
          [customer?.first_name, customer?.last_name].filter(Boolean).join(" ") ||
            form.name
        )
      );
      setSaveToAccount(true);
      return;
    }
    setSelectedId(addr.id);
    const mapped = addressToForm(addr);
    setForm({
      name: mapped.name,
      email: customer?.email || form.email,
      phone: mapped.phone,
      address: mapped.address,
      address2: mapped.address2,
      city: mapped.city,
      province: mapped.province,
      notes: mapped.notes,
    });
    setSaveToAccount(false);
  };

  if (cartLoading) {
    return (
      <div className="ot-container py-20 text-center text-ot-muted">
        Cargando checkout…
      </div>
    );
  }

  if (!items.length) {
    return (
      <div className="ot-container min-h-[60vh] flex items-center justify-center py-16">
        <div className="text-center max-w-md">
          {/* eslint-disable-next-line @next/next/no-img-element */}
          <img
            src="/brand/ot-club-seal.png"
            alt=""
            className="mx-auto h-16 w-16 object-contain mb-6"
          />
          <h1 className="font-serif text-4xl md:text-5xl">No hay productos</h1>
          <p className="mt-3 text-ot-muted text-sm">
            Agrega piezas al carrito para continuar con el envío.
          </p>
          <Link href="/shop" className="ot-btn mt-8 inline-flex">
            Volver al shop
          </Link>
        </div>
      </div>
    );
  }

  const onSubmit = async (e: FormEvent<HTMLFormElement>) => {
    e.preventDefault();
    if (paying.current) return;
    setError(null);
    setSaved(false);
    setLoading(true);
    paying.current = true;

    const fullName = form.name.trim();
    const parts = fullName.split(/\s+/);
    const firstName = parts[0] || fullName;
    const lastName = parts.slice(1).join(" ") || "OT";
    const customerEmail = form.email.trim();
    const customerPhone = form.phone.trim();
    const city = form.city.trim();
    const province = form.province.trim();
    const address = form.address.trim();
    const notes = form.notes.trim();

    let shippingSaved = false;

    try {
      if (!cartId) {
        throw new Error("No hay un carrito activo. Vuelve al carrito e intenta de nuevo.");
      }

      await saveShipping({
        email: customerEmail,
        firstName,
        lastName,
        phone: customerPhone,
        address,
        address2: form.address2.trim(),
        city,
        province,
        notes,
      });
      shippingSaved = true;
      setSaved(true);

      if (customer && saveToAccount) {
        const payload = {
          firstName,
          lastName,
          phone: customerPhone,
          address,
          address2: form.address2.trim(),
          city,
          province,
          notes,
          isDefaultShipping: true,
          addressName: "Envío",
        };
        try {
          if (selectedId !== "new") {
            await updateCustomerAddress(selectedId, payload);
          } else {
            await createCustomerAddress(payload);
          }
        } catch {
          /* no bloquear pago si falla guardar en cuenta */
        }
      }

      const res = await fetch("/api/wompi/checkout", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          cartId,
          amountCop: total,
          shippingFee: shipping,
          customerEmail,
          customerName: fullName,
          customerPhone,
        }),
      });
      const data = await res.json();
      if (!res.ok) {
        if (data.error === "wompi_not_configured") {
          setError(
            "Datos de envío guardados, pero Wompi aún no está configurado en el servidor."
          );
          return;
        }
        throw new Error(data.message || "No se pudo iniciar el pago con Wompi.");
      }

      redirectToWompiCheckout(data as WompiSession, {
        fullName,
        phone: customerPhone,
        address,
        city,
        province,
      });
    } catch (err) {
      const message =
        err instanceof Error ? err.message : "No se pudo completar el checkout.";
      setError(
        shippingSaved ? `Envío guardado, pero falló el pago: ${message}` : message
      );
    } finally {
      setLoading(false);
      paying.current = false;
    }
  };

  const setField = (key: keyof FormState, value: string) => {
    setForm((prev) => ({ ...prev, [key]: value }));
    if (selectedId !== "new") setSaveToAccount(true);
  };

  return (
    <div className="ot-container py-12 md:py-14">
      {/* Progress — misma estructura de pasos, solo visual */}
      <ol className="flex flex-wrap items-center gap-2 sm:gap-3 mb-10 text-[11px] tracking-[0.16em] uppercase">
        <li className="flex items-center gap-2 text-ot-muted">
          <span className="grid h-7 w-7 place-items-center border border-black/15 text-[10px]">
            1
          </span>
          <Link href="/cart" className="hover:text-ot-green">
            Carrito
          </Link>
        </li>
        <li className="text-ot-muted/40" aria-hidden>
          —
        </li>
        <li className="flex items-center gap-2 text-ot-green">
          <span className="grid h-7 w-7 place-items-center border border-ot-green bg-ot-green text-ot-cream text-[10px]">
            2
          </span>
          Envío
        </li>
        <li className="text-ot-muted/40" aria-hidden>
          —
        </li>
        <li className="flex items-center gap-2 text-ot-muted/50">
          <span className="grid h-7 w-7 place-items-center border border-black/10 text-[10px]">
            3
          </span>
          Pago
        </li>
      </ol>

      <div className="grid lg:grid-cols-[1.4fr_0.8fr] gap-10 items-start">
        <form onSubmit={onSubmit} className="space-y-6">
          <header className="border-b border-black/10 pb-6">
            <p className="ot-eyebrow">Paso 2</p>
            <h1 className="font-serif text-4xl md:text-5xl mt-2 leading-tight">
              Datos de envío
            </h1>
            <p className="mt-3 text-sm text-ot-muted leading-relaxed max-w-xl">
              Verifica tu dirección, modifícala o agrega una nueva. Si tienes
              cuenta, la guardamos para la próxima compra.
            </p>
          </header>

          {!customer ? (
            <div className="flex flex-wrap items-center gap-3 border-y border-black/10 py-4 text-sm">
              <span className="text-ot-ink/85">¿Ya compraste antes?</span>
              <Link
                href="/account"
                className="text-ot-green underline underline-offset-2 hover:text-ot-ink"
              >
                Inicia sesión
              </Link>
              <span className="text-ot-muted">
                para ver tus direcciones guardadas.
              </span>
            </div>
          ) : null}

          {customer && addrLoading ? (
            <p className="text-sm text-ot-muted">Cargando direcciones…</p>
          ) : null}

          {customer && !addrLoading && addresses.length > 0 ? (
            <div className="space-y-2.5">
              <p className="ot-eyebrow">Direcciones guardadas</p>
              <div className="space-y-2">
                {addresses.map((addr) => {
                  const active = selectedId === addr.id;
                  return (
                    <button
                      key={addr.id}
                      type="button"
                      onClick={() => applyAddress(addr)}
                      className={`w-full text-left border px-4 py-3.5 text-sm transition ${
                        active
                          ? "border-ot-green bg-ot-cream-dark/50 shadow-[inset_3px_0_0_0_var(--ot-green)]"
                          : "border-black/10 bg-transparent hover:border-ot-green/40 hover:bg-ot-cream-dark/30"
                      }`}
                    >
                      <span className="font-medium text-ot-ink">
                        {formatAddressLabel(addr)}
                      </span>
                      {addr.is_default_shipping ? (
                        <span className="ml-2 text-[10px] tracking-[0.12em] uppercase text-ot-gold">
                          Predeterminada
                        </span>
                      ) : null}
                      <span className="block mt-1 text-ot-muted text-[13px]">
                        {[addr.address_1, addr.city, addr.province, addr.phone]
                          .filter(Boolean)
                          .join(" · ")}
                      </span>
                    </button>
                  );
                })}
                <button
                  type="button"
                  onClick={() => applyAddress(null)}
                  className={`w-full text-left border px-4 py-3.5 text-sm transition ${
                    selectedId === "new"
                      ? "border-ot-green bg-ot-cream-dark/50"
                      : "border-dashed border-black/20 bg-transparent hover:border-ot-green/50"
                  }`}
                >
                  + Agregar nueva dirección
                </button>
              </div>
            </div>
          ) : null}

          <div className="space-y-4">
            <div>
              <label className="ot-label-condensed text-[11px] text-ot-muted">
                Nombre completo
              </label>
              <input
                name="name"
                className={`${shippingFieldClass} mt-2`}
                placeholder="Como aparece en el documento"
                value={form.name}
                onChange={(e) => setField("name", e.target.value)}
                required
              />
            </div>
            <div className="grid sm:grid-cols-2 gap-4">
              <div>
                <label className="ot-label-condensed text-[11px] text-ot-muted">
                  Email
                </label>
                <input
                  name="email"
                  className={`${shippingFieldClass} mt-2`}
                  type="email"
                  placeholder="tucorreo@ejemplo.com"
                  value={form.email}
                  onChange={(e) => setField("email", e.target.value)}
                  required
                />
              </div>
              <div>
                <label className="ot-label-condensed text-[11px] text-ot-muted">
                  Teléfono / WhatsApp
                </label>
                <input
                  name="phone"
                  className={`${shippingFieldClass} mt-2`}
                  placeholder="300 000 0000"
                  value={form.phone}
                  onChange={(e) => setField("phone", e.target.value)}
                  required
                />
              </div>
            </div>
            <div>
              <label className="ot-label-condensed text-[11px] text-ot-muted">
                Dirección
              </label>
              <input
                name="address"
                className={`${shippingFieldClass} mt-2`}
                placeholder="Calle, número, apto"
                value={form.address}
                onChange={(e) => setField("address", e.target.value)}
                required
              />
            </div>
            <div>
              <label className="ot-label-condensed text-[11px] text-ot-muted">
                Complemento{" "}
                <span className="normal-case tracking-normal">(opcional)</span>
              </label>
              <input
                name="address2"
                className={`${shippingFieldClass} mt-2`}
                placeholder="Barrio, torre, referencias"
                value={form.address2}
                onChange={(e) => setField("address2", e.target.value)}
              />
            </div>
            <div className="grid sm:grid-cols-2 gap-4">
              <div>
                <label className="ot-label-condensed text-[11px] text-ot-muted">
                  Ciudad
                </label>
                <input
                  name="city"
                  className={`${shippingFieldClass} mt-2`}
                  placeholder="Ciudad"
                  value={form.city}
                  onChange={(e) => setField("city", e.target.value)}
                  required
                />
              </div>
              <div>
                <label className="ot-label-condensed text-[11px] text-ot-muted">
                  Departamento
                </label>
                <select
                  name="province"
                  className={`${shippingFieldClass} mt-2`}
                  required
                  value={form.province}
                  onChange={(e) => setField("province", e.target.value)}
                >
                  <option value="" disabled>
                    Selecciona
                  </option>
                  {COLOMBIA_DEPARTMENTS.map((d) => (
                    <option key={d} value={d}>
                      {d}
                    </option>
                  ))}
                </select>
              </div>
            </div>
            <div>
              <label className="ot-label-condensed text-[11px] text-ot-muted">
                Notas de entrega{" "}
                <span className="normal-case tracking-normal">(opcional)</span>
              </label>
              <textarea
                name="notes"
                className={`${shippingFieldClass} mt-2 resize-y min-h-[88px]`}
                placeholder="Horario, portería, indicaciones…"
                rows={3}
                value={form.notes}
                onChange={(e) => setField("notes", e.target.value)}
              />
            </div>
          </div>

          {customer ? (
            <label className="flex items-start gap-3 text-sm text-ot-ink/90 cursor-pointer border-y border-black/10 py-4">
              <input
                type="checkbox"
                className="mt-1 accent-[var(--ot-green)]"
                checked={saveToAccount}
                onChange={(e) => setSaveToAccount(e.target.checked)}
              />
              <span>
                {selectedId === "new"
                  ? "Guardar esta dirección en mi cuenta para próximas compras (predeterminada)."
                  : "Actualizar esta dirección en mi cuenta y dejarla como predeterminada."}
              </span>
            </label>
          ) : null}

          <button className="ot-btn w-full !py-3.5" type="submit" disabled={loading}>
            {loading
              ? "Guardando envío…"
              : `Confirmar envío y pagar ${formatCop(total)}`}
          </button>
          {saved && !error ? (
            <p className="text-sm text-ot-green">
              Datos de envío guardados en el carrito.
            </p>
          ) : null}
          {error ? (
            <p className="text-sm text-red-700 border border-red-700/20 bg-red-700/[0.04] px-3 py-2">
              {error}
            </p>
          ) : null}
          <p className="text-xs text-ot-muted leading-relaxed">
            Pago seguro con Wompi (tarjeta, PSE, Nequi). Tras pagar confirmamos
            tu pedido automáticamente.
          </p>
          {customer ? (
            <p className="text-xs text-ot-muted">
              También puedes gestionar direcciones en{" "}
              <Link href="/account/addresses" className="underline underline-offset-2">
                Mi cuenta → Direcciones
              </Link>
              .
            </p>
          ) : null}
        </form>

        <aside className="bg-ot-cream-dark p-6 h-fit lg:sticky lg:top-28">
          <h2 className="font-serif text-3xl">Tu pedido</h2>
          <div className="mt-6 space-y-5">
            {summary.map((i) => (
              <div
                key={i.key}
                className="flex gap-4 border-b border-black/10 pb-5 last:border-0 last:pb-0"
              >
                {/* eslint-disable-next-line @next/next/no-img-element */}
                <img
                  src={i.image}
                  alt=""
                  className="h-20 w-16 shrink-0 object-cover object-top bg-ot-cream"
                />
                <div className="min-w-0 flex-1 text-sm">
                  <div className="flex items-start justify-between gap-2">
                    <p className="font-serif text-lg leading-snug text-ot-ink">
                      {i.name}
                    </p>
                    <button
                      type="button"
                      className="shrink-0 text-[11px] tracking-[0.12em] uppercase text-ot-muted underline underline-offset-2 hover:text-ot-ink disabled:opacity-50"
                      disabled={removingId === i.key || loading}
                      aria-label={`Quitar ${i.name}`}
                      onClick={async () => {
                        setRemovingId(i.key);
                        try {
                          await removeItem(i.key);
                        } finally {
                          setRemovingId(null);
                        }
                      }}
                    >
                      {removingId === i.key ? "…" : "Quitar"}
                    </button>
                  </div>
                  <p className="mt-1 text-xs text-ot-muted">
                    {i.meta} · ×{i.qty}
                  </p>
                  <p className="mt-2">{formatCop(i.total)}</p>
                </div>
              </div>
            ))}
          </div>
          <div className="mt-6 space-y-2.5 border-t border-black/10 pt-5 text-sm">
            <div className="flex justify-between">
              <span className="text-ot-muted">Subtotal</span>
              <span>{formatCop(subtotal)}</span>
            </div>
            <div className="flex justify-between">
              <span className="text-ot-muted">Envío</span>
              <span className={shipping === 0 ? "text-ot-green" : undefined}>
                {shipping === 0 ? "Gratis" : formatCop(shipping)}
              </span>
            </div>
            <div className="flex justify-between font-medium text-lg pt-3 border-t border-black/10">
              <span>Total</span>
              <span>{formatCop(total)}</span>
            </div>
            {shipping === 0 ? (
              <p className="text-xs text-ot-muted pt-1">
                Envío gratis por compra desde $200.000.
              </p>
            ) : (
              <p className="text-xs text-ot-muted pt-1">
                Envío gratis desde {formatCop(FREE_SHIPPING_FROM)}.
              </p>
            )}
          </div>
          <Link
            href="/cart"
            className="mt-6 inline-flex text-[11px] tracking-[0.14em] uppercase text-ot-muted hover:text-ot-green"
          >
            ← Volver al carrito
          </Link>
        </aside>
      </div>
    </div>
  );
}
