import { createFileRoute, useNavigate } from "@tanstack/react-router";
import { useEffect, useMemo, useState } from "react";
import { toast } from "sonner";

import { bdt, toBn } from "@/lib/bn";
import { cartSubtotal, clearCart, useCart } from "@/lib/cart";
import { coupons, shippingZones } from "@/lib/catalog";
import { placeOrder, saveIncompleteOrder } from "@/lib/data";
import { track } from "@/lib/pixel";

export const Route = createFileRoute("/checkout")({
  head: () => ({
    meta: [
      { title: "চেকআউট | ইকোগ্রিন বিডি" },
      {
        name: "description",
        content: "নাম, মোবাইল নম্বর ও ঠিকানা দিয়ে ক্যাশ অন ডেলিভারিতে অর্ডার সম্পন্ন করুন।",
      },
      { property: "og:title", content: "চেকআউট | ইকোগ্রিন বিডি" },
      { property: "og:description", content: "সহজ তিন ধাপে অর্ডার সম্পন্ন করুন।" },
      { property: "og:type", content: "website" },
      { name: "twitter:card", content: "summary_large_image" },
    ],
  }),
  component: CheckoutPage,
});

function CheckoutPage() {
  const items = useCart();
  const navigate = useNavigate();
  const subtotal = cartSubtotal(items);

  const [name, setName] = useState("");
  const [phone, setPhone] = useState("");
  const [address, setAddress] = useState("");
  const [zoneId, setZoneId] = useState(shippingZones[0]!.id);
  const [couponInput, setCouponInput] = useState("");
  const [coupon, setCoupon] = useState<(typeof coupons)[number] | null>(null);
  const [submitting, setSubmitting] = useState(false);

  const zone = shippingZones.find((z) => z.id === zoneId) ?? shippingZones[0]!;

  const discount = useMemo(() => {
    if (!coupon || subtotal < coupon.minSpend) return 0;
    return coupon.type === "percent"
      ? Math.round((subtotal * coupon.value) / 100)
      : coupon.value;
  }, [coupon, subtotal]);

  const total = Math.max(0, subtotal - discount) + zone.charge;

  useEffect(() => {
    if (items.length > 0) track("InitiateCheckout", { value: subtotal, currency: "BDT" });
  }, [items.length, subtotal]);

  // Records checkout drop-off so the shop can follow up.
  useEffect(() => {
    if (!name || !phone || items.length === 0) return;
    const timer = window.setTimeout(() => {
      void saveIncompleteOrder({
        name,
        phone,
        address,
        cartTotal: total,
        items: items.map((l) => ({
          productId: l.productId,
          name: l.name,
          variant: l.variant,
          price: l.price,
          qty: l.qty,
        })),
      });
    }, 4000);
    return () => window.clearTimeout(timer);
  }, [name, phone, address, total, items]);

  function applyCoupon() {
    const found = coupons.find(
      (c) => c.code.toLowerCase() === couponInput.trim().toLowerCase(),
    );
    if (!found) {
      toast.error("কুপন কোডটি সঠিক নয়।");
      return;
    }
    if (subtotal < found.minSpend) {
      toast.error(`এই কুপনের জন্য কমপক্ষে ${bdt(found.minSpend)} কিনতে হবে।`);
      return;
    }
    setCoupon(found);
    toast.success("কুপন প্রয়োগ করা হয়েছে।");
  }

  async function submit(e: React.FormEvent) {
    e.preventDefault();
    if (items.length === 0) {
      toast.error("কার্টে কোনো পণ্য নেই।");
      return;
    }
    if (name.trim().length < 3) {
      toast.error("সম্পূর্ণ নাম লিখুন।");
      return;
    }
    if (!/^01[0-9]{9}$/.test(phone.replace(/\D/g, ""))) {
      toast.error("সঠিক ১১ ডিজিটের মোবাইল নম্বর লিখুন।");
      return;
    }
    if (address.trim().length < 10) {
      toast.error("বিস্তারিত ঠিকানা লিখুন।");
      return;
    }

    setSubmitting(true);
    try {
      const order = await placeOrder({
        name: name.trim(),
        phone: phone.trim(),
        address: address.trim(),
        zoneId: zone.id,
        zoneName: zone.name,
        deliveryCharge: zone.charge,
        couponCode: coupon?.code,
        discount,
        subtotal,
        total,
        items: items.map((l) => ({
          productId: l.productId,
          name: l.name,
          variant: l.variant,
          price: l.price,
          qty: l.qty,
        })),
      });
      track("Purchase", { value: total, currency: "BDT" });
      clearCart();
      void navigate({ to: "/order/$orderId", params: { orderId: order.id } });
    } catch {
      toast.error("অর্ডার সম্পন্ন করা যায়নি, আবার চেষ্টা করুন।");
    } finally {
      setSubmitting(false);
    }
  }

  return (
    <div className="mx-auto max-w-5xl px-4 py-8">
      <h1 className="text-2xl font-bold">চেকআউট</h1>
      <p className="mt-1 text-sm text-muted-foreground">
        ক্যাশ অন ডেলিভারি — পণ্য হাতে পেয়ে টাকা পরিশোধ করুন।
      </p>

      <form onSubmit={submit} className="mt-6 grid gap-6 lg:grid-cols-[1fr_340px]">
        <div className="space-y-4 rounded-2xl border border-border bg-card p-5">
          <div>
            <label htmlFor="name" className="mb-1 block text-sm font-medium">
              আপনার নাম
            </label>
            <input
              id="name"
              value={name}
              onChange={(e) => setName(e.target.value)}
              placeholder="সম্পূর্ণ নাম"
              className="w-full rounded-xl border border-border bg-background px-4 py-3 text-sm outline-none focus:border-primary"
            />
          </div>
          <div>
            <label htmlFor="phone" className="mb-1 block text-sm font-medium">
              মোবাইল নম্বর
            </label>
            <input
              id="phone"
              inputMode="numeric"
              value={phone}
              onChange={(e) => setPhone(e.target.value)}
              placeholder="01XXXXXXXXX"
              className="w-full rounded-xl border border-border bg-background px-4 py-3 text-sm outline-none focus:border-primary"
            />
          </div>
          <div>
            <label htmlFor="address" className="mb-1 block text-sm font-medium">
              সম্পূর্ণ ঠিকানা
            </label>
            <textarea
              id="address"
              rows={3}
              value={address}
              onChange={(e) => setAddress(e.target.value)}
              placeholder="বাসা/রোড, এলাকা, থানা, জেলা"
              className="w-full rounded-xl border border-border bg-background px-4 py-3 text-sm outline-none focus:border-primary"
            />
          </div>

          <fieldset>
            <legend className="mb-2 text-sm font-medium">ডেলিভারি এরিয়া</legend>
            <div className="grid gap-3 sm:grid-cols-2">
              {shippingZones.map((z) => (
                <label
                  key={z.id}
                  className={`flex cursor-pointer items-center justify-between rounded-xl border px-4 py-3 text-sm ${
                    zoneId === z.id ? "border-primary bg-primary/5" : "border-border"
                  }`}
                >
                  <span className="flex items-center gap-2">
                    <input
                      type="radio"
                      name="zone"
                      className="accent-primary"
                      checked={zoneId === z.id}
                      onChange={() => setZoneId(z.id)}
                    />
                    {z.name}
                  </span>
                  <span className="font-semibold">{bdt(z.charge)}</span>
                </label>
              ))}
            </div>
          </fieldset>

          <div>
            <label htmlFor="coupon" className="mb-1 block text-sm font-medium">
              কুপন কোড
            </label>
            <div className="flex gap-2">
              <input
                id="coupon"
                value={couponInput}
                onChange={(e) => setCouponInput(e.target.value)}
                placeholder="যেমন ECO10"
                className="flex-1 rounded-xl border border-border bg-background px-4 py-3 text-sm outline-none focus:border-primary"
              />
              <button
                type="button"
                onClick={applyCoupon}
                className="rounded-xl border border-primary px-4 py-3 text-sm font-semibold text-primary"
              >
                প্রয়োগ করুন
              </button>
            </div>
          </div>
        </div>

        <aside className="h-fit rounded-2xl border border-border bg-card p-5">
          <h2 className="text-lg font-semibold">অর্ডার সারসংক্ষেপ</h2>
          <ul className="mt-4 space-y-3 text-sm">
            {items.map((l) => (
              <li key={`${l.productId}-${l.variant ?? ""}`} className="flex justify-between gap-3">
                <span className="text-muted-foreground">
                  {l.name}
                  {l.variant ? ` (${l.variant})` : ""} × {toBn(l.qty)}
                </span>
                <span className="font-semibold">{bdt(l.price * l.qty)}</span>
              </li>
            ))}
          </ul>
          <div className="mt-4 space-y-2 border-t border-border pt-4 text-sm">
            <p className="flex justify-between">
              <span className="text-muted-foreground">সাবটোটাল</span>
              <span>{bdt(subtotal)}</span>
            </p>
            {discount > 0 && (
              <p className="flex justify-between text-primary">
                <span>ছাড় ({coupon?.code})</span>
                <span>- {bdt(discount)}</span>
              </p>
            )}
            <p className="flex justify-between">
              <span className="text-muted-foreground">ডেলিভারি চার্জ</span>
              <span>{bdt(zone.charge)}</span>
            </p>
            <p className="flex justify-between border-t border-border pt-2 text-base font-bold">
              <span>সর্বমোট</span>
              <span className="text-primary">{bdt(total)}</span>
            </p>
          </div>
          <button
            type="submit"
            disabled={submitting}
            className="mt-5 inline-flex w-full items-center justify-center gap-2 rounded-xl bg-primary px-4 py-3 text-sm font-semibold text-primary-foreground hover:bg-primary-deep disabled:opacity-60"
          >
            <i
              className={submitting ? "fa-solid fa-spinner fa-spin" : "fa-solid fa-bag-shopping"}
              aria-hidden="true"
            />
            {submitting ? "প্রসেস হচ্ছে..." : "অর্ডার কনফার্ম করুন"}
          </button>
        </aside>
      </form>
    </div>
  );
}
