"use client";

import { BuildTable } from "@/components/blocks/Table/table";
import { getAccessListCandidates } from "@/lib/features/access-list/query";
import { useCoreFetcher } from "@/lib/features/useCoreFetcher";
import type { AccessScope } from "@/lib/features/types";
import type { AdminUser } from "@/lib/features/users/types";
import {
  Avatar,
  Button,
  Flex,
  Group,
  Loader,
  Modal,
  Paper,
  ScrollArea,
  Stack,
  Text,
  TextInput,
  Title,
} from "@mantine/core";
import {
  IconPlus,
  IconSearch,
  IconShieldLock,
  IconTrash,
  IconUserPlus,
} from "@tabler/icons-react";
import type { MRT_ColumnDef, MRT_RowData } from "mantine-react-table";
import moment from "moment";
import { useEffect, useState } from "react";
import { useNavigate, Link } from "react-router";
import { toast } from "sonner";

const AccessListClientPage: React.FC<{
  tableProps: { data: AdminUser[]; totalRows: number };
  accessScope: AccessScope;
}> = ({ tableProps, accessScope }) => {
  const navigate = useNavigate();
  const [addModalOpen, setAddModalOpen] = useState(false);
  const [candidateSearch, setCandidateSearch] = useState("");
  const [candidates, setCandidates] = useState<AdminUser[]>([]);
  const [candidatesLoading, setCandidatesLoading] = useState(false);

  const { trigger: addTrigger, isLoading: isAdding } = useCoreFetcher(
    "add-user-to-access-list",
    "post",
    {
      onSuccess: () => {
        toast.success("User added to access list");
      },
      onError: (error) => {
        toast.error((error as Error)?.message ?? "Failed to add user");
      },
    },
  );

  const { trigger: removeTrigger } = useCoreFetcher(
    "remove-user-from-access-list",
    "delete",
    {
      onSuccess: () => {
        toast.success("User removed from access list");
      },
      onError: (error) => {
        toast.error((error as Error)?.message ?? "Failed to remove user");
      },
    },
  );

  useEffect(() => {
    if (!addModalOpen) return;
    let cancelled = false;
    setCandidatesLoading(true);
    void (async () => {
      const res = await getAccessListCandidates(1, 50, candidateSearch || undefined);
      if (cancelled) return;
      setCandidates(res?.data?.users ?? []);
      setCandidatesLoading(false);
    })();
    return () => {
      cancelled = true;
    };
  }, [addModalOpen, candidateSearch]);

  const handleAdd = async (userId: string) => {
    await addTrigger({ userId });
    setCandidates((prev) => prev.filter((c) => c.id !== userId));
  };

  const handleRemove = (row: AdminUser) => {
    const label = `${row.first_name} ${row.last_name ?? ""}`.trim() || row.email;
    if (!window.confirm(`Remove ${label} from the Promocode Access List? Their configured campaigns/promo codes will be cleared.`)) {
      return;
    }
    void removeTrigger({ userId: row.id });
  };

  const columns: MRT_ColumnDef<AdminUser>[] = [
    {
      accessorKey: "first_name",
      header: "First Name",
      minSize: 200,
    },
    {
      accessorKey: "last_name",
      header: "Last Name",
      minSize: 200,
    },
    {
      accessorKey: "email",
      header: "Email",
      minSize: 200,
    },
    {
      accessorFn: (row) => moment(row.created_at).format("LLL"),
      id: "created_at",
      header: "Created At",
    },
    ...(accessScope.delete
      ? [
          {
            id: "actions",
            header: "Actions",
            enableSorting: false,
            Cell: ({ row }: { row: { original: AdminUser } }) => (
              <Button
                size="xs"
                color="red"
                variant="light"
                leftSection={<IconTrash size={14} />}
                onClick={(e: React.MouseEvent) => {
                  e.stopPropagation();
                  handleRemove(row.original);
                }}
              >
                Remove
              </Button>
            ),
          } as MRT_ColumnDef<AdminUser>,
        ]
      : []),
  ];

  const handleRowClick = (rowData: MRT_RowData) => {
    const row = rowData as AdminUser;
    void navigate(row.id);
  };

  return (
    <Stack>
      <Flex justify="space-between" align="center" wrap="wrap" gap="sm">
        <Title order={6}>Promocode Access List</Title>
        <Group gap="xs">
          {/* Roles live under the Access List rather than in the nav — they grant
              the same access, just as a reusable bundle. */}
          <Button
            variant="light"
            leftSection={<IconShieldLock size={14} />}
            component={Link}
            to="/admin/promo-access-roles"
          >
            Promo Code Roles
          </Button>
          {accessScope.create && (
            <Button
              variant="filled"
              bg="blue.1"
              c="blue.9"
              leftSection={<IconPlus size={14} />}
              onClick={() => setAddModalOpen(true)}
            >
              Add User
            </Button>
          )}
        </Group>
      </Flex>

      <BuildTable
        data={tableProps.data}
        columns={columns}
        totalRows={tableProps.totalRows}
        onRowClick={handleRowClick}
        enableRowSelection={false}
      />

      <Modal
        opened={addModalOpen}
        onClose={() => {
          setAddModalOpen(false);
          setCandidateSearch("");
        }}
        title={
          <Group gap={8}>
            <IconUserPlus size={20} />
            <Text fw={700} size="lg">Add User to Access List</Text>
          </Group>
        }
        size="xl"
        radius="md"
        padding="xl"
      >
        <Stack gap="md">
          <Text size="sm" c="dimmed">
            Search for a user and grant them access to manage specific campaigns and promo codes.
          </Text>
          <TextInput
            placeholder="Search by name or email…"
            leftSection={<IconSearch size={16} />}
            size="md"
            radius="md"
            value={candidateSearch}
            onChange={(e) => setCandidateSearch(e.currentTarget.value)}
          />
          <ScrollArea h={480} type="auto" offsetScrollbars>
            <Stack gap="sm" pr="md">
              {candidatesLoading && <Loader size="sm" mx="auto" my="xl" />}
              {!candidatesLoading &&
                candidates.map((c) => {
                  const initials = `${c.first_name?.[0] ?? ""}${c.last_name?.[0] ?? ""}`.toUpperCase();
                  return (
                    <Paper key={c.id} withBorder radius="md" p="sm">
                      <Group justify="space-between" wrap="nowrap">
                        <Group gap="sm" wrap="nowrap">
                          <Avatar radius="xl" color="blue" size="md">
                            {initials || <IconUserPlus size={16} />}
                          </Avatar>
                          <Stack gap={0}>
                            <Text size="sm" fw={600}>
                              {c.first_name} {c.last_name ?? ""}
                            </Text>
                            <Text size="xs" c="dimmed">
                              {c.email}
                            </Text>
                          </Stack>
                        </Group>
                        <Button
                          size="sm"
                          radius="md"
                          variant="light"
                          leftSection={<IconPlus size={14} />}
                          loading={isAdding}
                          onClick={() => handleAdd(c.id)}
                        >
                          Add
                        </Button>
                      </Group>
                    </Paper>
                  );
                })}
              {!candidatesLoading && candidates.length === 0 && (
                <Text size="sm" c="dimmed" ta="center" my="xl">
                  No matching users found.
                </Text>
              )}
            </Stack>
          </ScrollArea>
        </Stack>
      </Modal>
    </Stack>
  );
};

export default AccessListClientPage;
