import type { LucideIcon } from 'lucide-react';
import { cn } from 'helpers/cn';
import { type Tone, toneFill, toneText } from './tone';

// The state marker, in the two densities every list needs: the full pill where there is room to say
// the word, and the bare icon where a row is too dense to spend a pill on.
//
// Both take the same `tone` + `icon`, so a view can switch between them without the colours drifting
// apart — which is exactly how the Gitea list and detail views ended up disagreeing about what
// colour "closed" was.

type StatusPillProps = {
  tone: Tone;
  icon?: LucideIcon;
  children: React.ReactNode;
  className?: string;
  title?: string;
};

export const StatusPill = ({ tone, icon: Icon, children, className, title }: StatusPillProps) => (
  <span
    title={title}
    className={cn(
      'inline-flex shrink-0 items-center gap-1.5 rounded-full px-2.5 py-0.5 text-xs font-medium',
      toneFill[tone],
      className,
    )}
  >
    {Icon && <Icon className="h-3.5 w-3.5" />}
    {children}
  </span>
);

/**
 * The same state as a bare icon. `title` is not optional in spirit — an icon with no text is the one
 * place the icon language's "if it needs explanation it is too complicated" rule can be broken by
 * accident, and a tooltip is the cheapest repair.
 */
export const StatusIcon = ({
  tone,
  icon: Icon,
  title,
  className,
}: {
  tone: Tone;
  icon: LucideIcon;
  title: string;
  className?: string;
}) => <Icon className={cn('h-4 w-4 shrink-0', toneText[tone], className)} aria-label={title} />;
