import { ArrowDown, ArrowUp, Minus } from 'lucide-react';

import { formatNumber } from '@/lib/format';
import { cn } from '@/lib/utils';

type MetricDeltaVariant = 'positive' | 'negative' | 'neutral';

interface MetricDeltaProps {
  value: number;
  format?: 'percent' | 'number' | 'decimal';
  variant?: MetricDeltaVariant;
  className?: string;
}

function formatValue(value: number, format: MetricDeltaProps['format']): string {
  const abs = Math.abs(value);
  switch (format) {
    case 'percent': {
      const rounded = Math.round(abs * 10) / 10;
      return rounded % 1 === 0 ? `${Math.round(abs)}%` : `${rounded}%`;
    }
    case 'number':
      return formatNumber(abs);
    case 'decimal':
      return abs.toFixed(2);
    default: {
      const rounded = Math.round(abs * 10) / 10;
      return rounded % 1 === 0 ? `${Math.round(abs)}` : `${rounded}`;
    }
  }
}

function getVariant(value: number, overrideVariant?: MetricDeltaVariant): MetricDeltaVariant {
  if (overrideVariant) return overrideVariant;
  if (value > 0) return 'positive';
  if (value < 0) return 'negative';
  return 'neutral';
}

function getColorClass(variant: MetricDeltaVariant): string {
  switch (variant) {
    case 'positive':
      return 'text-success';
    case 'negative':
      return 'text-destructive';
    case 'neutral':
      return 'text-muted-foreground';
    default:
      return 'text-muted-foreground';
  }
}

export default function MetricDelta({
  value,
  format = 'percent',
  variant,
  className,
}: MetricDeltaProps) {
  if (value === 0) {
    return (
      <span
        data-testid="metric-delta"
        className={cn('inline-flex items-center gap-1 text-sm text-muted-foreground', className)}
      >
        <span className="sr-only">No change</span>
        <Minus className="h-3 w-3" aria-hidden="true" />
        {formatValue(0, format)}
      </span>
    );
  }

  const resolvedVariant = getVariant(value, variant);
  const colorClass = getColorClass(resolvedVariant);
  const isPositive = resolvedVariant === 'positive';
  const formattedValue = formatValue(value, format);
  const srOnlyText = isPositive
    ? `increased by ${formattedValue}`
    : `decreased by ${formattedValue}`;

  return (
    <span
      data-testid="metric-delta"
      className={cn('inline-flex items-center gap-1 text-sm font-medium', colorClass, className)}
    >
      {isPositive ? (
        <ArrowUp className="h-3 w-3" aria-hidden="true" />
      ) : (
        <ArrowDown className="h-3 w-3" aria-hidden="true" />
      )}
      <span className="sr-only">{srOnlyText}</span>
      {isPositive ? '+' : '-'}
      {formattedValue}
    </span>
  );
}
