// @design-system: domain/cart/CartLineItem
// Registered at /design-system#cartlineitem-domain

'use client';

import { useEffect, useRef, useState } from 'react';
import { cn } from '@/lib/cn';
import { Icon } from '@/components/ui/icons/Icon';
import { Image } from '@/components/ui/primitives/Image';
import { QuantityStepper } from '@/components/ui/primitives/QuantityStepper';
import { Button } from '@/components/ui/primitives/Button';
import { IconButton } from '@/components/ui/primitives/IconButton';
import { useT } from '@/lib/i18n/react';
import { applyQtyTier } from '@/server/pricing/qty-tier';
import { formatAgorotShekels } from '@/lib/money';

/** A single cart line item data shape */
export interface CartLineItemData {
  dealId: string;
  /**
   * Deal image ID (passed to shared Image primitive).
   * Optional — absent for anon users and when the server hasn't joined dealImages yet.
   * When absent, a placeholder tile is rendered.
   */
  imageId?: string;
  /**
   * Deal title. Optional for anon cart (snapshot fields absent).
   * When absent, the dealId (truncated) is shown as a fallback.
   */
  title?: string;
  /** Vendor name. Optional for anon cart. */
  vendorName?: string;
  /**
   * Unit price in agorot (integer). Displayed as ₪.
   * Optional for anon cart (no server snapshot).
   */
  unitPrice?: number;
  /** Current quantity. */
  qty: number;
  /**
   * Maximum quantity (min of maxPerUser, remainingStock).
   * Optional for anon cart. When absent, stepper has no upper cap.
   */
  maxQty?: number;
  /** Qty-tier definitions for this SKU. Empty array when no tiers apply. */
  qtyTiers: { minQty: number; discountPercent: number }[];
}

/** Props for CartLineItem */
export interface CartLineItemProps {
  /** Line item data. */
  item: CartLineItemData;
  /** Called when quantity changes. */
  onQtyChange: (dealId: string, qty: number) => void;
  /** Called when remove is clicked. */
  onRemove: (dealId: string) => void;
  /** When true, shows loading state. */
  loading?: boolean;
  /** Additional class names. */
  className?: string;
}

/**
 * CartLineItem — one row in the cart: image, title, vendor, price, quantity stepper, remove.
 *
 * @example
 * ```tsx
 * <CartLineItem
 *   item={lineItem}
 *   onQtyChange={(dealId, qty) => updateQty(dealId, qty)}
 *   onRemove={(dealId) => remove(dealId)}
 * />
 * ```
 */
