import React, { useState, useEffect, useMemo, useCallback } from 'react';
import { toast } from 'sonner';
import { useSearchParams } from 'react-router-dom';
import {
    DataGrid, GridColDef, type GridFilterModel, type GridSortModel,
    type GridColumnVisibilityModel, type GridPaginationModel
} from '@mui/x-data-grid';
import { ThemeProvider as MuiThemeProvider } from '@mui/material/styles';
import { useMuiTheme } from '@/hooks/useMuiTheme';
import {
    filterModelToParams, paramsToFilterModel,
    sortModelToParams, paramsToSortModel,
    visibilityModelToParams, paramsToVisibilityModel,
} from '@/components/grids/gridUtils';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Label } from '@/components/ui/label';
import { Badge } from '@/components/ui/badge';
import {
    Dialog, DialogContent, DialogHeader, DialogTitle, DialogFooter
} from '@/components/ui/dialog';
import {
    Select, SelectContent, SelectItem, SelectTrigger, SelectValue
} from '@/components/ui/select';
import {
    AlertDialog, AlertDialogAction, AlertDialogCancel, AlertDialogContent,
    AlertDialogDescription, AlertDialogFooter, AlertDialogHeader, AlertDialogTitle
} from '@/components/ui/alert-dialog';
import {
    Plus, Search, Trash2, Pencil, Check, FileText, Users, Send, ChevronDown, BarChart2
} from 'lucide-react';
import { T, translate } from '@/i18n';
import {
    Campaign,
    fetchCampaigns, createCampaign, updateCampaign, deleteCampaign, sendCampaign,
} from '@/modules/campaigns/client-campaigns';
import { fetchContactGroups, ContactGroup } from '@/modules/contacts/client-contacts';
import { PagePickerDialog } from '@/modules/pages/PagePickerDialog';
import { ContactsPicker } from '@/components/ContactsPicker';
import { listMailboxes, type MailboxItem } from '@/modules/contacts/client-mailboxes';

// ─── Status badge ─────────────────────────────────────────────────────────────

const STATUS_COLORS: Record<string, string> = {
    draft: 'bg-slate-500/15 text-slate-600',
    scheduled: 'bg-blue-500/15 text-blue-600',
    sending: 'bg-yellow-500/15 text-yellow-600',
    sent: 'bg-green-500/15 text-green-600',
    failed: 'bg-red-500/15 text-red-600',
};

const STATUSES = ['draft', 'scheduled', 'sending', 'sent', 'failed'] as const;

const StatusBadge = ({ status }: { status?: string }) => (
    <span className={`text-xs px-2 py-0.5 rounded-full font-medium ${STATUS_COLORS[status || 'draft'] ?? STATUS_COLORS.draft}`}>
        <T>{status || 'draft'}</T>
    </span>
);

// ─── Campaign Form ────────────────────────────────────────────────────────────

const EMPTY: Partial<Campaign> = {
    name: '', page_slug: '', page_id: '', subject: '',
    group_ids: [], lang: '', tracking_id: '', vars: {}, status: 'draft',
};

