import type { CoreMemberDetailed } from "@/lib/features/members/types";
import { Badge, Group, Stack, Text, Title, Tooltip } from "@mantine/core";
import { useMemo, useState } from "react";
import { useNavigate } from "react-router";
import {
  MemberDataTable,
  type MemberColumn,
} from "@/routes/members/_components/MemberDataTable";
import { TableFilterDrawer } from "@/routes/members/_components/TableFilterDrawer";
import {
  accountStatusTone,
  recordStateTone,
} from "@/routes/members/_components/statusColors";

const MemberContacts: React.FC<{
  contacts: CoreMemberDetailed[];
  contactHrefBase?: string;
}> = ({ contacts, contactHrefBase }) => {
  const navigate = useNavigate();
  const [search, setSearch] = useState("");
  const [ownership, setOwnership] = useState<string[]>([]);
  const [statuses, setStatuses] = useState<string[]>([]);

  const statusOptions = useMemo(
    () =>
      Array.from(
        new Set(
          contacts
            .map((contact) => contact.account_status_name)
            .filter((name): name is string => Boolean(name)),
        ),
      ).map((name) => ({ value: name, label: name })),
    [contacts],
  );

  const filtered = useMemo(() => {
    const term = search.trim().toLowerCase();
    return contacts.filter((contact) => {
      const role = contact.is_primary
        ? "primary"
        : contact.is_owner
          ? "owner"
          : contact.is_family
            ? "family"
            : "contact";
      if (ownership.length && !ownership.includes(role)) return false;
      if (
        statuses.length &&
        !statuses.includes(contact.account_status_name ?? "")
      ) {
        return false;
      }
      if (!term) return true;
      return [
        contact.member_number,
        contact.first_name,
        contact.last_name,
        contact.email,
        contact.account_type_name,
      ]
        .filter(Boolean)
        .some((value) => String(value).toLowerCase().includes(term));
    });
  }, [contacts, search, ownership, statuses]);

  const handleRowClick = (row: CoreMemberDetailed) => {
    if (!row?.member_id) return;
    if (contactHrefBase) {
      navigate(`${contactHrefBase}/${row.member_number}`);
    } else {
      navigate(`${row.member_number}`);
    }
  };

  return (
    <Stack px={28} gap={12}>
      <Group justify="space-between" align="center">
        <Group gap={8} align="baseline">
          <Title order={6}>Members</Title>
          <Text fz={12} c="dimmed">
            {filtered.length} of {contacts.length}
          </Text>
        </Group>
        <TableFilterDrawer
          title="Filter Members"
          search={search}
          onSearchChange={setSearch}
          searchDescription="Name, email, member number"
          filters={[
            {
              key: "ownership",
              label: "Ownership",
              data: [
                { value: "primary", label: "Primary Contact" },
                { value: "owner", label: "Legal Owner" },
                { value: "family", label: "Family" },
                { value: "contact", label: "Contact" },
              ],
              value: ownership,
              onChange: setOwnership,
            },
            {
              key: "status",
              label: "Account Status",
              data: statusOptions,
              value: statuses,
              onChange: setStatuses,
            },
          ]}
        />
      </Group>
      <MemberDataTable
        rows={filtered}
        columns={columns}
        minWidth={1300}
        rowKey={(row, index) => `${row.member_number ?? index}`}
        onRowClick={handleRowClick}
        // Unregistered contacts have no detail page to open.
        rowStyle={(row) =>
          row.member_id ? undefined : { cursor: "not-allowed" }
        }
        emptyMessage="No contacts found"
      />
    </Stack>
  );
};

export default MemberContacts;

const Unregistered = ({
  memberId,
  children,
}: {
  memberId: string | null;
  children: React.ReactNode;
}) => (
  <Tooltip
    label="Member is not registered with the new system."
    disabled={memberId !== null}
  >
    <Text fz="sm">{children}</Text>
  </Tooltip>
);

const columns: MemberColumn<CoreMemberDetailed>[] = [
  {
    key: "member_number",
    header: "Member Id",
    render: (row) => (
      <Unregistered memberId={row.member_id}>
        <Text fz="sm" fw={600} component="span">
          {row.member_number}
        </Text>
      </Unregistered>
    ),
  },
  {
    key: "first_name",
    header: "First Name",
    render: (row) => (
      <Unregistered memberId={row.member_id}>{row.first_name}</Unregistered>
    ),
  },
  {
    key: "last_name",
    header: "Last Name",
    render: (row) => (
      <Unregistered memberId={row.member_id}>{row.last_name}</Unregistered>
    ),
  },
  {
    key: "email",
    header: "Email Address",
    render: (row) => (
      <Unregistered memberId={row.member_id}>{row.email}</Unregistered>
    ),
  },
  {
    key: "ownership",
    header: "Ownership Type",
    render: (row) => (
      <Badge
        {...recordStateTone(true)}
        size="sm"
        radius={4}
        tt="uppercase"
        fz={10}
        fw={600}
      >
        {row.is_owner ? "legal owner" : row.is_family ? "family" : "contact"}
      </Badge>
    ),
  },
  {
    key: "account_status",
    header: "Account Status",
    render: (row) => (
      <Badge
        {...accountStatusTone(row.account_status_name)}
        radius={4}
        tt="capitalize"
      >
        {row.account_status_name?.toLowerCase() ?? "NA"}
      </Badge>
    ),
  },
  {
    key: "record_state",
    header: "Record",
    render: (row) => (
      <Group gap={4}>
        <Badge {...recordStateTone(row.is_active)} size="sm" tt="capitalize">
          {row.is_active ? "active" : "inactive"}
        </Badge>
        {row.member_id ? null : (
          <Badge variant="light" color="gray" size="sm">
            unregistered
          </Badge>
        )}
      </Group>
    ),
  },
];
