// @design-system: domain/MetricTile

import { cva } from 'class-variance-authority';
import { cn } from '@/lib/cn';
import { useId, type ReactNode } from 'react';
import { AnimatedNumber } from '@/components/ui/domain/AnimatedNumber';
import { Skeleton } from '@/components/ui/feedback/Skeleton';
import { Sparkline } from '@/components/ui/domain/Sparkline';

const tileVariants = cva('flex flex-col gap-2 rounded-xl p-4', {
  variants: {
    tone: {
      default: 'bg-surface-raised text-text-primary',
      success: 'bg-success-50 text-success-700',
      warning: 'bg-warning-50 text-warning-700',
      danger: 'bg-danger-50 text-danger-700',
    },
  },
  defaultVariants: { tone: 'default' },
});

const deltaClasses: Record<'up' | 'down' | 'warn' | 'neutral', string> = {
  up: 'text-success-600',
  down: 'text-danger-600',
  warn: 'text-warning-600',
  neutral: 'text-text-muted',
};

/** Directional delta shown under the value (absorbed from AdminMetricTile). */
export interface MetricDelta {
  value: number;
  dir: 'up' | 'down' | 'warn' | 'neutral';
  /** When dir is neutral, shown instead of a percentage (e.g. "No change"). */
  label?: string;
  suffix?: string;
  periodLabel?: string;
}

/** Props for MetricTile */
export interface MetricTileProps {
  value: ReactNode;
  label: string;
  labelTooltip?: string;
  tone?: 'default' | 'success' | 'warning' | 'danger';
  delta?: MetricDelta;
  loading?: boolean;
  className?: string;
  countUpValue?: number;
  formatCountUpValue?: (value: number) => string;
  sparklinePoints?: number[];
  sparklineLabel?: string;
  periodLabel?: string;
}

/**
 * MetricTile - dashboard metric: large value + label, optional delta and loading state.
 */
export function MetricTile({
  value,
  label,
  labelTooltip,
  tone = 'default',
  delta,
  loading = false,
  className,
  countUpValue,
  formatCountUpValue,
  sparklinePoints,
  sparklineLabel,
  periodLabel,
}: MetricTileProps) {
  const labelId = useId();

  if (loading) {
    return (
      <div className={cn(tileVariants({ tone }), className)} aria-hidden="true">
        <Skeleton className="h-8 w-24 rounded-md" />
        <Skeleton className="h-3 w-20 rounded-md" />
      </div>
    );
  }

  const resolvedValue =
    typeof countUpValue === 'number' ? (
      <AnimatedNumber
        value={countUpValue}
        formatValue={formatCountUpValue}
        ariaLabel={label}
        reserveValue={countUpValue}
      />
    ) : (
      value
    );

  const deltaValue =
    delta?.dir === 'neutral'
      ? (delta.label ?? '—')
      : `${Math.abs(delta?.value ?? 0)}${delta?.suffix ?? '%'}`;

  const deltaGlyph = delta?.dir === 'up' ? '▲' : delta?.dir === 'down' ? '▼' : '◆';

  return (
    <div className={cn(tileVariants({ tone }), className)} role="group" aria-labelledby={labelId}>
      <span className="text-3xl leading-tight font-bold">{resolvedValue}</span>
      <span id={labelId} className="text-xs font-medium opacity-80" title={labelTooltip}>
        {label}
      </span>
      {periodLabel ? <span className="text-text-muted text-xs">{periodLabel}</span> : null}
      {delta && (
        <span
          className={cn('flex items-center gap-1 text-xs font-semibold', deltaClasses[delta.dir])}
        >
          {delta.dir === 'neutral' ? (
            deltaValue
          ) : (
            <>
              <span aria-hidden="true">{deltaGlyph}</span>
              <span>{deltaValue}</span>
            </>
          )}
        </span>
      )}
      {delta?.periodLabel ? (
        <span className="text-text-muted text-xs">{delta.periodLabel}</span>
      ) : null}
      {sparklinePoints && sparklinePoints.length > 0 ? (
        <Sparkline
          aria-label={sparklineLabel ?? label}
          points={sparklinePoints}
          tone={tone === 'default' ? 'default' : tone}
        />
      ) : null}
    </div>
  );
}
