"use client";

/**
 * Accounts dashboard: the promo module's own KPI tiles, donut breakdowns and
 * country chart, fed by the member DB.
 *
 * Components are imported from the promo module rather than reimplemented — the
 * colours come from `usePromoTheme().series()`, so the charts recolour with the
 * accent exactly like the campaign pages do.
 */

import { Badge, Box, Card, Group, Skeleton, Stack, Text } from "@mantine/core";
import {
  IconCalendarEvent,
  IconChartPie,
  IconIdBadge2,
  IconUsers,
  IconWorld,
} from "@tabler/icons-react";
import { useMemo } from "react";
import { usePromoTheme } from "@/routes/promo-code-campaigns/_components/appearance";
import { BreakdownPanel } from "@/routes/promo-code-campaigns/_components/BreakdownPanel";
import { CountryBreakdownBarChart } from "@/routes/promo-code-campaigns/_components/CountryBreakdownBarChart";
import { StatTiles } from "@/routes/promo-code-campaigns/_components/StatTiles";
import styles from "@/routes/promo-code-campaigns/_components/promo.module.css";

export interface MemberAnalytics {
  totals: {
    accounts: number;
    members: number;
    active: number;
    inactive: number;
  };
  bookings: {
    total: number;
    internal: number;
    external: number;
    curated: number;
  };
  byAccountType: { id: string; name: string; count: number }[];
  byAccountStatus: { id: string; name: string; count: number }[];
  byCountry: {
    country: string;
    accountTypeId: string;
    accountTypeName: string;
    count: number;
  }[];
}

export function MemberAnalyticsSection({
  analytics,
}: {
  analytics?: MemberAnalytics;
}) {
  const theme = usePromoTheme();

  const totals = analytics?.totals;
  const bookings = analytics?.bookings;
  const types = analytics?.byAccountType ?? [];
  const statuses = analytics?.byAccountStatus ?? [];
  const countries = analytics?.byCountry ?? [];

  const tiles = useMemo(() => {
    const series = theme.series(5);
    return [
      {
        key: "members",
        label: "Karma Subito Users",
        value: totals?.members ?? 0,
        icon: <IconUsers size={18} />,
        color: series[0].solid,
        colorTo: series[0].to,
        hint: "Contacts registered in the app",
      },
      {
        key: "accounts",
        label: "Viewpoint Accounts",
        value: totals?.accounts ?? 0,
        icon: <IconIdBadge2 size={18} />,
        color: series[1].solid,
        colorTo: series[1].to,
        hint: "Distinct membership numbers",
      },
      {
        key: "bookings",
        label: "Total Bookings",
        value: bookings?.total ?? 0,
        icon: <IconCalendarEvent size={18} />,
        color: series[2].solid,
        colorTo: series[2].to,
        hint: bookings
          ? `${bookings.internal.toLocaleString()} internal · ${bookings.external.toLocaleString()} external · ${bookings.curated.toLocaleString()} curated`
          : "Internal, external and curated",
      },
      {
        key: "countries",
        label: "Countries",
        value: new Set(countries.map((row) => row.country)).size,
        icon: <IconWorld size={18} />,
        color: series[4].solid,
        colorTo: series[4].to,
        hint: "With at least one member profile",
      },
    ];
  }, [theme, totals, bookings, countries]);

  const breakdowns = useMemo(() => {
    // One palette per ring so the slices sit in the accent's fan.
    const typeColors = theme.series(Math.max(1, types.length));
    const statusColors = theme.series(Math.max(1, statuses.length));

    return [
      {
        key: "accountType",
        label: "By Account Type",
        unit: "member",
        centerLabel: "members",
        slices: types.map((row, index) => ({
          name: row.name,
          value: row.count,
          id: row.id,
          color: typeColors[index % typeColors.length].solid,
          colorTo: typeColors[index % typeColors.length].to,
        })),
      },
      {
        key: "accountStatus",
        label: "By Account Status",
        unit: "member",
        centerLabel: "members",
        slices: statuses.map((row, index) => ({
          name: row.name,
          value: row.count,
          id: row.id,
          color: statusColors[index % statusColors.length].solid,
          colorTo: statusColors[index % statusColors.length].to,
        })),
      },
      {
        key: "bookingMix",
        label: "Bookings",
        unit: "booking",
        centerLabel: "bookings",
        // Same role colours the promo bookings donut uses, so internal and
        // external read the same across both dashboards.
        slices: [
          {
            name: "Internal Property",
            value: bookings?.internal ?? 0,
            color: theme.roles.internal.solid,
            colorTo: theme.roles.internal.to,
          },
          {
            name: "External (RCI)",
            value: bookings?.external ?? 0,
            color: theme.roles.external.solid,
            colorTo: theme.roles.external.to,
          },
          {
            name: "Curated Events",
            value: bookings?.curated ?? 0,
            color: theme.muted.solid,
            colorTo: theme.muted.to,
          },
        ],
      },
    ];
  }, [theme, types, statuses, bookings]);

  // The country chart is entity-oriented (one series per entity); for members
  // the entities are account types, so the map and bars split the same way the
  // donut does.
  const entities = useMemo(
    () => types.map((row) => ({ id: row.id, name: row.name })),
    [types],
  );
  const countryRows = useMemo(
    () =>
      countries.map((row) => ({
        country: row.country,
        id: row.accountTypeId,
        signups: row.count,
      })),
    [countries],
  );

  return (
    // Same composition as the campaigns page: KPI row in its own Box, then one
    // bordered Analytics card holding the breakdowns and the country chart,
    // split by the gradient rule.
    <Stack gap={0}>
      <Box mb="md">
        <StatTiles tiles={tiles} loading={!analytics} />
      </Box>

      <Card withBorder radius="lg" p="md" mb="md">
        <Group justify="space-between" align="center" mb="md">
          <Group gap={8} align="center">
            <IconChartPie size={17} stroke={1.8} />
            <Text fw={700} size="md">
              Analytics
            </Text>
          </Group>
          <Badge variant="light" size="md" radius="sm">
            {(totals?.members ?? 0).toLocaleString()} TOTAL MEMBERS
          </Badge>
        </Group>

        <BreakdownPanel breakdowns={breakdowns} loading={!analytics} />

        <hr className={styles.gradientRule} />
        <Box mt="md" pt="md">
          {!analytics ? (
            <Skeleton height={240} radius="md" />
          ) : countryRows.length > 0 ? (
            <CountryBreakdownBarChart
              title="Members by Country"
              entities={entities}
              rows={countryRows}
              totalBadgeLabel="members"
            />
          ) : (
            <Text c="dimmed" ta="center" py={20}>
              No country data on member profiles yet.
            </Text>
          )}
        </Box>
      </Card>
    </Stack>
  );
}
