'use client';

import {Icon} from '@astryxdesign/core/Icon';
import type {ReportKpi} from '@/features/loyaly-ai/types/chat';

function MiniSparkline({data}: {data: number[]}) {
  if (!data || data.length < 2) return null;
  const min = Math.min(...data);
  const max = Math.max(...data);
  const range = max - min || 1;
  const width = 80;
  const height = 24;

  const points = data
    .map((val, idx) => {
      const x = (idx / (data.length - 1)) * width;
      const y = height - ((val - min) / range) * (height - 4) - 2;
      return `${x},${y}`;
    })
    .join(' ');

  return (
    <svg width={width} height={height} className="overflow-visible">
      <polyline
        fill="none"
        stroke="currentColor"
        strokeWidth="2"
        strokeLinecap="round"
        strokeLinejoin="round"
        points={points}
        className="text-primary/70"
      />
    </svg>
  );
}

export function KpiGridBlock({kpis}: {kpis: ReportKpi[]}) {
  if (!kpis || kpis.length === 0) return null;

  return (
    /**
     * Intrinsic sizing, not a column count.
     *
     * This was `grid-cols-2 sm:grid-cols-3`, and `sm:` is a VIEWPORT query —
     * always true on desktop — so three columns were forced into a 440px
     * panel and each card landed at ~117px. The grid now states the only
     * thing that is actually true of a KPI card (it needs ~180px to be
     * legible) and lets the browser fit as many as the panel allows: two in
     * the default rail, five or six when it is dragged wide. Cards reflow to
     * the next row instead of shrinking past readability.
     *
     * `min(180px, 100%)` rather than a bare `180px` is what keeps this from
     * trading one overflow for another: at a container narrower than the
     * track minimum — the mobile slide-over, or a panel dragged to its 420px
     * floor with deep padding — a rigid 180px track would push the grid wider
     * than its parent and reintroduce horizontal scrolling. The `min()` lets
     * the track collapse to the container in exactly that case and behave as
     * a fixed minimum everywhere else.
     */
    <div className="grid w-full max-w-full gap-3 grid-cols-[repeat(auto-fit,minmax(min(180px,100%),1fr))]">
      {kpis.map((kpi) => {
        const isUp = kpi.trendDirection === 'up' || (kpi.trend && kpi.trend.startsWith('+'));
        const isDown = kpi.trendDirection === 'down' || (kpi.trend && (kpi.trend.startsWith('-') || kpi.trend.startsWith('−')));

        return (
          <div
            key={kpi.id || kpi.title}
            // `min-w-0` so the card may size to its grid track. A grid item
            // defaults to `min-width: auto` — its min-CONTENT width — which
            // means one long unbroken value silently widens the whole track
            // and pushes the row past the panel.
            className="rounded-xl border border-border bg-card p-3.5 flex flex-col justify-between gap-1 min-w-0 shadow-sm hover:border-border-strong transition-colors"
          >
            <div className="flex items-start justify-between gap-2">
              {/*
                `truncate` used to hide the consequence of the squeeze rather
                than fix it — a card too narrow for "Indiranagar footfall"
                simply clipped it to "Indiran…". With a real minimum width the
                label has room, and on the rare long one it wraps by WORD:
                `break-words` sets overflow-wrap without touching word-break,
                so a long token can still break as a last resort but ordinary
                prose never breaks mid-word.
              */}
              <span className="text-xs font-semibold text-zinc-300 whitespace-normal break-words min-w-0 flex-1">
                {kpi.title}
              </span>
              {kpi.iconName ? (
                <span className="shrink-0">
                  <Icon icon={kpi.iconName as any} size="xsm" color="secondary" />
                </span>
              ) : null}
            </div>

            <div className="mt-2 flex flex-wrap items-baseline justify-between gap-x-2 gap-y-1 min-w-0 w-full">
              {/*
                `tabular-nums` so a streaming figure does not jitter as digits
                land, and the size step is a CONTAINER query — the panel's
                width decides whether there is room for the larger setting,
                which is the question `sm:` was answering with the window's.
              */}
              <span className="text-xl @xs/report:text-2xl font-bold tracking-tight text-white tabular-nums whitespace-nowrap shrink-0">
                {kpi.value}
              </span>
              {kpi.trend ? (
                <span
                  title={kpi.trend}
                  className={`text-xs font-bold truncate max-w-full min-w-0 ${
                    isUp ? 'text-emerald-400' : isDown ? 'text-rose-400' : 'text-zinc-300'
                  }`}
                >
                  {kpi.trend}
                </span>
              ) : null}
            </div>

            {kpi.sparkline ? (
              <div className="mt-2 pt-1 flex justify-end">
                <MiniSparkline data={kpi.sparkline} />
              </div>
            ) : null}
          </div>
        );
      })}
    </div>
  );
}
