"use client";

/**
 * Every account currently in a deletion status, one row each.
 *
 * Read from the member database rather than from this console's own records. An
 * account moved to Invalid directly in Viewpoint is retired whether or not this
 * system did it, and leaving those off the list is how a closure goes unnoticed —
 * the member has been cut off, no acknowledgement went out, and no data-deletion
 * email is scheduled, because nothing here knows it happened.
 *
 * That is what the source column is for. It is the difference between a closure this
 * console can account for and one it merely observed.
 *
 * One row per account, not per member: a household of four shares a membership
 * number and is one retirement, not four.
 */

import {
  ActionIcon,
  Anchor,
  Badge,
  Card,
  Group,
  Pagination,
  Skeleton,
  Stack,
  Table,
  Text,
  TextInput,
  Tooltip,
} from "@mantine/core";
import {
  IconAlertTriangle,
  IconClock,
  IconRefresh,
  IconSearch,
  IconUserOff,
} from "@tabler/icons-react";
import { useCallback, useEffect, useState } from "react";
import { Link } from "react-router";
import {
  listRetiredAccounts,
  type EdmStatus,
  type RetiredAccount,
} from "@/lib/features/account-deletion/query";
import styles from "@/routes/promo-code-campaigns/_components/promo.module.css";

const PAGE_SIZE = 15;

const EDM_TONE: Record<EdmStatus, string> = {
  sent: "green",
  pending: "gray",
  skipped: "yellow",
  cancelled: "blue",
  failed: "red",
};

const REGION_LABEL: Record<string, string> = {
  uk: "UK",
  europe: "Europe",
  india: "India",
  indonesia: "Indonesia",
  others: "Rest of world",
};

const formatDay = (value: string | null): string => {
  if (!value) return "—";
  const parsed = new Date(value);
  return Number.isFinite(parsed.getTime()) ? parsed.toLocaleDateString() : "—";
};

const daysUntil = (iso: string | null): number | null => {
  if (!iso) return null;
  const due = new Date(iso).getTime();
  if (!Number.isFinite(due)) return null;
  return Math.max(0, Math.ceil((due - Date.now()) / (24 * 60 * 60 * 1000)));
};

