import React, { useEffect, useRef, useState } from 'react';
import { Drawer, Table, Pagination, Text, LoadingOverlay, Badge, Group, TextInput, Stack, Tabs } from '@mantine/core';
import { IconSearch } from '@tabler/icons-react';
import { getCampaignRecipients, getAudienceMembers } from '@/lib/features/notifications/action';
import type { Campaign } from './CampaignsTable/types';

interface RecipientsDrawerProps {
    opened: boolean;
    onClose: () => void;
    campaign: Campaign | null;
}

export const RecipientsDrawer: React.FC<RecipientsDrawerProps> = ({ opened, onClose, campaign }) => {
    const [recipients, setRecipients] = useState<any[]>([]);
    const [loading, setLoading] = useState(false);
    const [total, setTotal] = useState(0);
    const [page, setPage] = useState(1);
    const [search, setSearch] = useState('');
    const [activeTab, setActiveTab] = useState<string | null>('ALL');
    const pageSize = 20;
    const requestIdRef = useRef(0);

    useEffect(() => {
        if (opened && campaign) {
            loadRecipients(1, search, activeTab === 'ALL' ? undefined : activeTab || undefined);
        } else {
            setRecipients([]);
            setTotal(0);
            setPage(1);
            setSearch('');
            setActiveTab('ALL');
        }
    }, [opened, campaign]);

    const loadRecipients = async (p: number, s?: string, st?: string) => {
        if (!campaign) return;
        const reqId = ++requestIdRef.current;
        setLoading(true);
        try {
            const offset = (p - 1) * pageSize;
            const searchTerm = s ?? search;
            const statusFilter = st;

            const res = await getCampaignRecipients(campaign.id, offset, pageSize, searchTerm, statusFilter);
            if (reqId !== requestIdRef.current) return;

            // If we have sent items, OR if we are searching (we should still check sent items first)
            if (res.success && res.data && (res.data.total > 0 || (searchTerm || statusFilter) && res.data.items && res.data.items.length === 0)) {
                setRecipients(res.data.items || []);
                setTotal(res.data.total || 0);
                setPage(p);
            } else if (['DRAFT', 'SCHEDULED', 'QUEUED', 'SENDING'].includes(campaign.status) && !statusFilter) {
                // fallback to previewing the target audience members directly because they haven't been sent yet!
                const criteria = typeof campaign.target_criteria === 'string' ? JSON.parse(campaign.target_criteria) : campaign.target_criteria;
                const targetRes = await getAudienceMembers(criteria, pageSize, offset, searchTerm);
                if (reqId !== requestIdRef.current) return;
                if (targetRes.success && targetRes.data) {
                    setRecipients(targetRes.data.items || []);
                    setTotal(targetRes.data.total || 0);
                    setPage(p);
                }
            } else if (res.success && res.data) {
                setRecipients(res.data.items || []);
                setTotal(res.data.total || 0);
                setPage(p);
            } else {
                setRecipients([]);
                setTotal(0);
                setPage(1);
            }
        } catch (e) {
            console.error("Failed to load recipients", e);
        } finally {
            if (reqId === requestIdRef.current) setLoading(false);
        }
    };

    const handleSearchChange = (val: string) => {
        setSearch(val);
        setPage(1);
        loadRecipients(1, val, activeTab === 'ALL' ? undefined : activeTab || undefined);
    };

    const handleTabChange = (val: string | null) => {
        setActiveTab(val);
        setPage(1);
        loadRecipients(1, search, val === 'ALL' ? undefined : val || undefined);
    };

    return (
        <Drawer opened={opened} onClose={onClose} title={`Recipients: ${campaign?.title || ''}`} position="right" size="lg">
            <div style={{ position: 'relative', minHeight: 200 }}>
                <LoadingOverlay visible={loading} />
                
                <Stack gap="md">
                    <TextInput
                        placeholder="Search by email..."
                        leftSection={<IconSearch size={14} />}
                        value={search}
                        onChange={(e) => handleSearchChange(e.currentTarget.value)}
                        size="sm"
                    />

                    {campaign?.additional_data && (() => {
                        const data = typeof campaign.additional_data === 'string' ? JSON.parse(campaign.additional_data) : campaign.additional_data;
                        if (data?.delivery_summary) {
                            return (
                                <Group grow gap="xs">
                                    <Stack gap={2} align="center" style={{ border: '1px solid var(--mantine-color-gray-2)', padding: '8px', borderRadius: '8px', cursor: 'pointer', backgroundColor: activeTab === 'SENT' ? 'var(--mantine-color-green-0)' : 'transparent' }} onClick={() => handleTabChange('SENT')}>
                                        <Text size="xs" c="dimmed">Processable</Text>
                                        <Text size="sm" fw={600} c="green">{data.delivery_summary.processable || 0}</Text>
                                    </Stack>
                                    <Stack gap={2} align="center" style={{ border: '1px solid var(--mantine-color-gray-2)', padding: '8px', borderRadius: '8px', cursor: 'pointer', backgroundColor: activeTab === 'INVALID' ? 'var(--mantine-color-red-0)' : 'transparent' }} onClick={() => handleTabChange('INVALID')}>
                                        <Text size="xs" c="dimmed">Invalid</Text>
                                        <Text size="sm" fw={600} c="red">{data.delivery_summary.invalid || 0}</Text>
                                    </Stack>
                                    <Stack gap={2} align="center" style={{ border: '1px solid var(--mantine-color-gray-2)', padding: '8px', borderRadius: '8px', cursor: 'pointer', backgroundColor: activeTab === 'NON_PROCESSABLE' ? 'var(--mantine-color-orange-0)' : 'transparent' }} onClick={() => handleTabChange('NON_PROCESSABLE')}>
                                        <Text size="xs" c="dimmed">Non-Processable</Text>
                                        <Text size="sm" fw={600} c="orange">{data.delivery_summary.non_processable || 0}</Text>
                                    </Stack>
                                </Group>
                            );
                        }
                        return null;
                    })()}

                    <Tabs value={activeTab} onChange={handleTabChange}>
                        <Tabs.List>
                            <Tabs.Tab value="ALL">All Recipients</Tabs.Tab>
                            <Tabs.Tab value="SENT" color="green">Sent</Tabs.Tab>
                            <Tabs.Tab value="INVALID" color="red">Invalid</Tabs.Tab>
                            <Tabs.Tab value="NON_PROCESSABLE" color="orange">Non-Processable</Tabs.Tab>
                        </Tabs.List>
                    </Tabs>

                    <Text size="sm" fw={500}>{activeTab === 'ALL' || !activeTab ? 'Total' : activeTab.replace('_', ' ')}: {total}</Text>

                    <Table striped highlightOnHover>
                        <Table.Thead>
                            <Table.Tr>
                                <Table.Th>Email</Table.Th>
                                <Table.Th>Status</Table.Th>
                                <Table.Th>Sent At</Table.Th>
                            </Table.Tr>
                        </Table.Thead>
                        <Table.Tbody>
                            {recipients.map((r, index) => (
                                <Table.Tr key={index}>
                                    <Table.Td>{r.email}</Table.Td>
                                    <Table.Td>
                                        <Badge 
                                            color={
                                                r.status === 'SENT' ? 'green' : 
                                                r.status === 'INVALID' ? 'red' : 
                                                r.status === 'NON_PROCESSABLE' ? 'orange' : 
                                                'gray'
                                            } 
                                            size="sm"
                                        >
                                            {r.status.replace('_', ' ')}
                                        </Badge>
                                    </Table.Td>
                                    <Table.Td>
                                        {r.sent_at ? new Date(r.sent_at).toLocaleString() : '-'}
                                    </Table.Td>
                                </Table.Tr>
                            ))}
                            {recipients.length === 0 && !loading && (
                                <Table.Tr>
                                    <Table.Td colSpan={3} style={{ textAlign: 'center' }}>No recipients found</Table.Td>
                                </Table.Tr>
                            )}
                        </Table.Tbody>
                    </Table>

                    {total > pageSize && (
                        <Group justify="center" mt="md">
                            <Pagination total={Math.ceil(total / pageSize)} value={page} onChange={(p) => loadRecipients(p, search, activeTab === 'ALL' ? undefined : activeTab || undefined)} />
                        </Group>
                    )}
                </Stack>
            </div>
        </Drawer>
    );
};