export function CartLineItem({
  item,
  onQtyChange,
  onRemove,
  loading = false,
  className,
}: CartLineItemProps) {
  const t = useT('cart');
  const tV = useT('variants');
  const [quickActionsOpen, setQuickActionsOpen] = useState(false);
  const longPressTimerRef = useRef<number | null>(null);
  const pointerStartRef = useRef<{ x: number; y: number } | null>(null);
  const displayTitle = item.title ?? item.dealId.slice(0, 8) + '…';
  const priceILS = item.unitPrice !== undefined ? formatAgorotShekels(item.unitPrice) : null;
  const { effectiveUnitAgorot, tierApplied } =
    item.unitPrice !== undefined
      ? applyQtyTier(item.unitPrice, item.qty, item.qtyTiers)
      : { effectiveUnitAgorot: item.unitPrice, tierApplied: null };
  const tieredPriceILS =
    tierApplied !== null && effectiveUnitAgorot !== undefined
      ? formatAgorotShekels(effectiveUnitAgorot)
      : null;

  useEffect(
    () => () => {
      if (longPressTimerRef.current !== null) {
        window.clearTimeout(longPressTimerRef.current);
      }
    },
    [],
  );

  const clearLongPress = () => {
    if (longPressTimerRef.current !== null) {
      window.clearTimeout(longPressTimerRef.current);
      longPressTimerRef.current = null;
    }
    pointerStartRef.current = null;
  };

  const startLongPress = (event: React.PointerEvent<HTMLDivElement>) => {
    if (event.pointerType === 'mouse') return;
    if ((event.target as HTMLElement).closest('button')) return;
    clearLongPress();
    pointerStartRef.current = { x: event.clientX, y: event.clientY };
    longPressTimerRef.current = window.setTimeout(() => {
      setQuickActionsOpen(true);
      longPressTimerRef.current = null;
    }, 450);
  };

  const cancelLongPressOnMove = (event: React.PointerEvent<HTMLDivElement>) => {
    if (!pointerStartRef.current || longPressTimerRef.current === null) return;
    const dx = event.clientX - pointerStartRef.current.x;
    const dy = event.clientY - pointerStartRef.current.y;
    if (Math.hypot(dx, dy) > 12) {
      clearLongPress();
    }
  };

  const runQuickAction = (action: 'decrease' | 'increase' | 'remove') => {
    setQuickActionsOpen(false);
    if (action === 'remove') {
      onRemove(item.dealId);
      return;
    }
    onQtyChange(item.dealId, item.qty + (action === 'increase' ? 1 : -1));
  };

  return (
    <div
      className={cn(
        'relative flex items-start gap-3 py-3',
        loading && 'pointer-events-none opacity-60',
        className,
      )}
      data-testid={`cart-line-${item.dealId}`}
      onPointerDown={startLongPress}
      onPointerMove={cancelLongPressOnMove}
      onPointerUp={clearLongPress}
      onPointerCancel={clearLongPress}
      onPointerLeave={clearLongPress}
    >
      {/* Product image / placeholder */}
      <div className="bg-surface-subtle shrink-0 overflow-hidden rounded-md">
        {item.imageId ? (
          <Image
            src={item.imageId}
            alt={displayTitle}
            width={64}
            height={64}
            loading="lazy"
            variant="card"
            className="h-16 w-16 object-cover"
          />
        ) : (
          <div
            className="text-text-muted flex h-16 w-16 items-center justify-center"
            aria-hidden="true"
          >
            <Icon name="ShoppingCart" size="md" />
          </div>
        )}
      </div>

      {/* Details */}
      <div className="flex min-w-0 flex-1 flex-col gap-1">
        <p className="text-text-primary truncate text-sm font-medium">{displayTitle}</p>
        {item.vendorName && <p className="text-text-muted text-xs">{item.vendorName}</p>}
        {priceILS !== null && (
          <p className="text-brand-primary-700 text-sm font-semibold">{priceILS}</p>
        )}
        {tierApplied !== null && tieredPriceILS !== null && (
          <p className="text-text-secondary text-xs">
            {tV('qty_tier_applied')
              .replace('{percent}', String(tierApplied.discountPercent))
              .replace('{minQty}', String(tierApplied.minQty))}
            {' · '}
            {tieredPriceILS}
          </p>
        )}
      </div>

      {/* Controls: stepper + remove */}
      <div className="flex shrink-0 flex-col items-end gap-2">
        <IconButton
          variant="ghost"
          size="sm"
          shape="square"
          aria-label={t('remove')}
          onClick={() => onRemove(item.dealId)}
          disabled={loading}
          className="text-text-muted hover:bg-danger-50 hover:text-danger-600"
        >
          <Icon name="Trash2" size="sm" aria-hidden />
        </IconButton>

        <QuantityStepper
          value={item.qty}
          min={1}
          max={item.maxQty}
          onChange={(qty) => onQtyChange(item.dealId, qty)}
          label={displayTitle}
          disabled={loading}
        />
        {/* Announce quantity changes to screen readers */}
        <span className="sr-only" aria-live="polite" aria-atomic="true">
          {`${t('qty_updated')} ${item.qty}`}
        </span>
      </div>

      {quickActionsOpen && (
        <div
          className="bg-surface-raised border-border-subtle absolute inset-x-0 top-full z-10 mt-2 flex items-center justify-end gap-2 rounded-xl border p-2 shadow-lg"
          data-testid={`cart-line-actions-${item.dealId}`}
          role="group"
          aria-label={t('quick_actions_label')}
        >
          <Button
            type="button"
            variant="secondary"
            size="sm"
            onClick={() => runQuickAction('decrease')}
            disabled={item.qty <= 1}
          >
            {t('quick_decrease')}
          </Button>
          <Button
            type="button"
            variant="secondary"
            size="sm"
            onClick={() => runQuickAction('increase')}
            disabled={item.maxQty !== undefined && item.qty >= item.maxQty}
          >
            {t('quick_increase')}
          </Button>
          <Button type="button" variant="danger" size="sm" onClick={() => runQuickAction('remove')}>
            {t('quick_remove')}
          </Button>
        </div>
      )}
    </div>
  );
}
