"use client";

import { FormEvent, useMemo, useState } from "react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useCart } from "@/context/CartContext";
import { checkout, type PaymentMethod, type ShippingMethod } from "@/lib/store-api";
import { estimateShippingCents, formatCents } from "@/lib/shipping";
import { parseCodCountries } from "@/lib/api";
import type { SiteSettings } from "@/lib/types";

// Bag review is implicit here (the cart drawer already showed the items before the shopper
// clicked "Checkout"), so the flow starts on "details" per the reference — the "1 — Bag" pill
// still renders as a completed step for orientation, it's just never its own screen.
type Step = "bag" | "details" | "confirmation";

const COD_MAX_COUNTRY_LABEL = "US";

export default function CheckoutFlow({ site }: { site: SiteSettings }) {
  const { cart, loading } = useCart();
  const router = useRouter();

  const [step] = useState<Step>("details");
  const [shippingMethod, setShippingMethod] = useState<ShippingMethod>("STANDARD");
  const [paymentMethod, setPaymentMethod] = useState<PaymentMethod>("ONLINE");
  const [country, setCountry] = useState("US");
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState<string | null>(null);

  const codCountries = useMemo(() => parseCodCountries(site), [site]);
  const subtotalCents = Math.round((cart?.subtotal ?? 0) * 100);
  const codEligible = codCountries.includes(country) && subtotalCents < site.codMaxOrderCents;

  const shippingEstimateCents = estimateShippingCents(site, shippingMethod, subtotalCents);
  const codFeeCents = paymentMethod === "COD" ? site.codFeeCents : 0;
  const estimatedTotalCents = subtotalCents + shippingEstimateCents + codFeeCents;

  async function handleSubmit(e: FormEvent<HTMLFormElement>) {
    e.preventDefault();
    setSubmitting(true);
    setError(null);
    const form = new FormData(e.currentTarget);
    const firstName = String(form.get("shippingFirstName") || "");
    const lastName = String(form.get("shippingLastName") || "");
    try {
      const result = await checkout({
        customerEmail: String(form.get("customerEmail") || ""),
        shippingName: [firstName, lastName].filter(Boolean).join(" ") || undefined,
        shippingAddress: String(form.get("shippingAddress") || "") || undefined,
        shippingCity: String(form.get("shippingCity") || "") || undefined,
        shippingState: String(form.get("shippingState") || "") || undefined,
        shippingPostalCode: String(form.get("shippingPostalCode") || "") || undefined,
        shippingCountry: country,
        shippingMethod,
        paymentMethod
      });

      if (result.paymentMethod === "COD") {
        router.push(`/checkout/confirmed?order=${encodeURIComponent(result.orderNo)}`);
        return;
      }
      window.location.href = result.checkoutUrl;
    } catch (err) {
      setError(err instanceof Error ? err.message : "Checkout failed. Please try again.");
      setSubmitting(false);
    }
  }

  if (loading) {
    return <p className="text-center text-sm text-[#6f7885]">Loading…</p>;
  }

  if (!cart || cart.items.length === 0) {
    return (
      <div className="text-center py-16">
        <p className="text-[#515a68]">Your bag is empty.</p>
        <div className="mt-6">
          <Link
            href="/shop"
            className="inline-flex items-center justify-center bg-[#b08968] hover:bg-[#8f6d51] text-white text-xs font-bold uppercase tracking-wide px-6 py-3 transition-colors"
          >
            Shop allBETs Go
          </Link>
        </div>
      </div>
    );
  }

  return (
    <div className="grid grid-cols-1 lg:grid-cols-[1fr_360px] gap-12 py-10">
      <div>
        <StepPill step={step} />
        <h1 className="mt-6 font-black uppercase text-3xl text-[#1d2739]">Checkout</h1>

        <form onSubmit={handleSubmit} className="mt-8 flex flex-col gap-6">
          <div className="flex flex-col gap-3">
            <Field label="Email" name="customerEmail" type="email" placeholder="you@allbetsgo.com" required />
            <div className="grid grid-cols-2 gap-3">
              <Field label="First name" name="shippingFirstName" required />
              <Field label="Last name" name="shippingLastName" required />
            </div>
            <Field label="Address" name="shippingAddress" required />
            <div className="grid grid-cols-3 gap-3">
              <Field label="City" name="shippingCity" required />
              <Field label="Postcode" name="shippingPostalCode" required />
              <div>
                <label className="block text-[10px] font-bold uppercase tracking-[0.1em] text-[#6f7885] mb-1.5">Country</label>
                <select
                  value={country}
                  onChange={(e) => setCountry(e.target.value)}
                  className="w-full bg-[#f5f6f8] px-4 py-3 text-sm text-[#1d2739] focus:outline-none focus:ring-1 focus:ring-[#b08968]"
                >
                  <option value="US">United States</option>
                  <option value="CA">Canada</option>
                  <option value="OTHER">Other</option>
                </select>
              </div>
            </div>
          </div>

          <div>
            <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739] mb-3">Delivery</p>
            <div className="flex flex-col gap-2">
              <OptionCard
                selected={shippingMethod === "STANDARD"}
                onClick={() => setShippingMethod("STANDARD")}
                label="Standard"
                detail="2–4 working days"
                price={formatCents(estimateShippingCents(site, "STANDARD", subtotalCents))}
              />
              <OptionCard
                selected={shippingMethod === "EXPRESS"}
                onClick={() => setShippingMethod("EXPRESS")}
                label="Express"
                detail="Next working day"
                price={formatCents(estimateShippingCents(site, "EXPRESS", subtotalCents))}
              />
            </div>
          </div>

          <div>
            <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739] mb-3">Payment</p>
            <div className="flex flex-col gap-2">
              <OptionCard
                selected={paymentMethod === "ONLINE"}
                onClick={() => setPaymentMethod("ONLINE")}
                label="Pay Online"
                detail="Card, Apple Pay, PayPal, iDEAL or Klarna"
                price="Charged at dispatch"
              />
              {paymentMethod === "ONLINE" ? (
                <div className="grid grid-cols-2 gap-3 pl-4 sm:pl-6">
                  <div className="col-span-2">
                    <Field label="Card number" name="cardNumber" placeholder="4242 4242 4242 4242" />
                  </div>
                  <Field label="Expiry" name="cardExpiry" placeholder="08 / 30" />
                  <Field label="CVC" name="cardCvc" placeholder="123" />
                  <div className="col-span-2">
                    <Field label="Billing postcode" name="cardPostcode" />
                  </div>
                </div>
              ) : null}
              <OptionCard
                selected={paymentMethod === "COD"}
                onClick={() => setPaymentMethod("COD")}
                label="Cash on Delivery"
                detail={`Available in the ${COD_MAX_COUNTRY_LABEL} on orders under ${formatCents(site.codMaxOrderCents)}, one delivery attempt`}
                price={`+${formatCents(site.codFeeCents)} handling`}
                disabled={!codEligible}
              />
              {paymentMethod === "COD" && !codEligible ? (
                <p className="text-xs text-red-600">
                  Cash on Delivery isn&apos;t available for this order (country or order total is out of range).
                </p>
              ) : null}
            </div>
          </div>

          {error ? <p className="text-sm text-red-600">{error}</p> : null}

          <button
            type="submit"
            disabled={submitting || (paymentMethod === "COD" && !codEligible)}
            className="w-full bg-[#b08968] hover:bg-[#8f6d51] disabled:opacity-50 disabled:cursor-not-allowed text-white text-sm font-bold uppercase tracking-wide py-4 transition-colors"
          >
            {submitting
              ? "Placing order…"
              : paymentMethod === "COD"
                ? `Place COD Order — ${formatCents(estimatedTotalCents)}`
                : `Pay ${formatCents(estimatedTotalCents)}`}
          </button>
        </form>
      </div>

      <aside className="lg:sticky lg:top-24 h-fit border-l border-[rgba(29,39,57,0.18)] pl-8">
        <p className="text-[11px] font-bold uppercase tracking-[0.15em] text-[#1d2739]">
          Your Bag ({cart.items.reduce((s, i) => s + i.quantity, 0)})
        </p>
        <ul className="mt-4 flex flex-col gap-4">
          {cart.items.map((item) => (
            <li key={item.variantId} className="flex items-start justify-between gap-3 text-sm">
              <div>
                <p className="font-bold uppercase text-[#1d2739] text-[13px] leading-tight">{item.productName}</p>
                {item.variantLabel ? (
                  <p className="text-[11px] font-semibold uppercase tracking-wide text-[#6f7885]">
                    {item.variantLabel} / Qty {item.quantity}
                  </p>
                ) : (
                  <p className="text-[11px] font-semibold uppercase tracking-wide text-[#6f7885]">Qty {item.quantity}</p>
                )}
              </div>
              <span className="shrink-0 font-bold text-[#1d2739]">${item.lineTotal.toFixed(2)}</span>
            </li>
          ))}
        </ul>

        <div className="mt-6 pt-4 border-t border-[rgba(29,39,57,0.18)] flex flex-col gap-2 text-sm text-[#515a68]">
          <div className="flex justify-between">
            <span>Subtotal</span>
            <span>${cart.subtotal.toFixed(2)}</span>
          </div>
          <div className="flex justify-between">
            <span>Delivery</span>
            <span>{formatCents(shippingEstimateCents + codFeeCents)}</span>
          </div>
        </div>
        <div className="mt-2 pt-2 border-t border-[rgba(29,39,57,0.18)] flex justify-between font-black uppercase text-[#1d2739]">
          <span>Total</span>
          <span>{formatCents(estimatedTotalCents)}</span>
        </div>
      </aside>
    </div>
  );
}

