"use client";

import { Group, SimpleGrid, Skeleton, Stack, Text } from "@mantine/core";
import type { ReactNode } from "react";
import { AnimatedNumber, MotionChild, ProgressSpark, Stagger } from "./motion";
import styles from "./promo.module.css";

export interface StatTileSpec {
  key: string;
  label: string;
  value: number;
  icon: ReactNode;
  /** Any CSS colour — drives the rail, wash, icon chip and progress bar. */
  color: string;
  /** Second gradient stop for the rail. Falls back to `color`. */
  colorTo?: string;
  /** Small line under the figure. */
  hint?: string;
  /** When set, draws a share-of-total bar (0–100). */
  percent?: number;
}

/**
 * KPI row for the campaigns dashboard. Tiles cascade in on mount and their
 * figures roll up from the previous value whenever the filters change, so a
 * filter edit is visibly reflected in the numbers.
 */
export function StatTiles({
  tiles,
  loading = false,
}: {
  tiles: StatTileSpec[];
  loading?: boolean;
}) {
  /*
   * Column count is derived, not fixed. A hardcoded `lg: 5` left an empty cell
   * whenever a tile was removed, and would have squeezed a sixth onto its own
   * row. Capped at 5 so tiles never get too narrow to read.
   */
  const count = Math.max(1, tiles.length);
  const cols = {
    base: 1,
    xs: Math.min(count, 2),
    md: Math.min(count, 3),
    lg: Math.min(count, 5),
  };

  if (loading) {
    return (
      <SimpleGrid cols={cols} spacing="md">
        {tiles.map((t) => (
          <Skeleton key={t.key} height={104} radius="lg" />
        ))}
      </SimpleGrid>
    );
  }

  return (
    <Stagger stagger={0.06}>
      <SimpleGrid cols={cols} spacing="md">
        {tiles.map((tile) => (
          <MotionChild key={tile.key}>
            <div
              className={styles.tile}
              style={
                {
                  "--tile-accent": tile.color,
                  "--tile-accent-to": tile.colorTo ?? tile.color,
                  // The wash and icon chip need a faint version of the colour.
                  // color-mix keeps this working for any format the palette
                  // emits (oklch here, hex or a var elsewhere).
                  "--tile-accent-soft": `color-mix(in srgb, ${tile.color} 12%, transparent)`,
                } as React.CSSProperties
              }
            >
              <div className={styles.tileBody}>
                <Group justify="space-between" align="flex-start" wrap="nowrap">
                  <Stack gap={2} style={{ minWidth: 0 }}>
                    <Text size="xs" c="dimmed" fw={600} tt="uppercase" lh={1.4}>
                      {tile.label}
                    </Text>
                    <div className={styles.tileValue}>
                      <AnimatedNumber value={tile.value} />
                    </div>
                  </Stack>
                  <div className={styles.tileIcon}>{tile.icon}</div>
                </Group>

                {/*
                 * Bar and hint share one bottom-anchored footer.
                 *
                 * Giving each its own `margin-top: auto` would split the free
                 * space between them and leave the bar floating mid-tile — the
                 * footer keeps them together and on the same baseline as every
                 * other tile's.
                 */}
                {(tile.percent !== undefined || tile.hint) && (
                  <div className={styles.tileFooter}>
                    {tile.percent !== undefined && (
                      <ProgressSpark
                        percent={tile.percent}
                        color={tile.color}
                      />
                    )}
                    {tile.hint && (
                      <Text
                        size="xs"
                        c="dimmed"
                        className={styles.tileHint}
                        /* Full text on hover, since the line is clipped. */
                        title={tile.hint}
                        mt={tile.percent !== undefined ? 6 : 8}
                      >
                        {tile.hint}
                      </Text>
                    )}
                  </div>
                )}
              </div>
            </div>
          </MotionChild>
        ))}
      </SimpleGrid>
    </Stagger>
  );
}