const CampaignForm = ({
    initial, onSave, onCancel, saving, groups, mailboxes
}: {
    initial: Partial<Campaign>;
    onSave: (c: Partial<Campaign>) => void;
    onCancel: () => void;
    saving: boolean;
    groups: ContactGroup[];
    mailboxes: MailboxItem[];
}) => {
    const [c, setC] = useState<Partial<Campaign>>(initial);
    const [pagePicker, setPagePicker] = useState(false);

    const set = (k: keyof Campaign, v: any) => setC(prev => ({ ...prev, [k]: v }));

    const groupNames = useMemo(() => {
        const gMap = new Map(groups.map(g => [g.id, g.name]));
        return (c.group_ids || []).map(id => gMap.get(id) || id);
    }, [c.group_ids, groups]);

    return (
        <div className="space-y-4 max-h-[70vh] overflow-y-auto pr-1">
            <div className="space-y-1">
                <Label><T>Campaign name</T></Label>
                <Input value={c.name || ''} onChange={e => set('name', e.target.value)} placeholder={translate('March Newsletter')} />
            </div>

            <div className="space-y-1">
                <Label><T>Subject</T></Label>
                <Input value={c.subject || ''} onChange={e => set('subject', e.target.value)} placeholder={translate('Newsletter — March 2026')} />
            </div>

            <div className="grid grid-cols-2 gap-3">
                {/* From Address */}
                <div className="space-y-1 col-span-2">
                    <Label><T>Send From</T></Label>
                    <Select
                        value={c.meta?.settings?.from_address || 'default'}
                        onValueChange={v => set('meta', {
                            ...(c.meta || {}),
                            settings: {
                                ...((c.meta as any)?.settings || {}),
                                from_address: v === 'default' ? null : v
                            }
                        })}
                    >
                        <SelectTrigger className="w-full">
                            <SelectValue placeholder={translate('System Default (config.json)')} />
                        </SelectTrigger>
                        <SelectContent>
                            <SelectItem value="default"><T>System Default (config.json)</T></SelectItem>
                            {mailboxes.map(mb => (
                                <SelectItem key={mb.id} value={mb.user}>
                                    {mb.user} {mb.label ? `(${mb.label})` : ''}
                                </SelectItem>
                            ))}
                        </SelectContent>
                    </Select>
                </div>

                <div className="space-y-1">
                    <Label><T>Language</T></Label>
                    <Input value={c.lang || ''} onChange={e => set('lang', e.target.value)} placeholder="en, de…" />
                </div>
                <div className="space-y-1">
                    <Label><T>Tracking ID</T></Label>
                    <Input value={c.tracking_id || ''} onChange={e => set('tracking_id', e.target.value)} placeholder="mail-DD-HH-mm" />
                </div>
            </div>

            {/* Page picker */}
            <div className="space-y-1">
                <Label className="flex items-center gap-1"><FileText className="h-3 w-3" /><T>Email page</T></Label>
                <div className="flex items-center gap-2">
                    <Input readOnly value={c.page_slug || ''} placeholder={translate('Select a page…')} className="flex-1 cursor-pointer" onClick={() => setPagePicker(true)} />
                    <Button type="button" size="sm" variant="outline" onClick={() => setPagePicker(true)}>
                        <FileText className="h-3 w-3" />
                    </Button>
                </div>
                <PagePickerDialog
                    isOpen={pagePicker}
                    onClose={() => setPagePicker(false)}
                    onSelect={(page) => {
                        if (page) {
                            set('page_slug', page.slug);
                            set('page_id', page.id);
                        }
                    }}
                    currentValue={c.page_id || null}
                />
            </div>

            {/* Group picker */}
            <div className="space-y-2">
                <Label className="flex items-center gap-1"><Users className="h-3 w-3" /><T>Target groups</T></Label>
                <ContactsPicker
                    value={c.group_ids || []}
                    onChange={(ids) => set('group_ids', ids)}
                />
                {groupNames.length > 0 && (
                    <div className="flex flex-wrap gap-1">
                        {groupNames.map((name, i) => (
                            <Badge key={i} variant="secondary" className="text-xs">{name}</Badge>
                        ))}
                    </div>
                )}
            </div>

            <DialogFooter>
                <Button variant="outline" onClick={onCancel}><T>Cancel</T></Button>
                <Button onClick={() => onSave(c)} disabled={saving || !c.name?.trim()}>
                    <Check className="h-3 w-3 mr-1" /><T>{saving ? 'Saving…' : 'Save'}</T>
                </Button>
            </DialogFooter>
        </div>
    );
};

// ─── Main component ───────────────────────────────────────────────────────────

