"use client";

import Image from "next/image";
import Link from "next/link";
import { useEffect, useMemo, useState, useTransition } from "react";
import { usePathname, useRouter, useSearchParams } from "next/navigation";
import {
  applyPromoCodeAction,
  removeLineItemAction,
  removePromoCodeAction,
  updateLineItemAction,
} from "@/app/actions/cart";
import { getEffectiveCartTotal, getEffectiveShippingTotal, hasFreeShipping } from "@/lib/utils/cart-pricing";
import { formatEuro } from "@/lib/utils/money";
import { useSiteText } from "@/components/providers/site-text-provider";
import {
  isCustomizationHexColorValue,
  isCustomizationImageValue,
  normalizeCustomizationHexColor,
  type CartCustomizationValue,
} from "@/lib/personalization";

type CartDrawerItem = {
  id: string;
  productTitle: string;
  variantTitle?: string | null;
  imageUrl?: string | null;
  quantity: number;
  total?: number | null;
  theme?: string | null;
  paperFinish?: string | null;
  eventDate?: string | null;
  personalization?: string | null;
  customizations?: CartCustomizationValue[];
};

export type CartDrawerTriggerProps = {
  itemCount: number;
  subtotal?: number | null;
  shippingTotal?: number | null;
  discountTotal?: number | null;
  total?: number | null;
  items: CartDrawerItem[];
  promoCodes: string[];
  defaultOpen?: boolean;
  onOpenFromUrl?: () => void;
};

