'use client';

import {Grid} from '@astryxdesign/core/Grid';
import {AsyncBoundary} from '@/shared/components/data/AsyncBoundary';
import {MetricCard} from '@/shared/components/patterns/MetricCard';
import {SkeletonMetricGrid} from '@/shared/components/patterns/LoadingState';
import {ICONS} from '@/shared/utils/icons';
import {useBreakpoint, metricColumns} from '@/shared/hooks/useBreakpoint';
import {useLoyalyAi} from '@/features/loyaly-ai/providers/LoyalyAiProvider';
import {formatCompact, formatInrCompact} from '@/shared/utils/format';
import type {Kpi, KpiId} from '@/features/dashboard/types/dashboard';
import type {Resource} from '@/shared/hooks/useResource';
import type {IconType} from '@astryxdesign/core/Icon';

const KPI_ICON: Record<KpiId, IconType> = {
  visitors: ICONS.visitors,
  purchases: ICONS.purchases,
  revenue: ICONS.revenue,
  activeRewards: ICONS.activeRewards,
};

/**
 * Four KPIs must lay out 4-up, 2×2, or stacked — never 3+1, which reads as a
 * broken grid. `repeat: 'fit'` cannot express that: at a ~800px workspace it
 * yields exactly three columns whatever minWidth you choose, and the fourth
 * card drops to an orphan row.
 *
 * So the count is computed rather than inferred. The two things that decide
 * the available width are the breakpoint and whether the Loyaly AI panel is
 * taking 320–380px of it, and both are already known here.
 */
export function useMetricColumns(): number {
  const bp = useBreakpoint();
  const {isOpen} = useLoyalyAi();
  // The rule itself lives in lib/breakpoints alongside every other layout
  // threshold, so a breakpoint change is one edit rather than a hunt.
  return metricColumns(bp, isOpen);
}

export function KpiRow({resource}: {resource: Resource<Kpi[]>}) {
  const columns = useMetricColumns();

  return (
    <AsyncBoundary
      resource={resource}
      loading={<SkeletonMetricGrid columns={columns} />}
    >
      {(kpis) => (
        <Grid columns={columns} gap={4}>
          {kpis.map((k) => (
            <MetricCard
              key={k.id}
              label={k.label}
              value={k.value}
              format={k.unit === 'inr' ? formatInrCompact : formatCompact}
              icon={KPI_ICON[k.id]}
              deltaPct={k.deltaPct}
              isRiseGood={k.isRiseGood}
              trend={k.trend}
            />
          ))}
        </Grid>
      )}
    </AsyncBoundary>
  );
}
