import React, { useEffect, useMemo, useState } from "react";
import { Drawer, Tabs, Table, Text, Center, Loader, Group, Avatar, Box, Stack, Flex, TextInput, Pagination, Badge } from "@mantine/core";
import { IconSearch } from "@tabler/icons-react";
import { format } from "date-fns";
import type { Manager } from "../../../lib/features/points-transfer/types";
import { NotesCell } from "./NotesCell";
import { PageSizeSelect } from "./PageSizeSelect";
import { useIsMobile } from "@/hooks/useIsMobile";

interface HistoryDrawerProps {
  opened: boolean;
  onClose: () => void;
  manager: Manager | null;
  loading: boolean;
  data: { received: any[]; sent: any[] } | null;
}

const matches = (tx: any, fields: string[], query: string) => {
  const q = query.toLowerCase().trim();
  if (!q) return true;
  return fields.some((f) => String(tx[f] ?? "").toLowerCase().includes(q));
};

export function HistoryDrawer({ opened, onClose, manager, loading, data }: HistoryDrawerProps) {
  const isMobile = useIsMobile();
  const [receivedSearch, setReceivedSearch] = useState("");
  const [receivedPage, setReceivedPage] = useState(1);
  const [receivedLimit, setReceivedLimit] = useState(5);
  const [sentSearch, setSentSearch] = useState("");
  const [sentPage, setSentPage] = useState(1);
  const [sentLimit, setSentLimit] = useState(5);

  // Reset both tabs whenever the drawer is reopened for a different manager.
  useEffect(() => {
    setReceivedSearch("");
    setReceivedPage(1);
    setSentSearch("");
    setSentPage(1);
  }, [manager?.id, opened]);

  const filteredReceived = useMemo(
    () => (data?.received || []).filter((tx) =>
      matches(tx, ["source_holding_account", "notes", "points"], receivedSearch)),
    [data?.received, receivedSearch],
  );

  const filteredSent = useMemo(
    () => (data?.sent || []).filter((tx) =>
      matches(tx, ["target_first_name", "target_last_name", "target_email", "target_account_id", "target_contact_id", "notes", "points"], sentSearch)),
    [data?.sent, sentSearch],
  );

  const safeReceivedPage = Math.min(receivedPage, Math.ceil(filteredReceived.length / receivedLimit) || 1);
  const safeSentPage = Math.min(sentPage, Math.ceil(filteredSent.length / sentLimit) || 1);
  const pagedReceived = filteredReceived.slice((safeReceivedPage - 1) * receivedLimit, safeReceivedPage * receivedLimit);
  const pagedSent = filteredSent.slice((safeSentPage - 1) * sentLimit, safeSentPage * sentLimit);

  const renderToolbar = (
    title: string,
    count: number,
    value: string,
    onSearch: (v: string) => void,
    placeholder: string,
  ) => (
    <Flex
      direction={{ base: "column", sm: "row" }}
      justify="space-between"
      align={{ base: "stretch", sm: "center" }}
      gap="sm"
      mb="sm"
    >
      <Group gap="xs">
        <Text size="sm" fw={600}>{title}</Text>
        <Badge variant="light" color="gray" size="sm">{count}</Badge>
      </Group>
      <TextInput
        placeholder={placeholder}
        leftSection={<IconSearch size={14} />}
        value={value}
        onChange={(e) => onSearch(e.currentTarget.value)}
        size="xs"
        w={{ base: "100%", sm: 240 }}
      />
    </Flex>
  );

  const renderFooter = (
    total: number,
    page: number,
    onPage: (p: number) => void,
    limit: number,
    onLimit: (l: number) => void,
  ) => {
    if (total === 0) return null;
    const rangeStart = (page - 1) * limit + 1;
    const rangeEnd = Math.min(page * limit, total);
    return (
      <Flex
        direction={{ base: "column", sm: "row" }}
        justify="space-between"
        align="center"
        gap="sm"
        mt="md"
      >
        <Group gap="md" wrap="wrap">
          <Text size="sm" c="dimmed">Showing {rangeStart}–{rangeEnd} of {total}</Text>
          <PageSizeSelect value={limit} onChange={(v) => { onLimit(v); onPage(1); }} />
        </Group>
        <Pagination
          value={page}
          onChange={onPage}
          total={Math.ceil(total / limit)}
          size="sm"
          siblings={1}
          boundaries={1}
        />
      </Flex>
    );
  };

  return (
    <Drawer
      opened={opened}
      onClose={onClose}
      title={`Points Transfer History: ${manager?.first_name} ${manager?.last_name || ""}`}
      position="right"
      // The history tables already scroll horizontally; giving the drawer the
      // whole phone screen means less of that scrolling.
      size={isMobile ? "100%" : "xl"}
    >
      {loading ? (
        <Center py="xl">
          <Loader style={{ margin: "auto" }} />
        </Center>
      ) : !data ? (
        <Text size="sm" c="dimmed" ta="center" py="xl">No transaction history found for this manager.</Text>
      ) : (
        <Tabs defaultValue="received">
          <Tabs.List mb="md">
            <Tabs.Tab value="received">Transfers Received</Tabs.Tab>
            <Tabs.Tab value="sent">Transfers Sent</Tabs.Tab>
          </Tabs.List>

          <Tabs.Panel value="received">
            {renderToolbar(
              "Received from holding accounts",
              filteredReceived.length,
              receivedSearch,
              (v) => { setReceivedSearch(v); setReceivedPage(1); },
              "Search by account, points, notes...",
            )}
            <Table.ScrollContainer minWidth={520}>
              <Table striped highlightOnHover verticalSpacing="sm">
                <Table.Thead>
                  <Table.Tr>
                    <Table.Th>Date</Table.Th>
                    <Table.Th>Source Account</Table.Th>
                    <Table.Th>Points</Table.Th>
                    <Table.Th>Notes</Table.Th>
                  </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                  {pagedReceived.length === 0 ? (
                    <Table.Tr>
                      <Table.Td colSpan={4}>
                        <Text size="sm" c="dimmed" ta="center" py="lg">
                          {receivedSearch ? "No transfers match your search." : "No points received from holding accounts."}
                        </Text>
                      </Table.Td>
                    </Table.Tr>
                  ) : (
                    pagedReceived.map((tx: any) => (
                      <Table.Tr key={tx.id}>
                        <Table.Td>
                          <Text size="sm" style={{ whiteSpace: "nowrap" }}>{format(new Date(tx.created_at), "dd MMM yyyy HH:mm")}</Text>
                        </Table.Td>
                        <Table.Td><Text size="sm">{tx.source_holding_account}</Text></Table.Td>
                        <Table.Td fw={600} c="green" style={{ whiteSpace: "nowrap" }}>+{tx.points.toLocaleString()}</Table.Td>
                        <Table.Td><NotesCell value={tx.notes} maw={220} /></Table.Td>
                      </Table.Tr>
                    ))
                  )}
                </Table.Tbody>
              </Table>
            </Table.ScrollContainer>
            {renderFooter(filteredReceived.length, safeReceivedPage, setReceivedPage, receivedLimit, setReceivedLimit)}
          </Tabs.Panel>

          <Tabs.Panel value="sent">
            {renderToolbar(
              "Sent to members",
              filteredSent.length,
              sentSearch,
              (v) => { setSentSearch(v); setSentPage(1); },
              "Search by name, email, account, notes...",
            )}
            <Table.ScrollContainer minWidth={680}>
              <Table striped highlightOnHover verticalSpacing="sm">
                <Table.Thead>
                  <Table.Tr>
                    <Table.Th>Date</Table.Th>
                    <Table.Th>Transfer To</Table.Th>
                    <Table.Th>Account / Contact ID</Table.Th>
                    <Table.Th>Points</Table.Th>
                    <Table.Th>Notes</Table.Th>
                  </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                  {pagedSent.length === 0 ? (
                    <Table.Tr>
                      <Table.Td colSpan={5}>
                        <Text size="sm" c="dimmed" ta="center" py="lg">
                          {sentSearch ? "No transfers match your search." : "No points transferred to members."}
                        </Text>
                      </Table.Td>
                    </Table.Tr>
                  ) : (
                    pagedSent.map((tx: any) => (
                      <Table.Tr key={tx.id}>
                        <Table.Td>
                          <Text size="sm" style={{ whiteSpace: "nowrap" }}>{format(new Date(tx.created_at), "dd MMM yyyy HH:mm")}</Text>
                        </Table.Td>
                        <Table.Td>
                          {tx.target_first_name ? (
                            <Group gap="xs" wrap="nowrap">
                              <Avatar size={28} radius="xl" color="blue" variant="light">
                                {`${tx.target_first_name?.[0] || ""}${tx.target_last_name?.[0] || ""}`.toUpperCase()}
                              </Avatar>
                              <Box style={{ minWidth: 0 }}>
                                <Text size="sm" fw={500} truncate>{tx.target_first_name} {tx.target_last_name}</Text>
                                {tx.target_email && <Text size="sm" c="dimmed" truncate>{tx.target_email}</Text>}
                              </Box>
                            </Group>
                          ) : (
                            <Text size="sm" c="dimmed">-</Text>
                          )}
                        </Table.Td>
                        <Table.Td>
                          {tx.target_account_id ? (
                            <Stack gap={0}>
                              <Text size="sm" fw={500}>Acc: {tx.target_account_id}</Text>
                              <Text size="sm" c="dimmed">Contact: {tx.target_contact_id}</Text>
                            </Stack>
                          ) : (
                            <Text size="sm" c="dimmed">Not linked</Text>
                          )}
                        </Table.Td>
                        <Table.Td fw={600} c="red" style={{ whiteSpace: "nowrap" }}>-{tx.points.toLocaleString()}</Table.Td>
                        <Table.Td><NotesCell value={tx.notes} /></Table.Td>
                      </Table.Tr>
                    ))
                  )}
                </Table.Tbody>
              </Table>
            </Table.ScrollContainer>
            {renderFooter(filteredSent.length, safeSentPage, setSentPage, sentLimit, setSentLimit)}
          </Tabs.Panel>
        </Tabs>
      )}
    </Drawer>
  );
}