export function CartDrawerTrigger({
  itemCount,
  subtotal,
  shippingTotal,
  discountTotal,
  total,
  items,
  promoCodes,
  defaultOpen = false,
  onOpenFromUrl,
}: CartDrawerTriggerProps) {
  const { t } = useSiteText();
  const pathname = usePathname();
  const router = useRouter();
  const searchParams = useSearchParams();
  const shouldOpenFromUrl = searchParams.get("openCart") === "1";
  const shouldStartOpen = shouldOpenFromUrl || defaultOpen;
  const [open, setOpen] = useState(shouldStartOpen);
  const [renderDrawer, setRenderDrawer] = useState(shouldStartOpen);
  const [isPending, startTransition] = useTransition();
  const [promoCodeInput, setPromoCodeInput] = useState("");
  const [promoMessage, setPromoMessage] = useState<string | null>(null);

  useEffect(() => {
    if (!shouldOpenFromUrl) {
      return;
    }
    window.setTimeout(() => {
      setRenderDrawer(true);
      setOpen(true);
    }, 0);
    onOpenFromUrl?.();
    const next = new URLSearchParams(searchParams.toString());
    next.delete("openCart");
    const queryString = next.toString();
    router.replace(queryString ? `${pathname}?${queryString}` : pathname, { scroll: false });
  }, [onOpenFromUrl, pathname, router, searchParams, shouldOpenFromUrl]);

  useEffect(() => {
    if (!open) {
      document.body.style.overflow = "";
      return;
    }

    document.body.style.overflow = "hidden";
    return () => {
      document.body.style.overflow = "";
    };
  }, [open]);

  const cartLabel = useMemo(
    () => `${t("cart.button")}, ${itemCount} article${itemCount > 1 ? "s" : ""}`,
    [itemCount, t],
  );
  const freeShipping = hasFreeShipping(subtotal);
  const effectiveShippingTotal = getEffectiveShippingTotal({ subtotal, shippingTotal });
  const effectiveTotal = getEffectiveCartTotal({ subtotal, shippingTotal, total });
  const openDrawer = () => {
    setRenderDrawer(true);
    setOpen(true);
  };
  const closeDrawer = () => setOpen(false);
  const updateQuantity = (lineId: string, quantity: number) => {
    const nextQuantity = Math.max(1, quantity);
    const formData = new FormData();
    formData.set("lineId", lineId);
    formData.set("quantity", String(nextQuantity));

    startTransition(async () => {
      await updateLineItemAction(formData);
      router.refresh();
    });
  };
  const removeItem = (lineId: string) => {
    const formData = new FormData();
    formData.set("lineId", lineId);

    startTransition(async () => {
      await removeLineItemAction(formData);
      router.refresh();
    });
  };
  const applyPromo = () => {
    const formData = new FormData();
    formData.set("code", promoCodeInput);

    startTransition(async () => {
      const result = await applyPromoCodeAction(formData);
      setPromoMessage(result.message);
      if (result.ok) {
        setPromoCodeInput("");
      }
      router.refresh();
    });
  };
  const removePromo = (code: string) => {
    const formData = new FormData();
    formData.set("code", code);

    startTransition(async () => {
      const result = await removePromoCodeAction(formData);
      setPromoMessage(result.message);
      router.refresh();
    });
  };

  return (
    <>
      <button
        type="button"
        aria-label={cartLabel}
        onClick={openDrawer}
        className="group relative inline-flex items-center gap-2 rounded-full bg-[var(--accent-3)] px-4 py-2 text-white transition-all duration-200 hover:-translate-y-[1px] hover:bg-[var(--accent-2)] focus:outline-none focus:ring-2 focus:ring-[var(--accent)] focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50"
      >
        <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="1.8" className="h-4 w-4 text-white">
          <path strokeLinecap="round" strokeLinejoin="round" d="M3 4h2l2.2 10.2a2 2 0 0 0 2 1.6h8.8a2 2 0 0 0 2-1.7L23 7H7.2" />
          <circle cx="10" cy="20" r="1.5" />
          <circle cx="18" cy="20" r="1.5" />
        </svg>
        <span className="hidden text-white sm:inline">{t("cart.button")}</span>
        <span className="ml-0.5 inline-flex min-w-5 items-center justify-center rounded-full bg-[var(--accent-soft)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--accent-3)]">
          {itemCount}
        </span>
      </button>

      {renderDrawer ? (
        <div className={`fixed inset-0 z-[70] transition ${open ? "pointer-events-auto" : "pointer-events-none"}`} aria-hidden={!open}>
          <button
            type="button"
            onClick={closeDrawer}
            className={`absolute inset-0 bg-transparent transition-opacity duration-300 ${open ? "opacity-100" : "opacity-0"}`}
            aria-label={t("cart.aria.close")}
          />
          <aside
            onTransitionEnd={() => {
              if (!open) {
                setRenderDrawer(false);
              }
            }}
            className={`absolute right-0 top-0 flex h-dvh w-full max-w-[440px] flex-col border-l border-[var(--line)] bg-[var(--surface)] shadow-[-18px_0_40px_rgba(49,18,18,0.2)] transition-transform duration-300 ease-out ${open ? "translate-x-0" : "translate-x-full"}`}
          >
            <div className="flex items-center justify-between border-b border-[var(--line)] bg-white px-5 py-4">
              <div>
                <h2 className="font-serif text-2xl text-[var(--foreground)]">{t("cart.title")}</h2>
                <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[var(--muted)]">
                  {itemCount} article{itemCount > 1 ? "s" : ""}
                </p>
              </div>
              <button
                type="button"
                onClick={closeDrawer}
                className="inline-flex h-9 w-9 items-center justify-center rounded-full border border-[var(--line)] text-sm text-[var(--muted)] hover:text-[var(--foreground)]"
                aria-label={t("cart.aria.close")}
              >
                <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" className="h-4 w-4">
                  <path strokeLinecap="round" strokeLinejoin="round" d="M6 6l12 12M18 6 6 18" />
                </svg>
              </button>
            </div>

            <div className="flex min-h-0 flex-1 flex-col">
              <div className="min-h-0 flex-1 space-y-3 overflow-y-auto px-5 py-5">
                {items.length === 0 ? (
                  <div className="rounded-2xl border border-[var(--line)] bg-white p-5 text-center">
                    <p className="text-sm text-[var(--muted)]">{t("cart.empty")}</p>
                    <button
                      type="button"
                      onClick={closeDrawer}
                      className="mt-3 rounded-xl border border-[var(--line)] px-4 py-2 text-sm font-semibold text-[var(--foreground)]"
                    >
                      {t("cart.continue")}
                    </button>
                  </div>
                ) : (
                  items.map((item) => (
                    <article key={item.id} className="rounded-2xl border border-[var(--line)] bg-white p-4 shadow-[0_8px_20px_rgba(49,18,18,0.06)]">
                      <div className="flex items-start gap-3">
                        <div className="relative h-14 w-14 shrink-0 overflow-hidden rounded-xl border border-[var(--line)] bg-[var(--surface-2)]">
                          {item.imageUrl ? (
                            <Image src={item.imageUrl} alt={item.productTitle} fill sizes="56px" className="object-cover" loading="lazy" />
                          ) : (
                            <div className="h-full w-full bg-gradient-to-br from-[#ffe2e2] to-[#ffd3d3]" />
                          )}
                        </div>

                        <div className="min-w-0 flex-1">
                          <p className="line-clamp-2 font-semibold text-[var(--foreground)]">{item.productTitle}</p>
                          {item.variantTitle ? <p className="mt-1 text-sm text-[var(--muted)]">{item.variantTitle}</p> : null}
                          {item.theme ? <p className="mt-2 text-xs text-[var(--muted)]">Theme: {item.theme}</p> : null}
                          {item.paperFinish ? <p className="mt-1 text-xs text-[var(--muted)]">Effet du papier: {item.paperFinish}</p> : null}
                          {item.eventDate ? <p className="mt-1 text-xs text-[var(--muted)]">Date de l&apos;evenement: {item.eventDate}</p> : null}
                          {item.customizations?.map((entry) =>
                            isCustomizationImageValue(entry.value) ? (
                              <div key={`${item.id}-${entry.key}`} className="mt-2 space-y-1 text-xs text-[var(--muted)]">
                                <p>{entry.label}</p>
                                <div className="relative h-16 w-16 overflow-hidden rounded-lg border border-[var(--line)]">
                                  <Image src={entry.value} alt={entry.label} fill sizes="64px" className="object-cover" loading="lazy" />
                                </div>
                              </div>
                            ) : isCustomizationHexColorValue(entry.value) ? (
                              <div key={`${item.id}-${entry.key}`} className="mt-1 flex items-center gap-2 text-xs text-[var(--muted)]">
                                <span>{entry.label}:</span>
                                <span
                                  className="inline-block h-3.5 w-3.5 rounded-sm border border-black/10 shadow-sm"
                                  style={{ backgroundColor: normalizeCustomizationHexColor(entry.value) || entry.value }}
                                  aria-label={`${entry.label}: ${entry.value}`}
                                  title={entry.value}
                                />
                              </div>
                            ) : (
                              <p key={`${item.id}-${entry.key}`} className="mt-1 text-xs text-[var(--muted)]">
                                {entry.label}: {entry.value}
                              </p>
                            ),
                          )}
                          {item.personalization ? (
                            <p className="mt-2 text-xs text-[var(--muted)]">{t("cart.personalization")}: {item.personalization}</p>
                          ) : null}
                        </div>
                      </div>

                      <div className="mt-3 flex items-center justify-between text-sm">
                        <div className="inline-flex items-center rounded-full border border-[var(--line)] bg-[var(--surface-2)]">
                          <button
                            type="button"
                            onClick={() => updateQuantity(item.id, item.quantity - 1)}
                            disabled={isPending || item.quantity <= 1}
                            className="px-2.5 py-1 text-[var(--foreground)] disabled:cursor-not-allowed disabled:opacity-40"
                            aria-label={t("cart.qty.decrease")}
                          >
                            -
                          </button>
                          <span className="min-w-8 px-2 py-1 text-center text-[var(--muted)]">{item.quantity}</span>
                          <button
                            type="button"
                            onClick={() => updateQuantity(item.id, item.quantity + 1)}
                            disabled={isPending}
                            className="px-2.5 py-1 text-[var(--foreground)] disabled:cursor-not-allowed disabled:opacity-40"
                            aria-label={t("cart.qty.increase")}
                          >
                            +
                          </button>
                        </div>
                        <span className="font-semibold text-[var(--accent-3)]">{formatEuro(item.total)}</span>
                      </div>
                      <div className="mt-2 flex justify-end">
                        <button
                          type="button"
                          onClick={() => removeItem(item.id)}
                          disabled={isPending}
                          className="text-xs font-semibold text-[var(--accent)] underline-offset-2 hover:underline disabled:cursor-not-allowed disabled:opacity-40"
                        >
                          {t("cart.remove")}
                        </button>
                      </div>
                    </article>
                  ))
                )}
              </div>

              <div className="shrink-0 border-t border-[var(--line)] bg-white px-5 pb-5 pt-4">
                <div className="mb-4 space-y-2">
                  <p className="text-xs font-semibold uppercase tracking-[0.12em] text-[var(--muted)]">{t("cart.promo")}</p>
                  <div className="flex items-center gap-2">
                    <input
                      type="text"
                      value={promoCodeInput}
                      onChange={(event) => setPromoCodeInput(event.target.value)}
                      placeholder={t("cart.promo.placeholder")}
                      className="h-10 w-full rounded-xl border border-[var(--line)] px-3 text-sm outline-none focus:border-[#f5505080]"
                    />
                    <button
                      type="button"
                      onClick={applyPromo}
                      disabled={isPending || promoCodeInput.trim().length === 0}
                      className="h-10 shrink-0 rounded-xl border border-[var(--line)] px-3 text-sm font-semibold text-[var(--foreground)] disabled:cursor-not-allowed disabled:opacity-40"
                    >
                      {t("cart.promo.apply")}
                    </button>
                  </div>
                  {promoCodes.length > 0 ? (
                    <div className="flex flex-wrap gap-2">
                      {promoCodes.map((code) => (
                        <button
                          key={code}
                          type="button"
                          onClick={() => removePromo(code)}
                          disabled={isPending}
                          className="inline-flex items-center gap-1 rounded-full border border-[#ffd0d0] bg-[#fff3f3] px-2.5 py-1 text-xs font-semibold text-[var(--accent-3)] disabled:cursor-not-allowed disabled:opacity-40"
                          aria-label={`${t("cart.promo.removePrefix")} ${code}`}
                        >
                          <span>{code}</span>
                          <span aria-hidden>x</span>
                        </button>
                      ))}
                    </div>
                  ) : null}
                  {promoMessage ? <p className="text-xs text-[var(--muted)]">{promoMessage}</p> : null}
                </div>

                <p className="flex items-center justify-between text-[15px] text-[var(--foreground)]">
                  <span className="font-medium">{t("cart.subtotal")}</span>
                  <span className="font-semibold">{formatEuro(subtotal)}</span>
                </p>
                <p className="mt-1 flex items-center justify-between text-sm text-[var(--muted)]">
                  <span>{t("cart.shipping")}</span>
                  <span className="font-semibold">{freeShipping ? t("cart.shipping.free") : formatEuro(effectiveShippingTotal)}</span>
                </p>
                {typeof discountTotal === "number" && discountTotal > 0 ? (
                  <p className="mt-1 flex items-center justify-between text-sm text-[var(--muted)]">
                    <span>{t("cart.discount")}</span>
                    <span className="font-semibold text-[var(--accent)]">-{formatEuro(discountTotal)}</span>
                  </p>
                ) : null}
                <p className="mb-4 mt-2 flex items-center justify-between border-t border-[var(--line)] pt-3 text-[15px] text-[var(--foreground)]">
                  <span className="font-medium">{t("cart.total")}</span>
                  <span className="font-semibold">{formatEuro(effectiveTotal)}</span>
                </p>
                <div className="space-y-2">
                  <Link
                    href="/panier"
                    onClick={closeDrawer}
                    className="inline-flex w-full items-center justify-center rounded-xl bg-[var(--accent)] px-4 py-3 text-sm font-semibold text-white hover:bg-[var(--accent-2)]"
                  >
                    {t("cart.viewFull")}
                  </Link>
                  <button
                    type="button"
                    onClick={closeDrawer}
                    className="inline-flex w-full items-center justify-center rounded-xl border border-[var(--line)] px-4 py-3 text-sm font-semibold text-[var(--foreground)]"
                  >
                    {t("cart.continue")}
                  </button>
                </div>
              </div>
            </div>
          </aside>
        </div>
      ) : null}
    </>
  );
}
