"use client";

import Link from "next/link";
import { useEffect, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import { toast } from "sonner";
import Navbar from "@/components/Navbar";
import Footer from "@/components/Footer";
import { useAuth } from "@/context/AuthContext";
import { useCart } from "@/context/CartContext";
import {
  api,
  ApiError,
  type CheckoutPayload,
  type CheckoutPreviewResponse,
} from "@/lib/api";

const DEFAULT_SHIPPING_COST = 3000;
const SHIPPING_METHOD = {
  name: "Shipping charges",
  description: "Tracking number provided.",
  cost: DEFAULT_SHIPPING_COST,
};

const formatPkr = (amount: number) =>
  `Rs ${amount.toLocaleString("en-PK", { minimumFractionDigits: 2, maximumFractionDigits: 2 })}`;

type FormState = {
  email: string;
  marketing_consent: boolean;
  country: string;
  first_name: string;
  last_name: string;
  address: string;
  apartment: string;
  city: string;
  postal_code: string;
  phone: string;
  save_information: boolean;
  payment_method: "cod" | "card";
  same_as_shipping: boolean;
  billing_first_name: string;
  billing_last_name: string;
  billing_address: string;
  billing_apartment: string;
  billing_city: string;
  billing_postal_code: string;
  billing_phone: string;
  billing_country: string;
  notes: string;
};

export default function CheckoutPage() {
  const router = useRouter();
  const { items, clearCart } = useCart();
  const { user, token } = useAuth();
  const [submitting, setSubmitting] = useState(false);
  const [error, setError] = useState("");
  const [preview, setPreview] = useState<CheckoutPreviewResponse | null>(null);

  const [form, setForm] = useState<FormState>({
    email: user?.email || "",
    marketing_consent: true,
    country: "Pakistan",
    first_name: user?.first_name || "",
    last_name: user?.last_name || "",
    address: "",
    apartment: "",
    city: "",
    postal_code: "",
    phone: user?.phone || "",
    save_information: false,
    payment_method: "cod",
    same_as_shipping: true,
    billing_first_name: "",
    billing_last_name: "",
    billing_address: "",
    billing_apartment: "",
    billing_city: "",
    billing_postal_code: "",
    billing_phone: "",
    billing_country: "Pakistan",
    notes: "",
  });

  useEffect(() => {
    if (!items.length) router.replace("/cart");
  }, [items.length, router]);

  useEffect(() => {
    if (user?.email) {
      setForm((prev) => ({
        ...prev,
        email: prev.email || user.email,
        first_name: prev.first_name || user.first_name || "",
        last_name: prev.last_name || user.last_name || "",
        phone: prev.phone || user.phone || "",
      }));
    }
  }, [user]);

  const localSubtotal = useMemo(
    () => items.reduce((sum, item) => sum + item.product.price * item.quantity, 0),
    [items],
  );
  const shippingCost = preview?.summary.shipping ?? DEFAULT_SHIPPING_COST;
  const subtotal = preview?.summary.subtotal ?? localSubtotal;
  const total = preview?.summary.total ?? localSubtotal + DEFAULT_SHIPPING_COST;

  const setField = <K extends keyof FormState>(key: K, value: FormState[K]) => {
    setForm((prev) => ({ ...prev, [key]: value }));
  };

  const buildPayload = (): CheckoutPayload => {
    const shipping_address = {
      country: form.country,
      first_name: form.first_name.trim(),
      last_name: form.last_name.trim(),
      address: form.address.trim(),
      apartment: form.apartment.trim() || undefined,
      city: form.city.trim(),
      postal_code: form.postal_code.trim() || undefined,
      phone: form.phone.trim(),
    };

    const billing_address = form.same_as_shipping
      ? null
      : {
          country: form.billing_country,
          first_name: form.billing_first_name.trim(),
          last_name: form.billing_last_name.trim(),
          address: form.billing_address.trim(),
          apartment: form.billing_apartment.trim() || undefined,
          city: form.billing_city.trim(),
          postal_code: form.billing_postal_code.trim() || undefined,
          phone: form.billing_phone.trim(),
        };

    return {
      email: form.email.trim(),
      marketing_consent: form.marketing_consent,
      shipping_address,
      same_as_shipping: form.same_as_shipping,
      billing_address,
      save_information: form.save_information,
      shipping_method: SHIPPING_METHOD,
      payment_method: form.payment_method,
      items: items.map((item) => ({
        product_id: Number(item.product.id),
        variant_id: item.variantId ?? null,
        quantity: item.quantity,
      })),
      notes: form.notes.trim() || undefined,
    };
  };

  const onSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    if (!items.length) return;

    setSubmitting(true);
    setError("");
    const payload = buildPayload();

    try {
      const validated = await api.checkout.validate(payload, token);
      setPreview(validated);
      const order = await api.checkout.createOrder(payload, token);

      if (typeof window !== "undefined") {
        window.sessionStorage.setItem(
          "gns_glow_last_order_v1",
          JSON.stringify({
            order,
            payload,
            preview: validated,
            createdAt: new Date().toISOString(),
          }),
        );
      }

      clearCart();

      if (order.redirect_required && order.payment_method === "card") {
        toast.message(order.message || "Redirecting to card payment…");
      }

      router.push(`/checkout/success?orderId=${order.id}`);
    } catch (err) {
      const message =
        err instanceof ApiError ? err.message : "Checkout failed. Please verify details and try again.";
      setError(message);
      toast.error(message);
    } finally {
      setSubmitting(false);
    }
  };

  if (!items.length) return null;

  const inputClass =
    "w-full rounded-lg border border-border bg-background px-3.5 py-3 text-sm outline-none transition-colors focus:border-primary";

  return (
    <div className="min-h-screen bg-background">
      <Navbar />
      <div className="container mx-auto px-4 py-8 lg:px-8">
        <form onSubmit={onSubmit} className="grid gap-8 lg:grid-cols-[1.4fr_1fr]">
          <div className="space-y-8">
            {error ? (
              <div className="rounded-xl border border-destructive/30 bg-destructive/10 px-4 py-3 text-sm text-destructive">
                {error}
              </div>
            ) : null}

            {/* Contact */}
            <section>
              <div className="mb-3 flex items-center justify-between">
                <h2 className="text-lg font-bold">Contact</h2>
                {!user ? (
                  <Link href="/login" className="text-sm text-primary hover:underline">
                    Sign in
                  </Link>
                ) : null}
              </div>
              <input
                required
                type="email"
                placeholder="Email"
                value={form.email}
                onChange={(e) => setField("email", e.target.value)}
                className={inputClass}
              />
              <label className="mt-3 flex items-center gap-2 text-sm text-muted-foreground">
                <input
                  type="checkbox"
                  checked={form.marketing_consent}
                  onChange={(e) => setField("marketing_consent", e.target.checked)}
                  className="h-4 w-4 rounded border-border accent-primary"
                />
                Email me with news and offers
              </label>
            </section>

            {/* Delivery */}
            <section>
              <h2 className="mb-3 text-lg font-bold">Delivery</h2>
              <div className="space-y-3">
                <select
                  value={form.country}
                  onChange={(e) => setField("country", e.target.value)}
                  className={inputClass}
                >
                  <option value="Pakistan">Pakistan</option>
                </select>
                <div className="grid gap-3 sm:grid-cols-2">
                  <input
                    required
                    placeholder="First name"
                    value={form.first_name}
                    onChange={(e) => setField("first_name", e.target.value)}
                    className={inputClass}
                  />
                  <input
                    required
                    placeholder="Last name"
                    value={form.last_name}
                    onChange={(e) => setField("last_name", e.target.value)}
                    className={inputClass}
                  />
                </div>
                <input
                  required
                  placeholder="Address"
                  value={form.address}
                  onChange={(e) => setField("address", e.target.value)}
                  className={inputClass}
                />
                <input
                  placeholder="Apartment, suite, etc. (optional)"
                  value={form.apartment}
                  onChange={(e) => setField("apartment", e.target.value)}
                  className={inputClass}
                />
                <div className="grid gap-3 sm:grid-cols-2">
                  <input
                    required
                    placeholder="City"
                    value={form.city}
                    onChange={(e) => setField("city", e.target.value)}
                    className={inputClass}
                  />
                  <input
                    placeholder="Postal code (optional)"
                    value={form.postal_code}
                    onChange={(e) => setField("postal_code", e.target.value)}
                    className={inputClass}
                  />
                </div>
                <input
                  required
                  placeholder="Phone"
                  value={form.phone}
                  onChange={(e) => setField("phone", e.target.value)}
                  className={inputClass}
                />
                <label className="flex items-center gap-2 text-sm text-muted-foreground">
                  <input
                    type="checkbox"
                    checked={form.save_information}
                    onChange={(e) => setField("save_information", e.target.checked)}
                    className="h-4 w-4 rounded border-border accent-primary"
                  />
                  Save this information for next time
                </label>
              </div>
            </section>

            {/* Shipping method */}
            <section>
              <h2 className="mb-3 text-lg font-bold">Shipping method</h2>
              <div className="flex items-center justify-between rounded-xl border-2 border-primary bg-primary/5 px-4 py-4">
                <div>
                  <p className="text-sm font-semibold">{SHIPPING_METHOD.name}</p>
                  <p className="text-xs text-muted-foreground">{SHIPPING_METHOD.description}</p>
                </div>
                <p className="text-sm font-bold">{formatPkr(shippingCost)}</p>
              </div>
            </section>

            {/* Payment */}
            <section>
              <h2 className="mb-1 text-lg font-bold">Payment</h2>
              <p className="mb-3 text-xs text-muted-foreground">All transactions are secure and encrypted.</p>
              <div className="overflow-hidden rounded-xl border border-border">
                <label
                  className={`flex cursor-pointer items-start gap-3 border-b border-border px-4 py-4 ${
                    form.payment_method === "card" ? "bg-primary/5" : "bg-card"
                  }`}
                >
                  <input
                    type="radio"
                    name="payment_method"
                    checked={form.payment_method === "card"}
                    onChange={() => setField("payment_method", "card")}
                    className="mt-1 accent-primary"
                  />
                  <div className="flex-1">
                    <p className="text-sm font-semibold">Debit - Credit Card</p>
                    {form.payment_method === "card" ? (
                      <p className="mt-2 rounded-lg bg-secondary px-3 py-2 text-xs text-muted-foreground">
                        You&apos;ll be redirected to Debit - Credit Card to complete your purchase.
                      </p>
                    ) : null}
                  </div>
                </label>
                <label
                  className={`flex cursor-pointer items-center gap-3 px-4 py-4 ${
                    form.payment_method === "cod" ? "bg-primary/5" : "bg-card"
                  }`}
                >
                  <input
                    type="radio"
                    name="payment_method"
                    checked={form.payment_method === "cod"}
                    onChange={() => setField("payment_method", "cod")}
                    className="accent-primary"
                  />
                  <p className="text-sm font-semibold">Cash on Delivery (COD)</p>
                </label>
              </div>
            </section>

            {/* Billing */}
            <section>
              <h2 className="mb-3 text-lg font-bold">Billing address</h2>
              <div className="overflow-hidden rounded-xl border border-border">
                <label
                  className={`flex cursor-pointer items-center gap-3 border-b border-border px-4 py-4 ${
                    form.same_as_shipping ? "bg-primary/5" : "bg-card"
                  }`}
                >
                  <input
                    type="radio"
                    name="billing"
                    checked={form.same_as_shipping}
                    onChange={() => setField("same_as_shipping", true)}
                    className="accent-primary"
                  />
                  <span className="text-sm font-semibold">Same as shipping address</span>
                </label>
                <label
                  className={`flex cursor-pointer items-center gap-3 px-4 py-4 ${
                    !form.same_as_shipping ? "bg-primary/5" : "bg-card"
                  }`}
                >
                  <input
                    type="radio"
                    name="billing"
                    checked={!form.same_as_shipping}
                    onChange={() => setField("same_as_shipping", false)}
                    className="accent-primary"
                  />
                  <span className="text-sm font-semibold">Use a different billing address</span>
                </label>
              </div>

              {!form.same_as_shipping ? (
                <div className="mt-3 space-y-3">
                  <select
                    value={form.billing_country}
                    onChange={(e) => setField("billing_country", e.target.value)}
                    className={inputClass}
                  >
                    <option value="Pakistan">Pakistan</option>
                  </select>
                  <div className="grid gap-3 sm:grid-cols-2">
                    <input
                      required
                      placeholder="First name"
                      value={form.billing_first_name}
                      onChange={(e) => setField("billing_first_name", e.target.value)}
                      className={inputClass}
                    />
                    <input
                      required
                      placeholder="Last name"
                      value={form.billing_last_name}
                      onChange={(e) => setField("billing_last_name", e.target.value)}
                      className={inputClass}
                    />
                  </div>
                  <input
                    required
                    placeholder="Address"
                    value={form.billing_address}
                    onChange={(e) => setField("billing_address", e.target.value)}
                    className={inputClass}
                  />
                  <input
                    placeholder="Apartment, suite, etc. (optional)"
                    value={form.billing_apartment}
                    onChange={(e) => setField("billing_apartment", e.target.value)}
                    className={inputClass}
                  />
                  <div className="grid gap-3 sm:grid-cols-2">
                    <input
                      required
                      placeholder="City"
                      value={form.billing_city}
                      onChange={(e) => setField("billing_city", e.target.value)}
                      className={inputClass}
                    />
                    <input
                      placeholder="Postal code (optional)"
                      value={form.billing_postal_code}
                      onChange={(e) => setField("billing_postal_code", e.target.value)}
                      className={inputClass}
                    />
                  </div>
                  <input
                    required
                    placeholder="Phone"
                    value={form.billing_phone}
                    onChange={(e) => setField("billing_phone", e.target.value)}
                    className={inputClass}
                  />
                </div>
              ) : null}
            </section>

            <section>
              <h2 className="mb-3 text-lg font-bold">Order notes (optional)</h2>
              <textarea
                rows={3}
                placeholder="Notes about your order, e.g. special delivery instructions"
                value={form.notes}
                onChange={(e) => setField("notes", e.target.value)}
                className={inputClass}
              />
            </section>

            <button
              type="submit"
              disabled={submitting}
              className="w-full rounded-xl bg-primary px-6 py-4 text-sm font-bold uppercase tracking-wide text-primary-foreground transition-all hover:opacity-90 disabled:opacity-60"
            >
              {submitting ? "Processing…" : "Pay now"}
            </button>
          </div>

          {/* Order summary */}
          <aside className="h-fit rounded-2xl border border-border bg-secondary/40 p-5 lg:sticky lg:top-28">
            <div className="space-y-4">
              {items.map((item) => {
                const image =
                  item.product.colors.find((c) => c.name === item.selectedColor)?.image ||
                  item.product.colors[0]?.image;
                return (
                  <div key={`${item.product.id}-${item.selectedColor}`} className="flex gap-3">
                    <div className="relative h-16 w-16 shrink-0 overflow-hidden rounded-xl border border-border bg-card">
                      {image ? (
                        // eslint-disable-next-line @next/next/no-img-element
                        <img src={image} alt={item.product.name} className="h-full w-full object-cover" />
                      ) : null}
                      <span className="absolute -right-1.5 -top-1.5 flex h-5 w-5 items-center justify-center rounded-full bg-foreground text-[10px] font-bold text-primary-foreground">
                        {item.quantity}
                      </span>
                    </div>
                    <div className="min-w-0 flex-1">
                      <p className="line-clamp-2 text-sm font-medium">{item.product.name}</p>
                      <p className="mt-1 text-xs text-muted-foreground">{item.selectedColor}</p>
                    </div>
                    <p className="shrink-0 text-sm font-semibold">
                      {formatPkr(item.product.price * item.quantity)}
                    </p>
                  </div>
                );
              })}
            </div>

            <div className="mt-6 space-y-2 border-t border-border pt-4 text-sm">
              <div className="flex justify-between">
                <span className="text-muted-foreground">Subtotal</span>
                <span className="font-medium">{formatPkr(subtotal)}</span>
              </div>
              <div className="flex justify-between">
                <span className="text-muted-foreground">Shipping</span>
                <span className="font-medium">{formatPkr(shippingCost)}</span>
              </div>
              <div className="flex items-end justify-between border-t border-border pt-3">
                <span className="text-base font-bold">Total</span>
                <span className="text-right">
                  <span className="mr-2 text-xs text-muted-foreground">PKR</span>
                  <span className="text-xl font-extrabold">{formatPkr(total)}</span>
                </span>
              </div>
            </div>
          </aside>
        </form>
      </div>
      <Footer />
    </div>
  );
}
