import BreadCrumbLink from "@/layouts/shared/page.breadcrumbLink";
import { createRoleProtectedLoader } from "@/lib/features/protectedFetcher";
import { FEATURE_SLUGS } from "@/lib/role-helpers";
import { listBlockedEmails, createBlockedEmail, deleteBlockedEmail } from "@/lib/features/notifications/action";
import { 
    Button, 
    Flex, 
    Group, 
    Pagination, 
    Select, 
    Stack, 
    Table, 
    Text, 
    TextInput, 
    Title,
    ActionIcon,
    Modal,
    Box
} from "@mantine/core";
import { useDebouncedValue, useDisclosure } from "@mantine/hooks";
import { notifications } from "@mantine/notifications";
import { IconPlus, IconSearch, IconTrash, IconArrowLeft, IconMailOff } from "@tabler/icons-react";
import React, { useEffect, useState } from "react";
import { useNavigate, useSearchParams, useLoaderData, useRevalidator } from "react-router";

export const handle = {
    breadcrumb: () => (
        <BreadCrumbLink
            links={[
                { label: "Notifications" },
                { label: "Email Block List" },
            ]}
        />
    ),
};

export const loader = createRoleProtectedLoader(
    FEATURE_SLUGS.notifications,
    "read",
    async ({ request }) => {
        try {
            const url = new URL(request.url);
            const page = parseInt(url.searchParams.get("page") ?? "1", 10);
            const pageSize = parseInt(url.searchParams.get("pageSize") ?? "10", 10);
            const search = url.searchParams.get("search") ?? undefined;
            const start = (page - 1) * pageSize;

            const res = await listBlockedEmails(start, pageSize, search);
            return res.success ? res.data : { items: [], total: 0 };
        } catch (e) {
            console.error("Loader error in BlockListPage:", e);
            return { items: [], total: 0 };
        }
    },
);