const RetiredAccountsTable: React.FC<{ refreshToken?: number }> = ({
  refreshToken = 0,
}) => {
  const [items, setItems] = useState<RetiredAccount[]>([]);
  const [total, setTotal] = useState(0);
  const [page, setPage] = useState(1);
  const [search, setSearch] = useState("");
  const [applied, setApplied] = useState("");
  const [loading, setLoading] = useState(true);

  const load = useCallback(async () => {
    setLoading(true);
    const response = await listRetiredAccounts({
      page,
      pageSize: PAGE_SIZE,
      search: applied || undefined,
    });
    if (response.success && response.data) {
      setItems(response.data.items);
      setTotal(response.data.pagination.total);
    } else {
      setItems([]);
      setTotal(0);
    }
    setLoading(false);
  }, [applied, page]);

  useEffect(() => {
    void load();
  }, [load, refreshToken]);

  const pageCount = Math.max(1, Math.ceil(total / PAGE_SIZE));
  const externalCount = items.filter(
    (item) => item.source === "external",
  ).length;

  return (
    <Card className={styles.sectionCard} p="md">
      <Stack gap="sm">
        <Group justify="space-between" align="flex-end">
          <Group gap="xs">
            <IconUserOff size={18} />
            <Text fw={600}>Retired accounts</Text>
            <Badge variant="light" color="gray">
              {total}
            </Badge>
          </Group>
          <Group gap="xs">
            <TextInput
              placeholder="Account number or name"
              leftSection={<IconSearch size={14} />}
              value={search}
              onChange={(event) => setSearch(event.currentTarget.value)}
              onKeyDown={(event) => {
                if (event.key === "Enter") {
                  // Page reset on a new term: staying on page 3 of a narrower result
                  // set shows an empty table for a search that matched.
                  setPage(1);
                  setApplied(search.trim());
                }
              }}
              w={280}
            />
            <ActionIcon
              variant="default"
              onClick={() => void load()}
              aria-label="Refresh"
            >
              <IconRefresh size={16} />
            </ActionIcon>
          </Group>
        </Group>

        {loading ? (
          <Skeleton height={240} radius="md" />
        ) : items.length === 0 ? (
          <Text size="sm" c="dimmed" ta="center" py="lg">
            No account is currently in a deletion status.
          </Text>
        ) : (
          <Table highlightOnHover>
            <Table.Thead className={styles.tableHead}>
              <Table.Tr>
                <Table.Th className={styles.th}>Account</Table.Th>
                <Table.Th className={styles.th}>Status</Table.Th>
                <Table.Th className={styles.th}>Retired by</Table.Th>
                <Table.Th className={styles.th}>Acknowledgement</Table.Th>
                <Table.Th className={styles.th}>Data-deletion</Table.Th>
                <Table.Th className={styles.th}>Reason</Table.Th>
              </Table.Tr>
            </Table.Thead>
            <Table.Tbody>
              {items.map((item) => {
                const record = item.record;
                const remaining =
                  record?.followupEdmStatus === "pending"
                    ? daysUntil(record.followupDueAt)
                    : null;

                return (
                  <Table.Tr key={item.accountNumber}>
                    <Table.Td>
                      <Stack gap={0}>
                        <Anchor
                          component={Link}
                          to={`/admin/members/${item.accountNumber}?tab=deletion`}
                          size="sm"
                          fw={500}
                        >
                          {item.accountNumber}
                        </Anchor>
                        <Group gap={4}>
                          <Text size="xs" c="dimmed">
                            {item.name ?? "—"}
                          </Text>
                          {item.memberCount > 1 && (
                            <Text size="xs" c="dimmed">
                              · {item.memberCount} members
                            </Text>
                          )}
                          {record?.region && (
                            <Badge size="xs" variant="outline" color="gray">
                              {REGION_LABEL[record.region] ?? record.region}
                            </Badge>
                          )}
                        </Group>
                      </Stack>
                    </Table.Td>

                    <Table.Td>
                      <Badge color="red" variant="light">
                        {item.statusName}
                      </Badge>
                    </Table.Td>

                    <Table.Td>
                      {item.source === "console" ? (
                        <Stack gap={0}>
                          <Text size="sm">{record?.performedBy ?? "—"}</Text>
                          <Text size="xs" c="dimmed">
                            {formatDay(record?.createdAt ?? null)}
                          </Text>
                        </Stack>
                      ) : (
                        <Tooltip
                          label="This account is in a deletion status but was not retired through this console — most likely changed directly in Viewpoint. No emails were sent for it."
                          multiline
                          w={300}
                        >
                          <Badge
                            color="orange"
                            variant="light"
                            leftSection={<IconAlertTriangle size={11} />}
                          >
                            outside this console
                          </Badge>
                        </Tooltip>
                      )}
                    </Table.Td>

                    <Table.Td>
                      {record ? (
                        <Badge
                          variant="light"
                          color={EDM_TONE[record.noticeEdmStatus]}
                        >
                          {record.noticeEdmStatus}
                        </Badge>
                      ) : (
                        <Text size="xs" c="dimmed">
                          not sent
                        </Text>
                      )}
                    </Table.Td>

                    <Table.Td>
                      {record ? (
                        <Group gap={6}>
                          <Badge
                            variant="light"
                            color={EDM_TONE[record.followupEdmStatus]}
                          >
                            {record.followupEdmStatus}
                          </Badge>
                          {remaining !== null && (
                            <Badge
                              size="xs"
                              variant="light"
                              color="orange"
                              leftSection={<IconClock size={10} />}
                            >
                              {remaining}d
                            </Badge>
                          )}
                        </Group>
                      ) : (
                        <Text size="xs" c="dimmed">
                          not scheduled
                        </Text>
                      )}
                    </Table.Td>

                    <Table.Td>
                      <Text size="xs" c="dimmed" lineClamp={2} maw={260}>
                        {record?.reason ?? "—"}
                      </Text>
                    </Table.Td>
                  </Table.Tr>
                );
              })}
            </Table.Tbody>
          </Table>
        )}

        {pageCount > 1 && (
          <Group justify="flex-end">
            <Pagination value={page} onChange={setPage} total={pageCount} />
          </Group>
        )}
      </Stack>
    </Card>
  );
};

export default RetiredAccountsTable;
