// @design-system: notification/NotificationItem
/**
 * NotificationItem — single row in the notification inbox.
 *
 * Displays icon + locale-aware title/body + relative timestamp.
 * Clicking marks the notification as read and navigates to `link` if set.
 * `onRead(id)` is called for optimistic updates in the parent list.
 *
 * @wave 2c - UI components
 */
import type { KeyboardEvent } from 'react';
import { pickLocalized } from '@/lib/i18n';
import { useLocale } from '@/lib/i18n/react';
import { useT } from '@/lib/i18n/react';
import { formatRelative } from '@/lib/format';
import { Icon } from '@/components/ui/icons/Icon';
import { Button } from '@/components/ui/primitives/Button';
import type { NotificationRow } from '@/server/db/queries/live-notifications';

export interface NotificationItemProps {
  /** Full notification record from the DB. */
  notification: NotificationRow;
  /** Called with the notification id after read mutation fires. */
  onRead: (id: string) => void;
  onDismiss?: (notification: NotificationRow) => void;
  staggerIndex?: number;
}

/** Map event type to an icon name recognised by the Icon whitelist. */
function eventIcon(event: string): Parameters<typeof Icon>[0]['name'] {
  switch (event) {
    case 'purchase':
    case 'purchase_confirmed':
      return 'ShoppingBag';
    case 'deal_expiry':
    case 'deal_expiring':
      return 'Clock';
    case 'club_invite':
      return 'Users';
    case 'system':
    case 'admin':
      return 'Bell';
    default:
      return 'Bell';
  }
}

export function NotificationItem({
  notification: n,
  onRead,
  onDismiss,
  staggerIndex = 0,
}: NotificationItemProps) {
  const { locale } = useLocale();
  const t = useT('notif');

  const title = pickLocalized(n, locale, 'title');
  const body = pickLocalized(n, locale, 'body');
  const isUnread = n.readAt === null;

  function handleClick() {
    onRead(n.id);
    if (n.link) {
      window.location.href = n.link;
    }
  }

  function handleKeyDown(e: KeyboardEvent<HTMLButtonElement>) {
    if (e.key === 'Enter' || e.key === ' ') {
      e.preventDefault();
      handleClick();
    }
  }

  return (
    <li
      data-testid={`notification-item-${n.id}`}
      data-read-state={isUnread ? 'unread' : 'read'}
      data-stagger-index={staggerIndex}
      className={[
        'group relative flex gap-3 rounded-md px-3 py-3 transition-colors',
        'hover:bg-surface-raised focus-within:ring-brand-primary-500 focus-within:ring-2',
        isUnread ? 'bg-brand-primary-50' : 'bg-transparent',
      ].join(' ')}
      style={{ transitionDelay: `${Math.min(staggerIndex, 7) * 30}ms` }}
    >
      {/* Unread dot */}
      {isUnread && (
        <span
          aria-hidden
          className="bg-brand-primary-500 absolute start-1 top-1/2 size-2 -translate-y-1/2 rounded-full"
        />
      )}

      <button
        type="button"
        aria-label={title ?? t('item_mark_read')}
        onClick={handleClick}
        onKeyDown={handleKeyDown}
        className="focus-visible:ring-brand-primary-500 flex flex-1 cursor-pointer items-start gap-3 text-start focus-visible:rounded-sm focus-visible:ring-2 focus-visible:outline-none"
      >
        {/* Event icon */}
        <span
          aria-hidden
          className="bg-brand-primary-100 mt-0.5 flex size-8 shrink-0 items-center justify-center rounded-full"
        >
          <Icon name={eventIcon(n.event)} size="sm" color="primary" />
        </span>

        {/* Content */}
        <div className="min-w-0 flex-1">
          <p
            className={[
              'truncate text-sm',
              isUnread ? 'text-text-primary font-semibold' : 'text-text-secondary font-medium',
            ].join(' ')}
          >
            {title ?? t('item_untitled')}
          </p>

          {body ? <p className="text-text-muted mt-0.5 line-clamp-2 text-xs">{body}</p> : null}

          <time
            dateTime={new Date(n.createdAt).toISOString()}
            className="text-text-muted mt-1 block text-xs"
          >
            {formatRelative(new Date(n.createdAt), locale)}
          </time>
        </div>
      </button>

      {onDismiss ? (
        <Button
          type="button"
          variant="ghost"
          size="sm"
          onClick={() => onDismiss(n)}
          className="text-text-muted hover:text-text-primary focus-visible:ring-brand-primary-500 absolute end-3 top-3 rounded-sm text-xs opacity-0 transition-opacity group-hover:opacity-100 focus-visible:opacity-100 focus-visible:ring-2 focus-visible:outline-none"
          aria-label={t('dismiss')}
        >
          {t('dismiss')}
        </Button>
      ) : null}
    </li>
  );
}