function StepPill({ step }: { step: Step }) {
  const items: { key: Step; label: string }[] = [
    { key: "bag", label: "1 — Bag" },
    { key: "details", label: "2 — Details & Payment" },
    { key: "confirmation", label: "3 — Confirmation" }
  ];
  return (
    <ol className="flex flex-wrap items-center gap-2 text-[11px] font-bold uppercase tracking-wide">
      {items.map((item, i) => {
        const active = item.key === step;
        const done = (item.key === "bag" && step !== "bag") || false;
        return (
          <li key={item.key} className="flex items-center gap-2">
            {i > 0 ? <span className="text-[#bcc3ce]">—</span> : null}
            <span
              className={
                active
                  ? "bg-[#1d2739] text-white px-3 py-1.5"
                  : done
                    ? "text-[#b08968]"
                    : "text-[#949daa]"
              }
            >
              {item.label}
            </span>
          </li>
        );
      })}
    </ol>
  );
}

function Field({
  label,
  name,
  type = "text",
  required,
  placeholder
}: {
  label: string;
  name: string;
  type?: string;
  required?: boolean;
  placeholder?: string;
}) {
  return (
    <div>
      <label className="block text-[10px] font-bold uppercase tracking-[0.1em] text-[#6f7885] mb-1.5">{label}</label>
      <input
        name={name}
        type={type}
        required={required}
        placeholder={placeholder}
        className="w-full bg-[#f5f6f8] px-4 py-3 text-sm text-[#1d2739] placeholder:text-[#bcc3ce] focus:outline-none focus:ring-1 focus:ring-[#b08968]"
      />
    </div>
  );
}

