import { Link } from '@tanstack/react-router';
import { X, Plus, Minus, Trash2, ShoppingBag, ArrowRight, Loader2, Check } from 'lucide-react';
import { useCartDrawerStore } from '@/stores/cartDrawerStore';
import { useGqlCart } from '@/hooks/useGqlCart';
import { AnimatePresence, motion } from 'framer-motion';
import { useT } from '@/lib/i18n';

const FREE_SHIPPING_HINT_THRESHOLD = 150;

const CartDrawer = () => {
  const t = useT();
  const { isOpen, close } = useCartDrawerStore();
  const {
    items,
    totals,
    isReady,
    isFetching,
    updateItem,
    removeItem,
    updatePending,
    removePending,
    loadError,
    refresh,
  } = useGqlCart();

  const mutating = updatePending || removePending;

  // Free-shipping nudge. Showing the reward being filled is the cheapest way to
  // lift average order value: the shopper who is €12 away usually adds a vial
  // instead of paying for shipping.
  const freeShippingRemaining = Math.max(0, FREE_SHIPPING_HINT_THRESHOLD - totals.subtotal);
  const freeShippingReached = freeShippingRemaining === 0;
  const showFreeShippingMeter = freeShippingReached || totals.shipping > 0;
  const freeShippingPct = Math.min(100, (totals.subtotal / FREE_SHIPPING_HINT_THRESHOLD) * 100);

  return (
    <AnimatePresence>
      {isOpen && (
        <>
          <motion.div
            initial={{ opacity: 0 }}
            animate={{ opacity: 1 }}
            exit={{ opacity: 0 }}
            transition={{ duration: 0.2 }}
            onClick={close}
            className="fixed inset-0 z-[60] bg-black/50"
          />

          <motion.div
            initial={{ x: '100%' }}
            animate={{ x: 0 }}
            exit={{ x: '100%' }}
            transition={{ type: 'spring', damping: 30, stiffness: 300 }}
            className="fixed top-0 right-0 z-[61] h-full w-full max-w-md bg-background border-l border-border shadow-2xl flex flex-col"
          >
            <div className="flex items-center justify-between px-5 py-4 border-b border-border">
              <h2 className="font-bold text-lg flex items-center gap-2">
                <ShoppingBag className="w-5 h-5 text-primary" />
                {t('Winkelwagen', 'Cart')}
                {totals.itemCount > 0 && (
                  <span className="text-sm font-normal text-muted-foreground">({totals.itemCount} {totals.itemCount === 1 ? t('item', 'item') : t('items', 'items')})</span>
                )}
                {isFetching && <Loader2 className="w-3.5 h-3.5 animate-spin text-muted-foreground" />}
              </h2>
              <button
                onClick={close}
                className="p-2 rounded-md hover:bg-muted transition-colors text-muted-foreground hover:text-foreground"
              >
                <X className="w-5 h-5" />
              </button>
            </div>

            {!isReady ? (
              <div className="flex-1 flex items-center justify-center">
                <Loader2 className="w-6 h-6 animate-spin text-muted-foreground" />
              </div>
            ) : items.length === 0 ? (
              <div className="flex-1 flex flex-col items-center justify-center text-center px-8">
                <div className="w-20 h-20 rounded-full bg-muted flex items-center justify-center mb-4">
                  <ShoppingBag className="w-9 h-9 text-muted-foreground/60" aria-hidden="true" />
                </div>
                <p className="text-muted-foreground font-medium mb-1">{t('Uw winkelwagen is leeg', 'Your cart is empty')}</p>
                <p className="text-sm text-muted-foreground/70 mb-6">{t('Ontdek onze producten en voeg ze toe aan uw wagen.', 'Discover our products and add them to your cart.')}</p>
                <Link
                  to="/shop"
                  onClick={close}
                  className="inline-flex items-center gap-2 bg-primary text-primary-foreground font-semibold px-5 py-2.5 rounded-md hover:bg-primary-hover transition-colors text-sm"
                >
                  {t('Bekijk producten', 'View products')} <ArrowRight className="w-4 h-4" />
                </Link>
                {loadError && (
                  <p className="mt-5 text-xs text-muted-foreground">
                    {t('Kon je winkelwagen niet laden.', 'Could not load your cart.')}{' '}
                    <button type="button" onClick={() => refresh()} className="text-primary hover:underline">
                      {t('Opnieuw proberen', 'Try again')}
                    </button>
                  </p>
                )}
              </div>
            ) : (
              <div className="flex-1 overflow-y-auto px-5 py-4 space-y-4">
                {/*
                  `layout` makes the list glide instead of jumping: removing a
                  line collapses it and slides the rest up, so the shopper sees
                  the change they made rather than a sudden reflow.
                */}
                <AnimatePresence initial={false}>
                {items.map((item) => item.bundled ? (
                  <motion.div
                    key={item.key}
                    layout
                    exit={{ opacity: 0, x: 24 }}
                    transition={{ duration: 0.2, ease: 'easeOut' }}
                    className="flex items-center gap-3 -mt-2 ml-6 pl-3 border-l-2 border-primary/30"
                  >
                    <img src={item.image} alt={item.name} width={40} height={40} loading="lazy" className="w-10 h-10 object-contain bg-surface rounded-md shrink-0" />
                    <div className="flex-1 min-w-0">
                      <p className="text-sm font-medium truncate">{item.quantity > 1 ? `${item.quantity}× ` : ''}{item.name}</p>
                      <p className="text-xs text-muted-foreground">{t('Inbegrepen in bundel', 'Included in bundle')}</p>
                    </div>
                  </motion.div>
                ) : (
                  <motion.div
                    key={item.key}
                    layout
                    exit={{ opacity: 0, x: 24 }}
                    transition={{ duration: 0.2, ease: 'easeOut' }}
                    className="flex gap-3 bg-card border border-border rounded-lg p-3"
                  >
                    <Link to="/product/$slug" params={{ slug: item.slug }} onClick={close} className="shrink-0">
                      <img src={item.image} alt={`${item.name} — ${t('item in winkelwagen', 'item in cart')}`} width={64} height={64} loading="lazy" decoding="async" className="w-16 h-16 object-contain bg-surface rounded-md" />
                    </Link>
                    <div className="flex-1 min-w-0">
                      <Link to="/product/$slug" params={{ slug: item.slug }} onClick={close}>
                        <h4 className="text-sm font-medium truncate hover:text-primary transition-colors">{item.name}</h4>
                      </Link>
                      {item.variationLabel && (
                        <p className="text-xs text-muted-foreground mt-0.5">{item.variationLabel}</p>
                      )}
                      <div className="flex items-center gap-2 mt-1">
                        <span className="text-sm font-bold">€{item.unitPrice.toFixed(2)}</span>
                      </div>
                      <div className="flex items-center justify-between mt-2">
                        <div className="flex items-center border border-border rounded-md">
                          <button
                            disabled={mutating}
                            onClick={() => updateItem(item.key, Math.max(0, item.quantity - 1))}
                            className="p-1.5 hover:bg-muted transition-colors text-muted-foreground hover:text-foreground disabled:opacity-50"
                          >
                            <Minus className="w-3 h-3" />
                          </button>
                          <span className="px-3 text-sm font-medium min-w-[2rem] text-center">{item.quantity}</span>
                          <button
                            disabled={mutating}
                            onClick={() => updateItem(item.key, item.quantity + 1)}
                            className="p-1.5 hover:bg-muted transition-colors text-muted-foreground hover:text-foreground disabled:opacity-50"
                          >
                            <Plus className="w-3 h-3" />
                          </button>
                        </div>
                        <div className="flex items-center gap-3">
                          <span className="text-sm font-bold">€{item.lineTotal.toFixed(2)}</span>
                          <button
                            disabled={mutating}
                            onClick={() => removeItem(item.key)}
                            className="p-1 text-muted-foreground hover:text-destructive transition-colors disabled:opacity-50"
                          >
                            <Trash2 className="w-4 h-4" />
                          </button>
                        </div>
                      </div>
                    </div>
                  </motion.div>
                ))}
                </AnimatePresence>
              </div>
            )}

            {isReady && items.length > 0 && (
              <div className="border-t border-border px-5 py-4 space-y-3">
                <div className="space-y-1.5 text-sm">
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">{t('Subtotaal', 'Subtotal')}</span>
                    <span className="font-medium">€{totals.subtotal.toFixed(2)}</span>
                  </div>
                  {totals.discount > 0 && (
                    <div className="flex justify-between text-success">
                      <span>{t('Korting', 'Discount')}</span>
                      <span>-€{totals.discount.toFixed(2)}</span>
                    </div>
                  )}
                  <div className="flex justify-between">
                    <span className="text-muted-foreground">{t('Verzending', 'Shipping')}</span>
                    <span className="font-medium">
                      {totals.shipping === 0 ? <span className="text-primary">{t('Gratis', 'Free')}</span> : `€${totals.shipping.toFixed(2)}`}
                    </span>
                  </div>
                </div>

                {showFreeShippingMeter && (
                  <div className="space-y-1.5">
                    {freeShippingReached ? (
                      <p className="flex items-center gap-1.5 text-xs font-semibold text-success">
                        <Check className="h-3.5 w-3.5" aria-hidden="true" />
                        {t('Gratis verzending gehaald', 'Free shipping unlocked')}
                      </p>
                    ) : (
                      <p className="text-xs text-muted-foreground">
                        {t('Nog', 'Only')} <strong className="text-primary">€{freeShippingRemaining.toFixed(2)}</strong>{' '}
                        {t('tot gratis verzending', 'to free shipping')}
                      </p>
                    )}
                    <div
                      className="h-1.5 w-full overflow-hidden rounded-full bg-muted"
                      role="progressbar"
                      aria-valuemin={0}
                      aria-valuemax={FREE_SHIPPING_HINT_THRESHOLD}
                      aria-valuenow={Math.round(Math.min(totals.subtotal, FREE_SHIPPING_HINT_THRESHOLD))}
                      aria-label={t('Voortgang naar gratis verzending', 'Progress towards free shipping')}
                    >
                      <motion.div
                        className="h-full rounded-full bg-gradient-to-r from-brand-gold-lo to-brand-gold"
                        initial={false}
                        animate={{ width: `${freeShippingPct}%` }}
                        transition={{ type: 'spring', stiffness: 170, damping: 26 }}
                      />
                    </div>
                  </div>
                )}

                <div className="flex justify-between font-bold text-base border-t border-border pt-3">
                  <span>{t('Totaal', 'Total')}</span>
                  <span className="text-primary">€{totals.total.toFixed(2)}</span>
                </div>
                <div className="grid grid-cols-2 gap-2">
                  <Link
                    to="/cart"
                    onClick={close}
                    className="flex items-center justify-center gap-2 border border-border rounded-md py-2.5 text-sm font-semibold hover:bg-muted transition-colors"
                  >
                    {t('Bekijk wagen', 'View cart')}
                  </Link>
                  <Link
                    to="/checkout"
                    onClick={close}
                    className="flex items-center justify-center gap-2 bg-primary text-primary-foreground rounded-md py-2.5 text-sm font-semibold hover:bg-primary-hover transition-colors"
                  >
                    {t('Afrekenen', 'Checkout')} <ArrowRight className="w-4 h-4" />
                  </Link>
                </div>
              </div>
            )}
          </motion.div>
        </>
      )}
    </AnimatePresence>
  );
};

export default CartDrawer;
