"use client";

/**
 * Overview strip on the member account page: booking mix and most-booked
 * and the signup promo code, using the promo module's tiles and donut so the
 * page matches the campaign dashboards.
 */

import type { CoreAccountOverview } from "@/lib/features/members/query";
import {
  Badge,
  Card,
  Group,
  SegmentedControl,
  Stack,
  Text,
} from "@mantine/core";
import {
  IconBuildingCommunity,
  IconTicket,
  IconUsers,
} from "@tabler/icons-react";
import moment from "moment";
import { useMemo, useState } from "react";
import { usePromoTheme } from "@/routes/promo-code-campaigns/_components/appearance";
import { BreakdownPanel } from "@/routes/promo-code-campaigns/_components/BreakdownPanel";
import { StatTiles } from "@/routes/promo-code-campaigns/_components/StatTiles";
import { CountryCampaignBars } from "@/routes/promo-code-campaigns/_components/charts/CountryCampaignBars";

export function AccountOverview({
  overview,
}: {
  overview?: CoreAccountOverview;
}) {
  const theme = usePromoTheme();
  const bookings = overview?.bookings;
  const totalBookings =
    (bookings?.internal ?? 0) +
    (bookings?.external ?? 0) +
    (bookings?.curated ?? 0);
  const lastSession = overview?.lastSession;

  const tiles = useMemo(() => {
    const series = theme.series(4);
    return [
      {
        key: "bookings",
        label: "Bookings",
        value: totalBookings,
        icon: <IconBuildingCommunity size={18} />,
        color: series[0].solid,
        colorTo: series[0].to,
        hint: bookings
          ? `${bookings.internal} internal · ${bookings.external} external · ${bookings.curated} curated`
          : undefined,
      },
      {
        key: "members",
        label: "Total Members",
        value: overview?.emails?.contacts ?? 0,
        icon: <IconUsers size={18} />,
        color: series[2].solid,
        colorTo: series[2].to,
        hint: overview?.emails
          ? `${overview.emails.unique.length} unique email(s)`
          : undefined,
      },
    ];
  }, [theme, bookings, totalBookings, overview]);

  const breakdowns = useMemo(() => {
    const roles = theme.roles;
    return [
      {
        key: "bookingMix",
        label: "Booking Mix",
        unit: "booking",
        centerLabel: "bookings",
        slices: [
          {
            name: "Internal Property",
            value: bookings?.internal ?? 0,
            color: roles.internal.solid,
            colorTo: roles.internal.to,
          },
          {
            name: "External (RCI)",
            value: bookings?.external ?? 0,
            color: theme.series(3)[1].solid,
            colorTo: theme.series(3)[1].to,
          },
          {
            name: "Curated Events",
            value: bookings?.curated ?? 0,
            color: roles.external.solid,
            colorTo: roles.external.to,
          },
        ],
      },
    ];
  }, [theme, bookings]);

  /*
   * Where this account actually books.
   *
   * One chart with a type switch rather than three columns: the columns were
   * narrow, truncated resort names, and invited comparison across scales that
   * don't compare. This keeps one full-width scale per view.
   */
  const [entityKind, setEntityKind] = useState<
    "internal" | "external" | "curated"
  >("internal");

  const entityKinds = useMemo(() => {
    const entities = overview?.topEntities ?? [];
    return [
      {
        value: "internal" as const,
        label: "Internal",
        color: theme.roles.internal,
        rows: entities.filter((row) => row.kind === "internal"),
      },
      {
        value: "external" as const,
        label: "External",
        color: theme.series(3)[1],
        rows: entities.filter((row) => row.kind === "external"),
      },
      {
        value: "curated" as const,
        label: "Curated",
        color: theme.roles.external,
        rows: entities.filter((row) => row.kind === "curated"),
      },
    ];
  }, [overview, theme]);

  const activeKind =
    entityKinds.find((entry) => entry.value === entityKind) ?? entityKinds[0];
  const activeRows = (activeKind?.rows ?? []).slice(0, 8);
  const maxEntityBookings = Math.max(
    1,
    ...activeRows.map((row) => row.bookings),
  );
  const hasEntities = entityKinds.some((entry) => entry.rows.length > 0);
  const [hoveredEntity, setHoveredEntity] = useState<number | null>(null);

  return (
    <Stack gap="md" px={28}>
      <StatTiles tiles={tiles} loading={!overview} />

      <Group gap={8} wrap="wrap">
        {overview?.promoCodes?.length ? (
          overview.promoCodes.map((code) => (
            <Badge
              key={code}
              variant="light"
              radius={4}
              leftSection={<IconTicket size={12} />}
            >
              {code}
            </Badge>
          ))
        ) : (
          <Text fz={12} c="dimmed">
            No signup promo code on this account
          </Text>
        )}
      </Group>

      {totalBookings > 0 && (
        <BreakdownPanel breakdowns={breakdowns} loading={!overview} />
      )}

      {hasEntities ? (
        <Card withBorder radius="lg" p="md">
          <Group justify="space-between" align="center" mb={4}>
            <Text fw={600} fz={14}>
              Most booked
            </Text>
            <SegmentedControl
              size="xs"
              value={entityKind}
              onChange={(value) =>
                setEntityKind(value as "internal" | "external" | "curated")
              }
              data={entityKinds.map((entry) => ({
                value: entry.value,
                label: `${entry.label} (${entry.rows.length})`,
              }))}
            />
          </Group>
          <Text fz={12} c="dimmed" mb="sm">
            Top resorts and events for this account.
          </Text>

          {activeRows.length === 0 ? (
            <Text fz="sm" c="dimmed" py={12}>
              No {activeKind?.label.toLowerCase()} bookings on this account.
            </Text>
          ) : (
            /* Same chart as "Signups by Country" on the promo-code page —
               shared so a bar means the same thing in both places. */
            <CountryCampaignBars
              data={activeRows.map((row) => ({
                entity: row.name,
                Bookings: row.bookings,
              }))}
              series={[
                {
                  key: "bookings",
                  name: "Bookings",
                  color:
                    activeKind?.color.from ?? activeKind?.color.solid ?? "",
                  colorTo: activeKind?.color.to,
                },
              ]}
              xKey="entity"
              height={260}
              hoveredIndex={hoveredEntity}
              onHoverIndex={setHoveredEntity}
            />
          )}
        </Card>
      ) : null}
    </Stack>
  );
}