function OptionCard({
  selected,
  onClick,
  label,
  detail,
  price,
  disabled
}: {
  selected: boolean;
  onClick: () => void;
  label: string;
  detail: string;
  price: string;
  disabled?: boolean;
}) {
  return (
    <button
      type="button"
      onClick={onClick}
      disabled={disabled}
      className={`flex items-start justify-between gap-4 border px-4 py-3.5 text-left transition-colors ${
        disabled
          ? "border-[rgba(29,39,57,0.12)] opacity-50 cursor-not-allowed"
          : selected
            ? "border-[#b08968] bg-[#f7ede4]"
            : "border-[rgba(29,39,57,0.25)] hover:border-[#1d2739]"
      }`}
    >
      <span className="flex items-start gap-3">
        <span
          className={`mt-0.5 h-3.5 w-3.5 shrink-0 border ${
            selected ? "border-[#b08968] bg-[#b08968]" : "border-[rgba(29,39,57,0.35)]"
          }`}
        />
        <span>
          <span className="block text-sm font-bold text-[#1d2739]">{label}</span>
          <span className="block text-xs text-[#6f7885] mt-0.5">{detail}</span>
        </span>
      </span>
      <span className="shrink-0 text-sm font-bold text-[#1d2739]">{price}</span>
    </button>
  );
}