const BlockListPage = () => {
    const navigate = useNavigate();
    const [searchParams, setSearchParams] = useSearchParams();
    const revalidator = useRevalidator();
    const loaderData = useLoaderData() as any;
    
    const initialItems = loaderData?.items || [];
    const initialTotal = loaderData?.total || 0;

    const [items, setItems] = useState<any[]>(initialItems);
    const [total, setTotal] = useState(initialTotal);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        if (loaderData) {
            setItems(loaderData.items || []);
            setTotal(loaderData.total || 0);
        }
    }, [loaderData]);

    const page = parseInt(searchParams.get("page") || "1", 10);
    const pageSize = searchParams.get("pageSize") || "10";
    const search = searchParams.get("search") || "";

    const [localSearch, setLocalSearch] = useState(search);
    const [debouncedSearch] = useDebouncedValue(localSearch, 500);

    const [addModalOpened, { open: openAddModal, close: closeAddModal }] = useDisclosure(false);
    const [newEmail, setNewEmail] = useState("");
    const [submitting, setSubmitting] = useState(false);

    useEffect(() => {
        if (debouncedSearch !== search) {
            updateParams({ search: debouncedSearch, page: 1 });
        }
    }, [debouncedSearch]);

    const updateParams = (updates: Record<string, any>) => {
        const newParams = new URLSearchParams(searchParams);
        Object.entries(updates).forEach(([key, value]) => {
            if (value === undefined || value === null || value === "") newParams.delete(key);
            else newParams.set(key, String(value));
        });
        setSearchParams(newParams);
    };

    const handleAdd = async () => {
        if (!newEmail) return;
        setSubmitting(true);
        try {
            const res = await createBlockedEmail(newEmail);
            if (res.success) {
                notifications.show({ title: "Success", message: "Email added to block list", color: "green" });
                setNewEmail("");
                closeAddModal();
                revalidator.revalidate();
            } else {
                notifications.show({ title: "Error", message: res.message || "Failed to add email", color: "red" });
            }
        } catch (e) {
            notifications.show({ title: "Error", message: "An unexpected error occurred", color: "red" });
        } finally {
            setSubmitting(false);
        }
    };

    const handleDelete = async (id: string, email: string) => {
        if (!confirm(`Are you sure you want to remove ${email} from the block list?`)) return;
        try {
            const res = await deleteBlockedEmail(id);
            if (res.success) {
                notifications.show({ title: "Success", message: "Email removed from block list", color: "green" });
                revalidator.revalidate();
            } else {
                notifications.show({ title: "Error", message: "Failed to remove email", color: "red" });
            }
        } catch (e) {
            notifications.show({ title: "Error", message: "An unexpected error occurred", color: "red" });
        }
    };

    return (
        <Stack px={28} py={20} gap="lg">
            <Flex justify="space-between" align="center">
                <Group>
                    <Button 
                        variant="subtle" 
                        leftSection={<IconArrowLeft size={16} />} 
                        onClick={() => navigate("/admin/notifications")}
                    >
                        Back
                    </Button>
                    <Title order={3}>Email Block List</Title>
                </Group>
                <Button leftSection={<IconPlus size={16} />} onClick={openAddModal}>
                    Add Email to Block List
                </Button>
            </Flex>

            <Box p="md" style={{ backgroundColor: 'var(--mantine-color-gray-0)', borderRadius: '12px' }}>
                <TextInput
                    placeholder="Search blocked emails..."
                    value={localSearch}
                    onChange={(e) => setLocalSearch(e.currentTarget.value)}
                    leftSection={<IconSearch size={18} stroke={1.5} />}
                    size="sm"
                    radius="md"
                    variant="filled"
                    style={{ maxWidth: 400 }}
                />
            </Box>

            <Table verticalSpacing="md">
                <Table.Thead>
                    <Table.Tr>
                        <Table.Th>Email Address</Table.Th>
                        <Table.Th>Date Added</Table.Th>
                        <Table.Th></Table.Th>
                    </Table.Tr>
                </Table.Thead>
                <Table.Tbody>
                    {items.length === 0 ? (
                        <Table.Tr>
                            <Table.Td colSpan={3} style={{ textAlign: 'center', padding: '40px' }}>
                                <IconMailOff size={48} color="var(--mantine-color-gray-3)" />
                                <Text c="dimmed" mt="sm">No emails found in the block list</Text>
                            </Table.Td>
                        </Table.Tr>
                    ) : (
                        items.map((item) => (
                            <Table.Tr key={item.id}>
                                <Table.Td fw={500}>{item.email}</Table.Td>
                                <Table.Td c="dimmed">
                                    {new Date(item.created_at).toLocaleDateString(undefined, {
                                        year: 'numeric',
                                        month: 'short',
                                        day: 'numeric',
                                        hour: '2-digit',
                                        minute: '2-digit'
                                    })}
                                </Table.Td>
                                <Table.Td>
                                    <Group justify="flex-end">
                                        <ActionIcon 
                                            color="red" 
                                            variant="light" 
                                            onClick={() => handleDelete(item.id, item.email)}
                                        >
                                            <IconTrash size={16} />
                                        </ActionIcon>
                                    </Group>
                                </Table.Td>
                            </Table.Tr>
                        ))
                    )}
                </Table.Tbody>
            </Table>

            <Flex justify="space-between" align="center">
                <Group gap="xs">
                    <Select
                        style={{ width: 80 }}
                        data={['10', '20', '30', '40', '50']}
                        value={String(pageSize)}
                        onChange={(val) => updateParams({ pageSize: val, page: 1 })}
                    />
                    <Text size="sm" c="dimmed">Entries per page</Text>
                </Group>
                <Pagination
                    total={Math.max(1, Math.ceil(total / parseInt(String(pageSize))))}
                    value={page}
                    onChange={(val) => updateParams({ page: val })}
                />
            </Flex>

            <Modal 
                opened={addModalOpened} 
                onClose={closeAddModal} 
                title="Add Email to Block List"
                centered
            >
                <Stack>
                    <TextInput
                        label="Email Address"
                        placeholder="example@email.com"
                        value={newEmail}
                        onChange={(e) => setNewEmail(e.currentTarget.value)}
                        required
                    />
                    <Text size="xs" c="dimmed">
                        Emails in this list will be filtered out when "Apply Block List" is checked during campaign creation.
                    </Text>
                    <Button onClick={handleAdd} loading={submitting}>
                        Add to Block List
                    </Button>
                </Stack>
            </Modal>
        </Stack>
    );
};

export default BlockListPage;
