import { Card, Group, SegmentedControl, Stack, Text, Title } from "@mantine/core";
import { useState } from "react";
import {
  Area,
  AreaChart,
  CartesianGrid,
  ResponsiveContainer,
  Tooltip,
  XAxis,
  YAxis,
} from "recharts";
import { usePromoTheme } from "@/routes/promo-code-campaigns/_components/appearance";
import styles from "@/routes/promo-code-campaigns/_components/promo.module.css";
import type { MemberDayPoint } from "@/lib/features/event-analytics/types";

type Metric = "points" | "events";

/**
 * The member's activity over time.
 *
 * Points lead because they are the metric this dataset actually carries — most
 * events have no amount, so a revenue chart here would be an empty axis. Events
 * are the alternative view rather than a second series: the two have unrelated
 * magnitudes (hundreds of points against a handful of events), and sharing one
 * axis would flatten whichever is smaller into the baseline.
 */
export default function MemberTimeline({ byDay }: { byDay: MemberDayPoint[] }) {
  const [metric, setMetric] = useState<Metric>("points");
  const { series } = usePromoTheme();
  const [color] = series(1);

  if (byDay.length === 0) {
    return (
      <Card className={styles.sectionCard} p="md">
        <Stack gap="xs">
          <Title order={5}>Activity over time</Title>
          <Text c="dimmed" size="sm">
            No dated events in this range.
          </Text>
        </Stack>
      </Card>
    );
  }

  const total = byDay.reduce((sum, d) => sum + d[metric], 0);

  return (
    <Card className={styles.sectionCard} p="md">
      <Stack gap="sm">
        <Group justify="space-between" align="center" wrap="wrap">
          <Stack gap={0}>
            <Title order={5}>Activity over time</Title>
            <Text size="xs" c="dimmed">
              {total.toLocaleString("en-US")} {metric} across {byDay.length} day
              {byDay.length === 1 ? "" : "s"}
            </Text>
          </Stack>
          <SegmentedControl
            size="xs"
            value={metric}
            onChange={(value) => setMetric(value as Metric)}
            data={[
              { value: "points", label: "Points" },
              { value: "events", label: "Events" },
            ]}
          />
        </Group>

        <ResponsiveContainer width="100%" height={220}>
          <AreaChart data={byDay} margin={{ left: 4, right: 12, top: 8 }}>
            <defs>
              <linearGradient id="memberTimelineFill" x1="0" y1="0" x2="0" y2="1">
                <stop offset="0%" stopColor={color.from} stopOpacity={0.45} />
                <stop offset="100%" stopColor={color.to} stopOpacity={0.04} />
              </linearGradient>
            </defs>
            <CartesianGrid strokeDasharray="3 3" vertical={false} opacity={0.4} />
            <XAxis
              dataKey="day"
              fontSize={11}
              tickLine={false}
              /* Day and month only: a full ISO date per tick overlaps at any
                 range wider than a fortnight. */
              tickFormatter={(day: string) => day.slice(5)}
              minTickGap={24}
            />
            <YAxis fontSize={11} tickLine={false} allowDecimals={false} width={40} />
            <Tooltip
              formatter={(value) => [
                Number(value).toLocaleString("en-US"),
                metric === "points" ? "Points" : "Events",
              ]}
            />
            <Area
              type="monotone"
              dataKey={metric}
              stroke={color.from}
              strokeWidth={2}
              fill="url(#memberTimelineFill)"
            />
          </AreaChart>
        </ResponsiveContainer>
      </Stack>
    </Card>
  );
}
