import React, { useState, useEffect } from "react";
import { Modal, Stack, Button, Loader, Text, Alert, Card, Badge, Group, Radio, Box, Select, Center } from "@mantine/core";
import { notifications } from "@mantine/notifications";
import { searchViewPointByEmail, mapManagerToViewPoint } from "@/lib/features/points-transfer/query";
import type { Manager } from "@/lib/features/points-transfer/types";
import { useIsMobile } from "@/hooks/useIsMobile";

interface MapManagerModalProps {
  opened: boolean;
  onClose: () => void;
  unmappedManagers: Manager[];
  onSuccess: () => void;
}

export const MapManagerModal: React.FC<MapManagerModalProps> = ({ opened, onClose, unmappedManagers, onSuccess }) => {
  const isMobile = useIsMobile();
  const [selectedManagerId, setSelectedManagerId] = useState<string | null>(null);

  const [loadingSearch, setLoadingSearch] = useState(false);
  const [searchResults, setSearchResults] = useState<any[] | null>(null);

  const [selectedMapping, setSelectedMapping] = useState<{ accountId: string, contactId: string, club: string, isActive: boolean } | null>(null);
  const [saving, setSaving] = useState(false);

  useEffect(() => {
    if (opened) {
      setSelectedManagerId(null);
      setSearchResults(null);
      setSelectedMapping(null);
    }
  }, [opened]);

  useEffect(() => {
    if (selectedManagerId) {
      const manager = unmappedManagers.find(m => m.id === selectedManagerId);
      if (manager?.email) {
        handleSearch(manager.email);
      }
    } else {
      setSearchResults(null);
      setSelectedMapping(null);
    }
  }, [selectedManagerId]);

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

  const handleSave = async () => {
    if (!selectedManagerId || !selectedMapping) return;
    setSaving(true);
    try {
      const res = await mapManagerToViewPoint(selectedManagerId, selectedMapping);
      if (res.success) {
        notifications.show({ color: "green", message: "Manager added successfully" });
        onSuccess();
        onClose();
      } else {
        notifications.show({ color: "red", message: res.message || "Failed to add manager" });
      }
    } catch (err) {
      notifications.show({ color: "red", message: "Error saving manager" });
    } finally {
      setSaving(false);
    }
  };

  return (
    <Modal
      opened={opened}
      onClose={onClose}
      title="Add Manager"
      size="lg"
      // A fixed-width modal on a phone leaves the account cards squeezed into
      // ~300px with the action buttons pushed below the fold.
      fullScreen={isMobile}
    >
      <Stack gap="md">
        <Text size="sm">Select a user to link their ViewPoint account and add them as a  Manager.</Text>

        <Select
          label="Select Console User"
          placeholder="Choose a user"
          data={unmappedManagers.map(m => ({ value: m.id, label: `${m.first_name} ${m.last_name} (${m.email})` }))}
          value={selectedManagerId}
          onChange={setSelectedManagerId}
          searchable
          clearable
          rightSection={loadingSearch ? <Loader size="xs" /> : undefined}
        />

        {loadingSearch && (
          <Center my="xl">
            <Loader />
          </Center>
        )}

        {!loadingSearch && searchResults !== null && searchResults.length === 0 && (
          <Alert color="orange">This user's email does not exist in ViewPoint. They cannot be added as a Resort Manager.</Alert>
        )}

        {!loadingSearch && searchResults !== null && searchResults.length > 0 && (
          <Stack gap="md">
            <Text fw={500}>Select a Contact from the Results:</Text>
            {searchResults.map((account) => (
              <Card key={account.AccountID} withBorder padding="sm" radius="md">
                <Group justify="space-between" mb="xs">
                  <Text fw={600}>{account.AccountName} <Badge variant="light">{account.AccountType}</Badge></Text>
                  <Text size="sm" c="dimmed">ID: {account.AccountID}</Text>
                </Group>

                <Stack gap="xs">
                  {(account.Owners || []).concat(account.Contacts || []).map((contact: any) => {
                    const isSelected = selectedMapping?.accountId === account.AccountID && selectedMapping?.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={() => setSelectedMapping({
                          accountId: account.AccountID,
                          contactId: contact.ContactID,
                          club: account.AccountType,
                          isActive: contact.Active
                        })}
                      >
                        <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>
              </Card>
            ))}

            {/* Pinned to the bottom so the actions stay reachable however long
                the result list gets — on a phone it can run several screens. */}
            <Box
              style={{
                position: "sticky",
                bottom: 0,
                zIndex: 2,
                background: "var(--mantine-color-body)",
                borderTop: "1px solid var(--mantine-color-default-border)",
                marginInline: "calc(var(--mantine-spacing-md) * -1)",
                marginTop: "var(--mantine-spacing-sm)",
                padding: "var(--mantine-spacing-md)",
              }}
            >
              <Group justify="flex-end" grow={isMobile}>
                <Button variant="default" onClick={onClose}>Cancel</Button>
                <Button onClick={handleSave} loading={saving} disabled={!selectedMapping}>Add Manager</Button>
              </Group>
            </Box>
          </Stack>
        )}
      </Stack>
    </Modal>
  );
};