export const CampaignsManager = () => {
    const muiTheme = useMuiTheme();
    const [searchParams, setSearchParams] = useSearchParams();

    const q = searchParams.get('q') || '';
    const filterStatus = searchParams.get('status') || '';

    const setFilter = useCallback((key: string, value: string) => {
        setSearchParams(prev => {
            const next = new URLSearchParams(prev);
            if (value) next.set(key, value);
            else next.delete(key);
            return next;
        }, { replace: true });
    }, [setSearchParams]);

    const setQ = useCallback((v: string) => setFilter('q', v), [setFilter]);
    const setFilterStatus = useCallback((v: string) => setFilter('status', v), [setFilter]);

    const [campaigns, setCampaigns] = useState<Campaign[]>([]);
    const [groups, setGroups] = useState<ContactGroup[]>([]);
    const [mailboxes, setMailboxes] = useState<MailboxItem[]>([]);
    const [loading, setLoading] = useState(true);

    // Grid state from URL
    const [filterModel, setFilterModel] = useState<GridFilterModel>(() => paramsToFilterModel(searchParams));
    const [sortModel, setSortModel] = useState<GridSortModel>(() => paramsToSortModel(searchParams));
    const [columnVisibilityModel, setColumnVisibilityModel] = useState<GridColumnVisibilityModel>(() => paramsToVisibilityModel(searchParams));
    const [paginationModel, setPaginationModel] = useState<GridPaginationModel>(() => ({
        page: parseInt(searchParams.get('page') || '0', 10),
        pageSize: parseInt(searchParams.get('pageSize') || '25', 10),
    }));

    // Dialogs
    const [editCampaign, setEditCampaign] = useState<Partial<Campaign> | null>(null);
    const [isNew, setIsNew] = useState(false);
    const [saving, setSaving] = useState(false);
    const [deleteId, setDeleteId] = useState<string | null>(null);
    const [sendId, setSendId] = useState<string | null>(null);
    const [sending, setSending] = useState(false);
    const [sendInterval, setSendInterval] = useState(1);

    const load = async () => {
        setLoading(true);
        try {
            const [c, g, mbs] = await Promise.all([
                fetchCampaigns({ q: q || undefined, status: filterStatus || undefined }),
                fetchContactGroups(),
                listMailboxes(),
            ]);
            setCampaigns(c);
            setGroups(g);
            setMailboxes(mbs);
        } catch (e: any) { toast.error(e.message); }
        finally { setLoading(false); }
    };

    useEffect(() => { load(); }, [q, filterStatus]);

    // Group name lookup
    const groupById = useMemo(() => new Map(groups.map(g => [g.id, g])), [groups]);

    // ── Columns ──
    const columns = useMemo<GridColDef[]>(() => [
        {
            field: 'name', headerName: translate('Name'), flex: 1, minWidth: 200,
            renderCell: (params: any) => (
                <div className="flex items-center gap-2 h-full min-w-0">
                    <div className="h-8 w-8 rounded-full bg-gradient-to-br from-primary/40 to-primary flex items-center justify-center text-white font-semibold text-xs shrink-0">
                        <Send className="h-3.5 w-3.5" />
                    </div>
                    <div className="min-w-0 flex flex-col justify-center leading-tight mt-0.5">
                        <p className="font-medium text-sm truncate">{params.row.name || '—'}</p>
                        {params.row.subject && (
                            <p className="text-[11px] text-muted-foreground truncate">{params.row.subject}</p>
                        )}
                    </div>
                </div>
            )
        },
        {
            field: 'actions', headerName: translate('Actions'), width: 130, align: 'right', headerAlign: 'right', sortable: false,
            renderCell: (params: any) => (
                <div className="flex items-center h-full justify-end gap-1 opacity-0 group-hover:opacity-100 transition-opacity w-full pr-2">
                    <Button size="icon" variant="ghost" className="h-7 w-7 text-primary hover:text-primary"
                        onClick={(e) => { e.stopPropagation(); setSendId(params.row.id); }}>
                        <Send className="h-3.5 w-3.5" />
                    </Button>
                    <Button size="icon" variant="ghost" className="h-7 w-7 text-green-600 hover:text-green-700 hover:bg-green-50"
                        onClick={(e) => {
                            e.stopPropagation();
                            // Open analytics pre-filtered by the tracking query
                            const url = `/admin/analytics?filter_search_contains=tracking%3D${params.row.tracking_id}`;
                            window.open(url, '_blank');
                        }}>
                        <BarChart2 className="h-3.5 w-3.5" />
                    </Button>
                    <Button size="icon" variant="ghost" className="h-7 w-7"
                        onClick={(e) => { e.stopPropagation(); setEditCampaign(params.row); setIsNew(false); }}>
                        <Pencil className="h-3.5 w-3.5" />
                    </Button>
                    <Button size="icon" variant="ghost" className="h-7 w-7 text-destructive hover:text-destructive"
                        onClick={(e) => { e.stopPropagation(); setDeleteId(params.row.id); }}>
                        <Trash2 className="h-3.5 w-3.5" />
                    </Button>
                </div>
            )
        },
        {
            field: 'page_slug', headerName: translate('Page'), width: 160,
            renderCell: (params: any) => (
                <span className="text-xs text-muted-foreground truncate">
                    {params.value ? `/${params.value}` : '—'}
                </span>
            )
        },
        {
            field: 'status', headerName: translate('Status'), width: 120,
            renderCell: (params: any) => (
                <div className="flex items-center h-full">
                    <StatusBadge status={params.row.status} />
                </div>
            )
        },
        {
            field: 'group_ids', headerName: translate('Groups'), width: 180,
            renderCell: (params: any) => {
                const ids: string[] = params.row.group_ids || [];
                return (
                    <div className="flex items-center gap-1 flex-wrap h-full py-1">
                        {ids.slice(0, 2).map(id => {
                            const g = groupById.get(id);
                            return <Badge key={id} variant="secondary" className="text-[10px] px-1.5 py-0 max-w-[66px] truncate">{g?.name || id.slice(0, 6)}</Badge>;
                        })}
                        {ids.length > 2 && (
                            <Badge variant="secondary" className="text-[10px] px-1.5 py-0">+{ids.length - 2}</Badge>
                        )}
                    </div>
                );
            }
        },
        {
            field: 'stats', headerName: translate('Stats'), width: 140,
            renderCell: (params: any) => {
                const s = params.row.stats || {};
                if (!s.total) return <span className="text-xs text-muted-foreground">—</span>;
                return (
                    <div className="flex items-center gap-1.5 h-full text-xs tabular-nums">
                        <span className="text-green-600">{s.sent ?? 0}✓</span>
                        {(s.failed ?? 0) > 0 && <span className="text-red-500">{s.failed}✕</span>}
                        {(s.skipped ?? 0) > 0 && <span className="text-muted-foreground">{s.skipped}⊘</span>}
                        <span className="text-muted-foreground">/ {s.total}</span>
                    </div>
                );
            }
        },
        {
            field: 'created_at', headerName: translate('Created'), width: 140,
            renderCell: (params: any) => (
                <span className="text-xs text-muted-foreground">
                    {params.value ? new Date(params.value).toLocaleDateString() : '—'}
                </span>
            )
        },
    ], [groupById]);

    // ── CRUD ──────────────────────────────────────────────────────────────────

    const handleSave = async (data: Partial<Campaign>) => {
        setSaving(true);
        try {
            if (isNew) {
                const created = await createCampaign(data);
                setCampaigns(prev => [created, ...prev]);
                toast.success(translate('Campaign created'));
            } else if (editCampaign?.id) {
                const updated = await updateCampaign(editCampaign.id, data);
                setCampaigns(prev => prev.map(x => x.id === updated.id ? updated : x));
                toast.success(translate('Campaign saved'));
            }
            setEditCampaign(null);
        } catch (e: any) { toast.error(e.message); }
        finally { setSaving(false); }
    };

    const handleDelete = async () => {
        if (!deleteId) return;
        try {
            await deleteCampaign(deleteId);
            setCampaigns(prev => prev.filter(c => c.id !== deleteId));
            toast.success(translate('Campaign deleted'));
        } catch (e: any) { toast.error(e.message); }
        finally { setDeleteId(null); }
    };

    const handleSend = async () => {
        if (!sendId) return;
        setSending(true);
        try {
            const stats = await sendCampaign(sendId, sendInterval);
            toast.success(translate(`Sent: ${stats.sent}/${stats.total}${stats.failed ? `, ${stats.failed} failed` : ''}`));
            await load(); // Refresh to show updated status + stats
        } catch (e: any) { toast.error(e.message); }
        finally { setSending(false); setSendId(null); }
    };

    // ── Render ────────────────────────────────────────────────────────────────

    return (
        <div className="space-y-3">
            {/* ── Toolbar ── */}
            <div className="flex flex-wrap items-center gap-2">
                <div className="relative flex-1 min-w-[180px]">
                    <Search className="absolute left-2.5 top-1/2 -translate-y-1/2 h-3.5 w-3.5 text-muted-foreground" />
                    <Input className="pl-8 h-8 text-sm" placeholder={translate('Search…')} value={q} onChange={e => setQ(e.target.value)} />
                </div>

                <Select value={filterStatus || '__all'} onValueChange={v => setFilterStatus(v === '__all' ? '' : v)}>
                    <SelectTrigger className="h-8 w-36 text-sm">
                        <ChevronDown className="h-3 w-3 mr-1 text-muted-foreground" />
                        <SelectValue placeholder={translate('All statuses')} />
                    </SelectTrigger>
                    <SelectContent>
                        <SelectItem value="__all"><T>All statuses</T></SelectItem>
                        {STATUSES.map(s => <SelectItem key={s} value={s}>{translate(s)}</SelectItem>)}
                    </SelectContent>
                </Select>

                <div className="flex items-center gap-1 ml-auto">
                    <Button size="sm" className="h-8 text-xs gap-1" onClick={() => { setEditCampaign({ ...EMPTY }); setIsNew(true); }}>
                        <Plus className="h-3 w-3" /><T>New Campaign</T>
                    </Button>
                </div>
            </div>

            {/* ── DataGrid ── */}
            {loading ? (
                <div className="py-12 text-center text-sm text-muted-foreground"><T>Loading…</T></div>
            ) : campaigns.length === 0 ? (
                <div className="py-12 text-center text-sm text-muted-foreground">
                    <T>No campaigns found.</T>{' '}
                    <button className="underline" onClick={() => { setEditCampaign({ ...EMPTY }); setIsNew(true); }}>
                        <T>Create one</T>
                    </button>
                </div>
            ) : (
                <div className="h-[600px] w-full bg-background rounded-md border">
                    <MuiThemeProvider theme={muiTheme}>
                        <DataGrid
                            rows={campaigns}
                            columns={columns}
                            getRowId={(row) => row.id}
                            showToolbar
                            disableRowSelectionOnClick
                            filterModel={filterModel}
                            onFilterModelChange={(newFilterModel) => {
                                setFilterModel(newFilterModel);
                                setSearchParams(prev => {
                                    const p = new URLSearchParams(prev);
                                    Array.from(p.keys()).forEach(k => { if (k.startsWith('filter_')) p.delete(k); });
                                    Object.entries(filterModelToParams(newFilterModel)).forEach(([k, v]) => p.set(k, v));
                                    return p;
                                }, { replace: true });
                            }}
                            sortModel={sortModel}
                            onSortModelChange={(newSortModel) => {
                                setSortModel(newSortModel);
                                setSearchParams(prev => {
                                    const p = new URLSearchParams(prev);
                                    p.delete('sort');
                                    const sp = sortModelToParams(newSortModel);
                                    if (sp.sort) p.set('sort', sp.sort);
                                    return p;
                                }, { replace: true });
                            }}
                            columnVisibilityModel={columnVisibilityModel}
                            onColumnVisibilityModelChange={(newModel) => {
                                setColumnVisibilityModel(newModel);
                                setSearchParams(prev => {
                                    const p = new URLSearchParams(prev);
                                    p.delete('hidden');
                                    const vp = visibilityModelToParams(newModel);
                                    if (vp.hidden !== undefined) p.set('hidden', vp.hidden);
                                    return p;
                                }, { replace: true });
                            }}
                            paginationModel={paginationModel}
                            onPaginationModelChange={(newPaginationModel) => {
                                setPaginationModel(newPaginationModel);
                                setSearchParams(prev => {
                                    const p = new URLSearchParams(prev);
                                    if (newPaginationModel.page !== 0) p.set('page', String(newPaginationModel.page));
                                    else p.delete('page');
                                    if (newPaginationModel.pageSize !== 25) p.set('pageSize', String(newPaginationModel.pageSize));
                                    else p.delete('pageSize');
                                    return p;
                                }, { replace: true });
                            }}
                            pageSizeOptions={[10, 25, 50]}
                            getRowClassName={() => 'group cursor-pointer hover:bg-muted/30 transition-colors'}
                            sx={{
                                border: 0,
                                bgcolor: 'transparent',
                                color: 'hsl(var(--foreground))',
                                '& .MuiDataGrid-columnHeaders': {
                                    borderColor: 'hsl(var(--border))',
                                },
                                '& .MuiDataGrid-cell': {
                                    borderColor: 'hsl(var(--border))',
                                    '&:focus, &:focus-within': { outline: 'none' },
                                },
                                '& .MuiDataGrid-columnHeader': {
                                    '&:focus, &:focus-within': { outline: 'none' },
                                },
                                '& .MuiDataGrid-footerContainer': {
                                    borderColor: 'hsl(var(--border))',
                                },
                                '& .MuiTablePagination-root': {
                                    color: 'hsl(var(--muted-foreground))',
                                },
                                '& .MuiDataGrid-overlay': {
                                    bgcolor: 'transparent',
                                },
                                '& .MuiCheckbox-root': {
                                    color: 'hsl(var(--muted-foreground))',
                                    '&.Mui-checked': {
                                        color: 'hsl(var(--primary))',
                                    },
                                },
                                '& .MuiDataGrid-columnSeparator': {
                                    color: 'hsl(var(--border))',
                                },
                                '& .MuiDataGrid-menuIcon button, & .MuiDataGrid-iconButtonContainer button': {
                                    color: 'hsl(var(--muted-foreground))',
                                },
                            }}
                        />
                    </MuiThemeProvider>
                </div>
            )}

            <p className="text-xs text-muted-foreground text-right">
                {campaigns.length} {translate(campaigns.length !== 1 ? 'campaigns' : 'campaign')}
            </p>

            {/* ── Edit / Create dialog ── */}
            <Dialog open={!!editCampaign} onOpenChange={o => !o && setEditCampaign(null)}>
                <DialogContent className="max-w-xl">
                    <DialogHeader>
                        <DialogTitle><T>{isNew ? 'New Campaign' : 'Edit Campaign'}</T></DialogTitle>
                    </DialogHeader>
                    {editCampaign && (
                        <CampaignForm
                            initial={editCampaign}
                            onSave={handleSave}
                            onCancel={() => setEditCampaign(null)}
                            saving={saving}
                            groups={groups}
                            mailboxes={mailboxes}
                        />
                    )}
                </DialogContent>
            </Dialog>

            {/* ── Delete confirm ── */}
            <AlertDialog open={!!deleteId} onOpenChange={o => !o && setDeleteId(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle><T>Delete campaign?</T></AlertDialogTitle>
                        <AlertDialogDescription><T>This cannot be undone.</T></AlertDialogDescription>
                    </AlertDialogHeader>
                    <AlertDialogFooter>
                        <AlertDialogCancel><T>Cancel</T></AlertDialogCancel>
                        <AlertDialogAction onClick={handleDelete} className="bg-destructive text-destructive-foreground hover:bg-destructive/90">
                            <T>Delete</T>
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>

            {/* ── Send confirm ── */}
            <AlertDialog open={!!sendId} onOpenChange={o => !o && !sending && setSendId(null)}>
                <AlertDialogContent>
                    <AlertDialogHeader>
                        <AlertDialogTitle><T>Send campaign?</T></AlertDialogTitle>
                        <AlertDialogDescription><T>This will send the email to all contacts in the target groups. This cannot be undone.</T></AlertDialogDescription>
                    </AlertDialogHeader>
                    <div className="py-3">
                        <Label className="text-sm"><T>Interval between sends (seconds)</T></Label>
                        <Input
                            type="number" min={0} step={0.5}
                            value={sendInterval}
                            onChange={e => setSendInterval(Math.max(0, parseFloat(e.target.value) || 0))}
                            className="mt-1 w-32 h-8 text-sm"
                        />
                    </div>
                    <AlertDialogFooter>
                        <AlertDialogCancel disabled={sending}><T>Cancel</T></AlertDialogCancel>
                        <AlertDialogAction onClick={handleSend} disabled={sending} className="bg-primary text-primary-foreground hover:bg-primary/90">
                            <Send className="h-3 w-3 mr-1" /><T>{sending ? 'Sending…' : 'Send'}</T>
                        </AlertDialogAction>
                    </AlertDialogFooter>
                </AlertDialogContent>
            </AlertDialog>
        </div>
    );
};
