'use client';

import {Card} from '@astryxdesign/core/Card';
import {VStack, HStack} from '@astryxdesign/core/Layout';
import {Text} from '@astryxdesign/core/Text';
import {Icon} from '@astryxdesign/core/Icon';
import type {IconType} from '@astryxdesign/core/Icon';
import {AnimatedNumber} from '@/shared/components/motion/AnimatedNumber';
import {HoverLift} from '@/shared/components/motion/HoverLift';
import {MetricDelta} from '@/shared/components/primitives/MetricDelta';
import {Sparkline} from '@/shared/components/charts/Sparkline';

/**
 * A single headline number.
 *
 * Extracted from the dashboard's private KpiCard because the same object is
 * needed by Staff (present/absent/late/total) and by the Store detail header —
 * and a second hand-written copy is exactly how two screens start disagreeing
 * about how a metric looks.
 *
 * Two deliberate constraints carried over from the dashboard:
 *
 *  - The trend line is GRAY. The delta chip already states whether the
 *    direction is good; tinting the whole line repeats that in the loudest
 *    possible way and would make metric rows the most colourful thing on a
 *    monochrome page.
 *  - Sparklines never animate. A row of them firing on every load is noise.
 */
export function MetricCard({
  label,
  value,
  format,
  icon,
  deltaPct,
  isRiseGood = true,
  trend,
  footer,
}: {
  label: string;
  value: number;
  format: (v: number) => string;
  icon?: IconType;
  deltaPct?: number;
  isRiseGood?: boolean;
  /** 14-ish points. Omit for metrics with no meaningful history. */
  trend?: {v: number}[];
  /** Replaces the sparkline — e.g. a share-of-total caption. */
  footer?: React.ReactNode;
}) {
  return (
    <HoverLift>
      <Card>
        <VStack gap={3}>
          <HStack gap={2} vAlign="center">
            {icon ? <Icon icon={icon} size="sm" color="secondary" /> : null}
            <Text size="sm" color="secondary">
              {label}
            </Text>
          </HStack>

          <HStack gap={2} vAlign="center" hAlign="between" className="min-w-0 flex-wrap gap-y-1">
            {/*
              Text, NOT Heading. A KPI value is data, not a section title —
              marking it up as an h2 puts "32.7k" into the document outline
              and makes screen-reader heading navigation read a list of
              numbers. `display-3` gives the visual weight without the
              semantics.
            */}
            <Text type="display-3" className="truncate shrink min-w-0">
              <AnimatedNumber value={value} format={format} />
            </Text>
            {deltaPct !== undefined ? (
              <div className="shrink-0">
                <MetricDelta value={deltaPct} isRiseGood={isRiseGood} />
              </div>
            ) : null}
          </HStack>

          {footer ??
            (trend && trend.length > 1 ? (
              <Sparkline data={trend} dataKey="v" />
            ) : null)}
        </VStack>
      </Card>
    </HoverLift>
  );
}
