'use client';

import {VStack, HStack} from '@astryxdesign/core/Layout';
import {Text} from '@astryxdesign/core/Text';
import {Icon} from '@astryxdesign/core/Icon';
import {Timestamp} from '@astryxdesign/core/Timestamp';
import {ICONS} from '@/shared/utils/icons';
import type {IconKey} from '@/shared/utils/icons';

/** Icon tones. Only `warning` carries colour — see the note on ActivityFeed. */
export type ActivityTone = 'neutral' | 'warning';

export interface ActivityEntry {
  id: string;
  title: string;
  detail?: string;
  at: string;
  /** Which kind of event this is — the glyph IS the category label. */
  icon: IconKey;
  tone: ActivityTone;
  /** Announced with the icon; a glyph alone is not an accessible label. */
  toneLabel: string;
}

/**
 * One row in a chronological feed.
 *
 * Rows, not cards: Astryx's own guidance is that dense sequential data reads
 * edge-to-edge, and wrapping each event in a Card would triple the vertical
 * space while making the feed harder to scan.
 *
 * The leading glyph is the event's TYPE — purchase, reward, staff, store,
 * alert — not its status. A status dot could only encode severity, which meant
 * five different kinds of event all rendered as the same grey circle and the
 * feed could not be skimmed by category. The icon does that job, and colour is
 * left to do the one job it is good at: marking the row that needs action.
 *
 * Hover is `--color-overlay-hover`, the same white-at-6% the sidebar nav uses.
 * It tracks the eye across a dense row; it does not imply the row is clickable,
 * because there is no per-event destination to send anyone to.
 */
export function ActivityItem({entry}: {entry: ActivityEntry}) {
  return (
    <HStack
      gap={3}
      vAlign="start"
      paddingBlock={1}
      paddingInline={2}
      // Token-backed utilities: --color-overlay-hover is bridged into Tailwind
      // by tailwind-theme.css, so this is the theme's hover, not a new value.
      className="rounded-md transition-colors hover:bg-overlay-hover"
    >
      <HStack paddingBlock={0.5}>
        <Icon
          icon={ICONS[entry.icon]}
          size="sm"
          color={entry.tone === 'warning' ? 'warning' : 'secondary'}
          label={entry.toneLabel}
        />
      </HStack>
      <VStack gap={0.5} width="100%">
        <HStack gap={3} hAlign="between" vAlign="center">
          <Text size="sm" weight="medium">
            {entry.title}
          </Text>
          <Timestamp value={entry.at} format="relative" isLive />
        </HStack>
        {entry.detail ? (
          <Text size="sm" color="secondary">
            {entry.detail}
          </Text>
        ) : null}
      </VStack>
    </HStack>
  );
}

/**
 * The list wrapper.
 *
 * Dividers are gone: with a hover background doing the row separation, rules
 * between every entry were two separators doing one job, and each one cost
 * vertical space on a panel whose whole problem was height.
 *
 * `limit` is deliberately applied HERE rather than by each caller slicing its
 * own array — a feed that quietly grows without bound is what put this panel
 * at 784px on the dashboard, and one place to cap it is one place to get right.
 */
export function ActivityFeed({
  entries,
  limit,
}: {
  entries: ActivityEntry[];
  limit?: number;
}) {
  const shown = limit ? entries.slice(0, limit) : entries;

  return (
    <VStack gap={0}>
      {shown.map((e) => (
        <ActivityItem key={e.id} entry={e} />
      ))}
    </VStack>
  );
}
