'use client';

/**
 * Dev-only chart gallery.
 *
 * Every primitive is exercised here against the REAL route handlers, not
 * inline arrays — so this page simultaneously proves the charts render, the
 * data layer round-trips, and the loading/empty/error skins are correct.
 * Use the state buttons to force each branch.
 */

import {useState} from 'react';
import {VStack, HStack} from '@astryxdesign/core/Layout';
import {Grid} from '@astryxdesign/core/Grid';
import {Card} from '@astryxdesign/core/Card';
import {Heading, Text} from '@astryxdesign/core/Text';
import {Button} from '@astryxdesign/core/Button';
import {Badge} from '@astryxdesign/core/Badge';
import {useResource} from '@/shared/hooks/useResource';
import {dashboardRepository} from '@/features/dashboard/repositories/dashboardRepository';
import {ChartCard} from '@/shared/components/charts/ChartCard';
import {LineChartView} from '@/shared/components/charts/LineChartView';
import {AreaChartView} from '@/shared/components/charts/AreaChartView';
import {BarChartView} from '@/shared/components/charts/BarChartView';
import {Sparkline} from '@/shared/components/charts/Sparkline';
import {HeatmapGrid} from '@/shared/components/charts/HeatmapGrid';
import type {HourCell, Kpi, TimePoint} from '@/features/dashboard/types/dashboard';
import {
  formatCompact,
  formatDayLabel,
  formatDelta,
  formatInrCompact,
  formatPct,
} from '@/shared/utils/format';

type Forced = '' | 'empty' | 'error' | 'delay';

export default function ChartsGallery() {
  const [forced, setForced] = useState<Forced>('');

  // The forced state is folded into the endpoint params, so it becomes part of
  // the request identity and useResource refetches when it changes.
  const extra =
    forced === 'delay'
      ? {_delay: '4000'}
      : forced
        ? {_state: forced}
        : {};

  const scope = {range: '30d' as const, storeId: 'all'};
  const withExtra = <T,>(e: {path: string; params: Record<string, string>}) =>
    ({...e, params: {...e.params, ...extra}}) as never as T;

  const series = useResource<TimePoint[]>(
    withExtra(dashboardRepository.timeseries(scope)),
  );
  const kpis = useResource<Kpi[]>(withExtra(dashboardRepository.kpis(scope)));
  const peak = useResource<HourCell[]>(
    withExtra(dashboardRepository.peakHours(scope)),
  );

  return (
    <VStack gap={6} padding={6}>
      <VStack gap={2}>
        <Heading level={1}>Chart primitives</Heading>
        <Text color="secondary">
          Monochrome by construction. Series beyond the second are separated by
          dash pattern and hatch fill, never hue — semantic colour is reserved
          for thresholds and deltas.
        </Text>
        <HStack gap={2} wrap="wrap">
          {(
            [
              ['', 'Live data'],
              ['delay', 'Loading (4s)'],
              ['empty', 'Empty'],
              ['error', 'Error'],
            ] as [Forced, string][]
          ).map(([v, label]) => (
            <Button
              key={label}
              size="sm"
              variant={forced === v ? 'primary' : 'secondary'}
              label={label}
              onClick={() => setForced(v)}
            />
          ))}
        </HStack>
      </VStack>

      {/* KPI sparklines — never animated, semantic tone on the delta only. */}
      <Grid columns={{minWidth: 220, repeat: 'fit'}} gap={4}>
        {kpis.status === 'success'
          ? kpis.data.map((k) => (
              <Card key={k.id}>
                <VStack gap={2}>
                  <Text size="sm" color="secondary">
                    {k.label}
                  </Text>
                  <HStack gap={2} vAlign="center" hAlign="between">
                    <Heading level={3}>
                      {k.unit === 'inr'
                        ? formatInrCompact(k.value)
                        : formatCompact(k.value)}
                    </Heading>
                    <Badge
                      variant={
                        k.deltaPct === 0
                          ? 'neutral'
                          : k.deltaPct > 0 === k.isRiseGood
                            ? 'success'
                            : 'error'
                      }
                      label={formatDelta(k.deltaPct)}
                    />
                  </HStack>
                  <Sparkline
                    data={k.trend}
                    dataKey="v"
                    tone={
                      k.deltaPct === 0
                        ? 'neutral'
                        : k.deltaPct > 0 === k.isRiseGood
                          ? 'positive'
                          : 'negative'
                    }
                  />
                </VStack>
              </Card>
            ))
          : null}
      </Grid>

      <Grid columns={{minWidth: 420, repeat: 'fit'}} gap={4}>
        <ChartCard
          title="Footfall"
          subtitle="Visitors per day"
          resource={series}
        >
          {(d) => (
            <AreaChartView
              data={d}
              xKey="t"
              xFormat={formatDayLabel}
              yFormat={formatCompact}
              series={[{key: 'visitors', label: 'Visitors'}]}
            />
          )}
        </ChartCard>

        <ChartCard
          title="Visitors vs purchases"
          subtitle="Two series — solid and dashed, same ramp"
          resource={series}
        >
          {(d) => (
            <LineChartView
              data={d}
              xKey="t"
              xFormat={formatDayLabel}
              yFormat={formatCompact}
              series={[
                {key: 'visitors', label: 'Visitors'},
                {key: 'purchases', label: 'Purchases'},
              ]}
            />
          )}
        </ChartCard>

        <ChartCard
          title="Revenue"
          subtitle="Bars, with a target reference line"
          resource={series}
        >
          {(d) => (
            <BarChartView
              data={d}
              xKey="t"
              xFormat={formatDayLabel}
              yFormat={formatInrCompact}
              series={[{key: 'revenue', label: 'Revenue'}]}
              reference={{y: 90000, label: 'Daily target', tone: 'positive'}}
            />
          )}
        </ChartCard>

        <ChartCard
          title="Three series"
          subtitle="The encoding test: luminance, then hatch — never hue"
          resource={series}
        >
          {(d) => (
            <BarChartView
              // Three series only tells you anything if they share a scale, so
              // this splits visitors into who bought and who didn't rather
              // than mixing a percentage onto a counts axis.
              data={d.slice(-10).map((p) => ({
                t: p.t,
                purchases: p.purchases,
                browsed: p.visitors - p.purchases,
                repeat: Math.round(p.purchases * 0.42),
              }))}
              xKey="t"
              xFormat={formatDayLabel}
              yFormat={formatCompact}
              series={[
                {key: 'browsed', label: 'Browsed only'},
                {key: 'purchases', label: 'Purchased'},
                {key: 'repeat', label: 'Repeat customers'},
              ]}
            />
          )}
        </ChartCard>

        <ChartCard
          title="Conversion"
          subtitle="Dotted third encoding at line scale"
          resource={series}
        >
          {(d) => (
            <LineChartView
              data={d}
              xKey="t"
              xFormat={formatDayLabel}
              yFormat={(v) => formatPct(v, 0)}
              series={[{key: 'conversion', label: 'Conversion'}]}
              reference={{y: 22, label: 'Benchmark'}}
            />
          )}
        </ChartCard>

        <ChartCard
          title="Peak hours"
          subtitle="CSS grid, not recharts — monochrome by construction"
          resource={peak}
          height={200}
        >
          {(d) => <HeatmapGrid data={d} />}
        </ChartCard>
      </Grid>
    </VStack>
  );
}
