import React, { useState, useEffect } from "react";
import { Drawer, Stack, TextInput, Button, Loader, Text, Alert, Card, Badge, Group, ActionIcon, Radio, Box, NumberInput, Textarea, Collapse } from "@mantine/core";
import { IconSearch, IconArrowsRightLeft, IconChevronDown, IconChevronUp } from "@tabler/icons-react";
import { notifications } from "@mantine/notifications";
import { searchViewPointByEmail, transferToMember, getMyEntitlements } from "@/lib/features/points-transfer/query";
import type { ViewPointAccount, PointsEntitlement, ViewPointContact } from "@/lib/features/points-transfer/types";
import { useIsMobile } from "@/hooks/useIsMobile";

interface MemberTransferPanelProps {
  opened: boolean;
  onClose: () => void;
  maxPoints: number;
  onSuccess: () => void;
}

export const MemberTransferPanel: React.FC<MemberTransferPanelProps> = ({ opened, onClose, maxPoints, onSuccess }) => {
  const isMobile = useIsMobile();
  const [emailQuery, setEmailQuery] = useState("");
  const [loadingSearch, setLoadingSearch] = useState(false);
  const [searchResults, setSearchResults] = useState<ViewPointAccount[] | null>(null);

  const [selectedContact, setSelectedContact] = useState<{ accountId: string, contactId: string, firstName?: string, lastName?: string, email?: string } | null>(null);
  const [expandedAccount, setExpandedAccount] = useState<string | null>(null);

  const [points, setPoints] = useState<number | "">("");
  const [notes, setNotes] = useState("");
  const [transferring, setTransferring] = useState(false);

  // Eligible entitlements the transfer will be drawn from, in drain order
  // (soonest expiry first) — the backend already filters and sorts these.
  const [entitlements, setEntitlements] = useState<PointsEntitlement[]>([]);
  const [loadingEntitlements, setLoadingEntitlements] = useState(false);

  useEffect(() => {
    if (opened) {
      const fetchEntitlements = async () => {
        setLoadingEntitlements(true);
        try {
          const res = await getMyEntitlements();
          if (res.success && res.data) {
            setEntitlements(res.data);
          }
        } catch (err) {
          notifications.show({ color: "red", message: "Failed to load entitlements" });
        } finally {
          setLoadingEntitlements(false);
        }
      };
      fetchEntitlements();
    } else {
      setEmailQuery("");
      setSearchResults(null);
      setSelectedContact(null);
      setPoints("");
      setNotes("");
      setEntitlements([]);
    }
  }, [opened]);

  const handleSearch = async () => {
    if (!emailQuery) return;
    setLoadingSearch(true);
    try {
      const res = await searchViewPointByEmail(emailQuery);
      if (res.success && res.data) {
        setSearchResults(res.data);
      } else {
        setSearchResults([]);
      }
    } catch (err) {
      notifications.show({ color: "red", message: "Failed to search ViewPoint" });
    } finally {
      setLoadingSearch(false);
    }
  };

  const handleTransfer = async () => {
    if (!selectedContact || !points) return;

    if (Number(points) > maxPoints) {
      notifications.show({
        title: "Validation Error",
        message: `Points cannot exceed available balance of ${maxPoints.toLocaleString()} pts.`,
        color: "red",
      });
      return;
    }

    setTransferring(true);
    try {
      const res = await transferToMember({
        targetAccountId: selectedContact.accountId,
        targetContactId: selectedContact.contactId,
        targetFirstName: selectedContact.firstName,
        targetLastName: selectedContact.lastName,
        targetEmail: selectedContact.email,
        points: Number(points),
        notes
      });
      if (res.success) {
        notifications.show({ color: "green", message: "Points transferred successfully" });
        onSuccess();
        onClose();
      } else {
        notifications.show({ color: "red", message: res.message || "Failed to transfer points" });
      }
    } catch (err) {
      notifications.show({ color: "red", message: "Error transferring points" });
    } finally {
      setTransferring(false);
    }
  };

  return (
    <Drawer
      opened={opened}
      onClose={onClose}
      title="Transfer Points to Member"
      position="right"
      // Full width on phones — at "lg" the entitlement rows and contact cards
      // get clipped by the drawer edge.
      size={isMobile ? "100%" : "lg"}
    >
      <Stack gap="md">

        <Group align="flex-end">
          <TextInput
            label="Search Member by Email or Member Number"
            placeholder="member@email.com or Member Number"
            value={emailQuery}
            onChange={(e) => setEmailQuery(e.currentTarget.value)}
            style={{ flex: 1 }}
            onKeyDown={(e) => e.key === "Enter" && handleSearch()}
          />
          <Button onClick={handleSearch} loading={loadingSearch} leftSection={<IconSearch size={16} />}>Search</Button>
        </Group>

        {loadingSearch && (
          <Group justify="center" my="xl">
            <Loader />
          </Group>
        )}

        {!loadingSearch && searchResults !== null && searchResults.length === 0 && (
          <Alert color="orange">No ViewPoint accounts found for this search query.</Alert>
        )}

        {!loadingSearch && searchResults !== null && searchResults.length > 0 && (
          <Stack gap="md">
            <Text fw={500}>Select Target Account/Contact:</Text>
            {searchResults.map((account) => {
              const isExpanded = expandedAccount === account.AccountID;
              return (
              <Card key={account.AccountID} withBorder padding="sm" radius="md">
                <Group justify="space-between" mb="xs" style={{ cursor: 'pointer' }} onClick={() => setExpandedAccount(isExpanded ? null : account.AccountID)}>
                  <Box>
                    <Text fw={600}>{account.AccountName} <Badge variant="light">{account.AccountType}</Badge></Text>
                    <Text size="sm" c="dimmed">ID: {account.AccountID}</Text>
                  </Box>
                  <ActionIcon variant="subtle">
                    {isExpanded ? <IconChevronUp size={16} /> : <IconChevronDown size={16} />}
                  </ActionIcon>
                </Group>

                <Collapse in={isExpanded}>
                  <Stack gap="xs">
                    {(account.Owners || []).concat(account.Contacts || []).map((contact: ViewPointContact) => {
                      const isSelected = selectedContact?.accountId === account.AccountID && selectedContact?.contactId === contact.ContactID;
                      return (
                        <Card
                          key={contact.ContactID}
                          withBorder
                          bg={isSelected ? "blue.0" : "transparent"}
                          style={{ cursor: "pointer", borderColor: isSelected ? "var(--mantine-color-blue-filled)" : undefined }}
                          onClick={() => setSelectedContact({
                            accountId: account.AccountID,
                            contactId: contact.ContactID,
                            firstName: contact.FirstName,
                            lastName: contact.LastName,
                            email: contact.Email
                          })}
                        >
                          <Group justify="space-between" wrap="nowrap">
                            <Box>
                              <Text size="sm" fw={500}>{contact.FirstName} {contact.LastName} {contact.IsOwner && <Badge size="xs" color="violet">Owner</Badge>}</Text>
                              <Text size="xs" c="dimmed">{contact.Email}</Text>
                            </Box>
                            <Radio checked={isSelected} onChange={() => { }} />
                          </Group>
                        </Card>
                      );
                    })}
                  </Stack>
                </Collapse>
              </Card>
            )})}

            {selectedContact && (
              <>
                <Alert color="blue" title="Available Balance">
                  You can transfer up to <strong>{maxPoints.toLocaleString()}</strong> points from your account.
                </Alert>

                <Card withBorder padding="sm" radius="md">
                  <Text size="sm" fw={500} mb={6}>
                    Points are drawn automatically from your eligible entitlements (soonest expiry first):
                  </Text>
                  {loadingEntitlements ? (
                    <Group justify="center" my="sm">
                      <Loader size="sm" />
                    </Group>
                  ) : entitlements.length === 0 ? (
                    <Text size="sm" c="dimmed">No eligible entitlements available to transfer from.</Text>
                  ) : (
                    <Stack gap={6}>
                      {entitlements.map((e, idx) => (
                        <Group key={e.PointsEntitlementID} justify="space-between" wrap="nowrap">
                          <Group gap={6} wrap="nowrap" style={{ flex: 1, minWidth: 0 }}>
                            <Badge size="xs" variant="light" color="gray">{idx + 1}</Badge>
                            <Text size="xs" truncate>[{e.CustomType} - {e.EntitlementYear}] {e.PointsClubName}</Text>
                          </Group>
                          <Text size="xs" c="dimmed" style={{ flexShrink: 0 }}>
                            {e.Balance.toLocaleString()} pts · exp {new Date(e.ExpiryDate).toLocaleDateString()}
                          </Text>
                        </Group>
                      ))}
                    </Stack>
                  )}
                </Card>

                <NumberInput
                  label="Points to Transfer"
                  value={points}
                  onChange={(val) => setPoints(typeof val === 'number' ? val : "")}
                  min={1}
                  max={maxPoints}
                  required
                />

                <Textarea
                  label="Notes"
                  placeholder="Optional notes for this transfer"
                  value={notes}
                  onChange={(e) => setNotes(e.currentTarget.value)}
                  autosize
                  minRows={2}
                />

                <Box
                  style={{
                    position: "sticky",
                    bottom: 0,
                    zIndex: 2,
                    background: "var(--mantine-color-body)",
                    borderTop: "1px solid var(--mantine-color-gray-2)",
                    marginInline: "calc(var(--mantine-spacing-md) * -1)",
                    marginTop: "var(--mantine-spacing-sm)",
                    padding: "var(--mantine-spacing-md)",
                  }}
                >
                  <Button
                    fullWidth
                    onClick={handleTransfer}
                    loading={transferring}
                    disabled={!points || entitlements.length === 0}
                    leftSection={<IconArrowsRightLeft size={16} />}
                  >
                    Confirm Transfer
                  </Button>
                </Box>
              </>
            )}
          </Stack>
        )}
      </Stack>
    </Drawer>
  );
};
