// @design-system: domain/DealCTA

'use client';

import { useCallback } from 'react';
import { cn } from '@/lib/cn';
import { Icon } from '@/components/ui/icons/Icon';
import { useT } from '@/lib/i18n/react';
import { useCart } from '@/features/cart/useCart';
import { addButtonVariants } from './variants';

function runFlyToCart(source: HTMLElement) {
  if (typeof window === 'undefined') return;
  if (window.matchMedia?.('(prefers-reduced-motion: reduce)').matches) return;

  const target = document.querySelector<HTMLElement>('[data-cart-fly-target="true"]');
  if (!target) return;

  const sourceRect = source.getBoundingClientRect();
  const targetRect = target.getBoundingClientRect();
  const flyer = document.createElement('div');
  flyer.setAttribute('aria-hidden', 'true');
  flyer.setAttribute('data-cart-flyer', 'true');
  flyer.className =
    'pointer-events-none fixed z-[var(--z-toast)] inline-flex h-9 min-w-9 items-center justify-center rounded-full bg-brand-primary-600 px-3 text-sm font-semibold text-brand-on-primary shadow-lg transition-[transform,opacity] duration-[var(--duration-slow)] ease-out';
  flyer.textContent = '+1';
  flyer.style.left = `${sourceRect.left + sourceRect.width / 2 - 18}px`;
  flyer.style.top = `${sourceRect.top + sourceRect.height / 2 - 18}px`;
  flyer.style.transform = 'translate3d(0, 0, 0) scale(1)';
  flyer.style.opacity = '1';
  document.body.appendChild(flyer);

  const deltaX = targetRect.left + targetRect.width / 2 - (sourceRect.left + sourceRect.width / 2);
  const deltaY = targetRect.top + targetRect.height / 2 - (sourceRect.top + sourceRect.height / 2);
  const finalDistance = Math.hypot(
    sourceRect.left + sourceRect.width / 2 + deltaX - (targetRect.left + targetRect.width / 2),
    sourceRect.top + sourceRect.height / 2 + deltaY - (targetRect.top + targetRect.height / 2),
  );

  requestAnimationFrame(() => {
    flyer.style.transform = `translate3d(${deltaX}px, ${deltaY}px, 0) scale(0.42)`;
    flyer.style.opacity = '0.18';
  });

  window.setTimeout(() => {
    target.setAttribute('data-fly-landed', 'true');
    target.setAttribute('data-fly-distance', finalDistance.toFixed(2));
    flyer.remove();
  }, 420);
}

export interface AddToCartButtonProps {
  /** SKU ID to add. Pass null to disable (e.g. when no variant selected). */
  dealSkuId: string | null;
  size?: 'sm' | 'md' | 'lg';
  disabled?: boolean;
  iconOnly?: boolean;
  className?: string;
  onAdded?: () => void;
  /** Snapshot stored in anon cart so drawer shows title/image without a server fetch. */
  title?: string;
  imageUrl?: string;
  /** Pass -1 when rendered inside an aria-hidden visible duplicate (axe aria-hidden-focus). */
  tabIndex?: number;
}

/**
 * AddToCartButton — adds deal SKU to cart.
 * Plus icon. Stops event propagation (safe inside card buttons).
 */
export function AddToCartButton({
  dealSkuId,
  size = 'md',
  disabled = false,
  iconOnly,
  className,
  onAdded,
  title,
  imageUrl,
  tabIndex,
}: AddToCartButtonProps) {
  const t = useT('domain_deal_cta');
  const { add } = useCart();
  const resolvedIconOnly = iconOnly ?? size === 'sm';

  const addLabel = size === 'lg' ? t('add_to_cart') : size === 'md' ? t('add_short') : t('add');

  const isDisabled = disabled || dealSkuId === null;

  const handleClick = useCallback(
    (e: React.MouseEvent) => {
      e.preventDefault();
      e.stopPropagation();
      if (isDisabled || !dealSkuId) return;
      add(dealSkuId, 1, { title, imageUrl });
      runFlyToCart(e.currentTarget as HTMLElement);
      onAdded?.();
    },
    [dealSkuId, add, isDisabled, onAdded, title, imageUrl],
  );

  return (
    <button
      type="button"
      onClick={handleClick}
      disabled={isDisabled}
      tabIndex={tabIndex}
      aria-label={resolvedIconOnly ? addLabel : undefined}
      className={cn(
        addButtonVariants({ size }),
        'border-brand-primary-600 text-brand-primary-600 hover:bg-brand-primary-50 active:bg-brand-primary-100 border',
        className,
      )}
    >
      <Icon name="Plus" size="sm" aria-hidden />
      {!resolvedIconOnly && <span>{addLabel}</span>}
    </button>
  );
}
