import type { CSSProperties } from 'react';
import type { NotificationItem, NotificationKind } from './types.js';

export interface InboxItemProps {
  item: NotificationItem;
  /** Called when the item body is clicked. */
  onSelect?: (item: NotificationItem) => void;
  /** Mark this single item as read. */
  onMarkRead?: (id: string) => void;
  /** Dense layout (smaller padding, smaller font). */
  dense?: boolean;
  className?: string;
  style?: CSSProperties;
}

/**
 * `<InboxItem>` — single notification row. Used inside `<NotificationCenter>`
 * but also exported for products that build custom inbox surfaces.
 */
export function InboxItem({
  item,
  onSelect,
  onMarkRead,
  dense,
  className,
  style,
}: InboxItemProps) {
  const tone = TONE[item.kind ?? 'info'];
  const padding = dense ? '6px 10px' : 'var(--bl-space-2, 8px) var(--bl-space-3, 12px)';

  return (
    <article
      data-testid={`bl-inbox-item-${item.id}`}
      data-kind={item.kind ?? 'info'}
      data-read={item.read ? 'true' : 'false'}
      className={className}
      style={{
        display: 'flex',
        alignItems: 'flex-start',
        gap: 'var(--bl-space-2, 8px)',
        padding,
        borderBottom: '1px solid var(--bl-border-subtle, rgba(0,0,0,0.06))',
        background: item.read ? 'transparent' : 'var(--bl-accent-muted, rgba(99,102,241,0.06))',
        ...style,
      }}
    >
      {/* Unread dot */}
      <span
        aria-hidden
        style={{
          width: 8,
          height: 8,
          borderRadius: '50%',
          marginTop: 8,
          flexShrink: 0,
          background: item.read ? 'transparent' : tone.dot,
          transition: 'background 200ms ease',
        }}
      />

      {/* Avatar / kind icon */}
      <span
        aria-hidden
        style={{
          width: 28,
          height: 28,
          borderRadius: 'var(--bl-radius-pill, 999px)',
          background: tone.iconBg,
          color: tone.iconFg,
          display: 'inline-grid',
          placeItems: 'center',
          fontSize: 14,
          fontWeight: 700,
          flexShrink: 0,
        }}
      >
        {item.icon ?? tone.glyph}
      </span>

      <div style={{ flex: 1, minWidth: 0 }}>
        <button
          type="button"
          data-testid={`bl-inbox-item-trigger-${item.id}`}
          onClick={() => {
            if (!item.read) onMarkRead?.(item.id);
            onSelect?.(item);
          }}
          style={{
            display: 'block',
            width: '100%',
            textAlign: 'left',
            background: 'transparent',
            border: 'none',
            padding: 0,
            color: 'inherit',
            cursor: 'pointer',
          }}
        >
          <div
            style={{
              fontSize: dense ? '0.8rem' : '0.85rem',
              fontWeight: 600,
              color: 'var(--bl-text-primary, inherit)',
            }}
          >
            {item.title}
          </div>
          {item.body && (
            <div
              style={{
                fontSize: dense ? '0.7rem' : '0.75rem',
                color: 'var(--bl-text-secondary, #555)',
                marginTop: 2,
                whiteSpace: 'pre-wrap',
              }}
            >
              {item.body}
            </div>
          )}
          {item.createdAt && (
            <div
              style={{
                fontSize: '0.7rem',
                color: 'var(--bl-text-tertiary, #888)',
                marginTop: 4,
              }}
            >
              {relativeTime(item.createdAt)}
            </div>
          )}
        </button>
        {item.actions && item.actions.length > 0 && (
          <div style={{ marginTop: 6, display: 'flex', gap: 6 }}>
            {item.actions.map(a => (
              <button
                key={a.id}
                type="button"
                onClick={a.onSelect}
                style={{
                  fontSize: '0.7rem',
                  padding: '2px 8px',
                  borderRadius: 'var(--bl-radius-pill, 999px)',
                  border: '1px solid var(--bl-border, rgba(0,0,0,0.12))',
                  background: 'transparent',
                  color: 'var(--bl-text-secondary, #555)',
                  cursor: 'pointer',
                }}
              >
                {a.label}
              </button>
            ))}
          </div>
        )}
      </div>
    </article>
  );
}

const TONE: Record<NotificationKind, { dot: string; iconBg: string; iconFg: string; glyph: string }> = {
  info: {
    dot: 'var(--bl-info, #38bdf8)',
    iconBg: 'var(--bl-info-muted, rgba(56,189,248,0.18))',
    iconFg: 'var(--bl-info, #38bdf8)',
    glyph: 'i',
  },
  success: {
    dot: 'var(--bl-success, #22c55e)',
    iconBg: 'var(--bl-success-muted, rgba(34,197,94,0.18))',
    iconFg: 'var(--bl-success, #22c55e)',
    glyph: '✓',
  },
  warning: {
    dot: 'var(--bl-warning, #f59e0b)',
    iconBg: 'var(--bl-warning-muted, rgba(245,158,11,0.18))',
    iconFg: 'var(--bl-warning, #f59e0b)',
    glyph: '!',
  },
  danger: {
    dot: 'var(--bl-danger, #ef4444)',
    iconBg: 'var(--bl-danger-muted, rgba(239,68,68,0.18))',
    iconFg: 'var(--bl-danger, #ef4444)',
    glyph: '✕',
  },
  mention: {
    dot: 'var(--bl-accent, #6366f1)',
    iconBg: 'var(--bl-accent-muted, rgba(99,102,241,0.18))',
    iconFg: 'var(--bl-accent, #6366f1)',
    glyph: '@',
  },
};

function relativeTime(input: string | Date): string {
  const d = typeof input === 'string' ? new Date(input) : input;
  const diff = (Date.now() - d.getTime()) / 1000;
  if (diff < 60) return 'just now';
  if (diff < 3600) return `${Math.floor(diff / 60)}m ago`;
  if (diff < 86400) return `${Math.floor(diff / 3600)}h ago`;
  if (diff < 86400 * 7) return `${Math.floor(diff / 86400)}d ago`;
  return d.toLocaleDateString();
}
