/**
 * AudienceSegments — reusable audiences with consent count, suppression count,
 * export/sync status, refresh, AND an editable segment builder with a live preview
 * count that always applies opt-out + suppression filtering (spec §4, §8, §12 E1/E2).
 * Exports/syncs only permitted, consented, suppression-filtered contacts.
 */
import React, { useState, useMemo } from 'react';
import { createPortal } from 'react-dom';
import {
    Users, RefreshCw, Download, Upload, ShieldCheck, ShieldX, UserCheck,
    Plus, Pencil, X, Target, MapPin, Lock, ShieldQuestion, Sparkles, SlidersHorizontal,
    CheckCircle2, ChevronDown, CircleDashed,
} from 'lucide-react';
import { useSocialAds } from '../SocialAdsContext.jsx';
import { FILTER_OPTIONS, previewSegment, DEFAULT_FILTER_DEF } from '../data/contactPool.js';
import { AUDIENCE_SUGGESTIONS } from '../ai/audienceAdvisor.js';
import { Card, SectionHeader, Btn } from '../components/ui.jsx';
import { toast } from 'sonner';

const SEGMENT_LABEL = {
    storm_geo: 'Storm geo', crm_stage: 'CRM stage', reactivation: 'Reactivation',
    b2b: 'B2B', referral: 'Referral',
};
const LAST_JOB_OPTIONS = [['', 'Any time'], ['90', '< 90 days'], ['180', '< 180 days'], ['365', '< 1 year'], ['540', '< 18 months']];

export default function AudienceSegments() {
    const { audiences, createAudience, updateAudience, syncAudience, refreshAudience } = useSocialAds();
    const [editing, setEditing] = useState(null); // { audience } edit · { preset } new-from-AI · {} blank new · null closed
    const [dismissed, setDismissed] = useState([]);

    // Hide a suggestion once a segment with that name exists, or the user dismisses it.
    const existingNames = useMemo(() => new Set(audiences.map(a => a.name)), [audiences]);
    const suggestions = AUDIENCE_SUGGESTIONS.filter(s => !existingNames.has(s.name) && !dismissed.includes(s.key));

    const exportCsv = (a) => toast.success(`Exported ${(a.eligibleCount ?? a.consentCount).toLocaleString()} eligible contacts from "${a.name}" to CSV`);
    const handleSync = (a, dest) => {
        const tid = toast.loading(`Syncing "${a.name}" to ${dest}…`);
        setTimeout(() => { toast.dismiss(tid); syncAudience(a.id, dest); }, 700);
    };

    return (
        <div>
            <SectionHeader icon={Users} title="Audience Segments" description="Reusable CRM audiences. Only consented contacts sync, and suppression lists are always applied — including for retargeting.">
                <Btn icon={Plus} onClick={() => setEditing({})}>New segment</Btn>
            </SectionHeader>

            {/* AI audience suggestions (spec §6) */}
            {suggestions.length > 0 && (
                <div className="rounded-xl border border-purple-200 dark:border-purple-500/20 bg-purple-50/60 dark:bg-purple-500/5 p-3 mb-5">
                    <div className="flex items-center gap-2 mb-3">
                        <Sparkles size={15} className="text-purple-500 shrink-0" />
                        <p className="text-xs text-zinc-600 dark:text-zinc-300">AI suggested segments — consent + suppression always applied; no sensitive-attribute targeting.</p>
                    </div>
                    <div className="grid grid-cols-1 lg:grid-cols-2 gap-3">
                        {suggestions.map(s => (
                            <SuggestionCard key={s.key} s={s}
                                onCreate={() => createAudience({ name: s.name, segmentType: s.segmentType, filterDef: s.filterDef })}
                                onCustomize={() => setEditing({ preset: s })}
                                onDismiss={() => setDismissed(d => [...d, s.key])} />
                        ))}
                    </div>
                </div>
            )}

            <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
                {audiences.map(a => {
                    const eligible = a.eligibleCount ?? a.consentCount;
                    const eligiblePct = a.totalCount ? Math.round((eligible / a.totalCount) * 100) : 0;
                    return (
                        <Card key={a.id} className="!h-auto" pad="p-4">
                            <div className="flex items-start justify-between mb-2 gap-2">
                                <div className="min-w-0">
                                    <h4 className="font-bold text-sm text-zinc-900 dark:text-white">{a.name}</h4>
                                    <p className="text-[11px] text-zinc-400">{a.filters}</p>
                                </div>
                                <span className="text-[10px] font-bold uppercase tracking-wide px-2 py-0.5 rounded-full bg-zinc-100 dark:bg-white/10 text-zinc-500 shrink-0">
                                    {SEGMENT_LABEL[a.segmentType] || a.segmentType}
                                </span>
                            </div>

                            {/* Count breakdown */}
                            <div className="grid grid-cols-3 gap-2 my-3">
                                <Stat icon={Users} label="Total" value={a.totalCount} color="text-zinc-500" />
                                <Stat icon={ShieldCheck} label="Consented" value={a.consentCount} color="text-emerald-500" />
                                <Stat icon={ShieldX} label="Suppressed" value={a.suppressionCount} color="text-red-500" />
                            </div>

                            {/* Eligible bar (consent ∩ not-suppressed) */}
                            <div className="mb-3">
                                <div className="flex items-center justify-between text-[10px] text-zinc-400 mb-1">
                                    <span className="flex items-center gap-1"><UserCheck size={11} /> Eligible to sync (consent + suppression)</span>
                                    <span className="font-mono font-semibold text-emerald-600 dark:text-emerald-400">{eligible.toLocaleString()} · {eligiblePct}%</span>
                                </div>
                                <div className="h-2 rounded-full bg-zinc-200 dark:bg-zinc-700 overflow-hidden">
                                    <div className="h-full bg-gradient-to-r from-emerald-400 to-emerald-500" style={{ width: `${eligiblePct}%` }} />
                                </div>
                            </div>

                            <div className="flex items-center justify-between gap-2 mb-2">
                                <span className="text-[10px] text-zinc-400">Updated {a.lastCount}{a.frequencyCap ? ` · freq cap ${a.frequencyCap}/wk` : ''}</span>
                                <SyncStatusChip audience={a} />
                            </div>

                            <div className="flex flex-wrap items-center gap-1.5 pt-3 border-t border-zinc-100 dark:border-white/5">
                                <Btn size="sm" variant="ghost" icon={Pencil} onClick={() => setEditing({ audience: a })}>Edit</Btn>
                                <Btn size="sm" variant="ghost" icon={RefreshCw} onClick={() => refreshAudience(a.id)}>Refresh</Btn>
                                <div className="flex items-center gap-1.5 ml-auto">
                                    <Btn size="sm" variant="outline" icon={Download} onClick={() => exportCsv(a)}>CSV</Btn>
                                    <SyncMenu onSync={(dest) => handleSync(a, dest)} />
                                </div>
                            </div>
                        </Card>
                    );
                })}
            </div>

            {editing && (
                <SegmentBuilder
                    audience={editing.audience}
                    preset={editing.preset}
                    onClose={() => setEditing(null)}
                    onSave={(def) => {
                        if (editing.audience) updateAudience(editing.audience.id, def);
                        else createAudience(def);
                        setEditing(null);
                    }}
                />
            )}
        </div>
    );
}

function Stat({ icon: Icon, label, value, color }) {
    return (
        <div className="rounded-lg bg-zinc-50 dark:bg-white/5 p-2 text-center">
            {Icon && <Icon size={14} className={`${color} mx-auto mb-0.5`} />}
            <p className="text-sm font-mono font-bold text-zinc-800 dark:text-zinc-100">{value.toLocaleString()}</p>
            <p className="text-[9px] uppercase tracking-wider text-zinc-400">{label}</p>
        </div>
    );
}

// ── Sync status + destination menu (spec §8 "export/sync status"; §12 E2) ──────
const SYNC_DESTINATIONS = ['Meta Custom Audience', 'Google Customer Match', 'LinkedIn Matched Audiences'];

function SyncStatusChip({ audience }) {
    if (audience.syncStatus === 'synced') {
        const when = audience.lastSyncedAt
            ? new Date(audience.lastSyncedAt).toLocaleDateString(undefined, { month: 'short', day: 'numeric' })
            : '';
        const short = (audience.syncDestination || '').split(' ')[0];
        return (
            <span className="inline-flex items-center gap-1 text-[10px] font-semibold text-emerald-600 dark:text-emerald-400 bg-emerald-500/10 px-2 py-0.5 rounded-full" title={`Synced to ${audience.syncDestination}`}>
                <CheckCircle2 size={11} /> Synced · {short}{when ? ` · ${when}` : ''}
            </span>
        );
    }
    return (
        <span className="inline-flex items-center gap-1 text-[10px] font-semibold text-zinc-400 bg-zinc-100 dark:bg-white/5 px-2 py-0.5 rounded-full">
            <CircleDashed size={11} /> Not synced
        </span>
    );
}

function SyncMenu({ onSync }) {
    const [open, setOpen] = useState(false);
    return (
        <div className="relative">
            <button onClick={() => setOpen(o => !o)}
                className="inline-flex items-center justify-center gap-1 font-semibold rounded-xl transition-all focus:outline-none focus:ring-2 focus:ring-amber-500 px-2.5 py-1.5 text-xs bg-gradient-to-r from-amber-400 to-orange-500 text-white shadow-lg shadow-amber-500/25 hover:shadow-amber-500/40">
                <Upload size={14} /> Sync <ChevronDown size={13} />
            </button>
            {open && (
                <>
                    <div className="fixed inset-0 z-10" onClick={() => setOpen(false)} />
                    <div className="absolute right-0 mt-1 w-52 rounded-xl border border-zinc-200 dark:border-white/10 bg-white dark:bg-zinc-900 shadow-xl z-20 p-1">
                        <p className="px-3 py-1.5 text-[10px] font-bold uppercase tracking-wider text-zinc-400">Sync to platform</p>
                        {SYNC_DESTINATIONS.map(d => (
                            <button key={d} onClick={() => { onSync(d); setOpen(false); }}
                                className="w-full text-left px-3 py-2 rounded-lg text-xs text-zinc-700 dark:text-zinc-200 hover:bg-amber-500/10 hover:text-amber-600 dark:hover:text-amber-400 transition-colors">
                                {d}
                            </button>
                        ))}
                    </div>
                </>
            )}
        </div>
    );
}

// ── AI suggestion card (spec §6): reasons visible, one-click create, opt-out aware ──
function SuggestionCard({ s, onCreate, onCustomize, onDismiss }) {
    const SIcon = s.icon;
    const reach = useMemo(() => previewSegment(s.filterDef), [s.filterDef]);
    return (
        <div className="rounded-xl border border-zinc-200 dark:border-white/10 bg-white dark:bg-zinc-900 p-3 flex flex-col">
            <div className="flex items-start justify-between gap-2 mb-1.5">
                <div className="flex items-center gap-2 min-w-0">
                    <span className="p-1.5 rounded-lg bg-purple-500/10 text-purple-500 shrink-0">{SIcon && <SIcon size={15} />}</span>
                    <div className="min-w-0">
                        <h4 className="font-bold text-sm text-zinc-900 dark:text-white truncate">{s.name}</h4>
                        <span className="text-[10px] font-bold uppercase tracking-wide text-purple-500">AI · {Math.round(s.confidence * 100)}% match</span>
                    </div>
                </div>
                <button onClick={onDismiss} title="Dismiss" className="p-1 text-zinc-400 hover:text-zinc-600 dark:hover:text-zinc-200 shrink-0"><X size={14} /></button>
            </div>

            <p className="text-[11px] text-zinc-500 dark:text-zinc-400 mb-2">{s.rationale}</p>

            {/* AI reasons visible (spec §12 E1) */}
            <ul className="space-y-1 mb-2">
                {s.reasons.map((r, i) => (
                    <li key={i} className="text-[11px] text-zinc-600 dark:text-zinc-300 flex items-start gap-1.5">
                        <span className="text-purple-400 mt-1.5 w-1 h-1 rounded-full bg-purple-400 shrink-0" /> {r}
                    </li>
                ))}
            </ul>

            <div className="flex items-center gap-1.5 text-[11px] text-zinc-400 mb-3 mt-auto pt-2 border-t border-zinc-100 dark:border-white/5">
                <UserCheck size={12} className="text-emerald-500" />
                <span className="text-emerald-600 dark:text-emerald-400 font-mono font-semibold">{reach.eligible.toLocaleString()}</span> eligible after consent + suppression
            </div>

            <div className="flex items-center gap-2">
                <Btn size="sm" variant="primary" icon={Plus} onClick={onCreate}>Create</Btn>
                <Btn size="sm" variant="outline" icon={SlidersHorizontal} onClick={onCustomize}>Customize</Btn>
            </div>
        </div>
    );
}

// ── Segment builder modal: filter CRM contacts with a live, opt-out-aware count ──
function SegmentBuilder({ audience, preset, onClose, onSave }) {
    const init = audience || preset; // edit an existing audience, or seed a new one from an AI suggestion
    const [name, setName] = useState(init?.name || '');
    const [segmentType, setSegmentType] = useState(init?.segmentType || 'crm_stage');
    const [f, setF] = useState(() => ({ ...DEFAULT_FILTER_DEF, ...(init?.filterDef || {}) }));

    const set = (patch) => setF(prev => ({ ...prev, ...patch }));
    const toggleZip = (z) => set({ geo: f.geo.includes(z) ? f.geo.filter(x => x !== z) : [...f.geo, z] });

    const preview = useMemo(() => previewSegment(f), [f]);
    const optOuts = preview.matched - preview.consented;

    return createPortal(
        <div className="fixed inset-0 z-[1000] flex items-center justify-center p-4" onClick={onClose}>
            <div className="absolute inset-0 bg-black/50 backdrop-blur-[1px]" />
            <div onClick={e => e.stopPropagation()} className="relative w-full max-w-2xl max-h-[90vh] overflow-y-auto rounded-2xl bg-white dark:bg-zinc-900 shadow-2xl border border-zinc-200 dark:border-white/10 animate-in zoom-in-95">
                {/* Header */}
                <div className="sticky top-0 z-10 bg-white/95 dark:bg-zinc-900/95 backdrop-blur border-b border-zinc-200 dark:border-white/10 px-5 py-3 flex items-center justify-between gap-3">
                    <div className="flex items-center gap-2">
                        <Target size={18} className="text-amber-500" />
                        <h3 className="font-bold text-sm text-zinc-900 dark:text-white">{audience ? 'Edit segment' : 'New segment'}</h3>
                    </div>
                    <button onClick={onClose} className="p-1.5 rounded-lg text-zinc-400 hover:text-zinc-700 dark:hover:text-zinc-200 hover:bg-zinc-100 dark:hover:bg-white/10"><X size={18} /></button>
                </div>

                <div className="p-5 space-y-4">
                    {/* Name + type */}
                    <div className="grid grid-cols-1 sm:grid-cols-2 gap-3">
                        <Field label="Segment name">
                            <input value={name} onChange={e => setName(e.target.value)} placeholder="e.g. Plano storm — past 30 days"
                                className={inCls} />
                        </Field>
                        <Field label="Segment type">
                            <select value={segmentType} onChange={e => setSegmentType(e.target.value)} className={inCls}>
                                {Object.entries(SEGMENT_LABEL).map(([k, v]) => <option key={k} value={k}>{v}</option>)}
                            </select>
                        </Field>
                    </div>

                    {/* CRM filters (spec §12 E1) */}
                    <div>
                        <p className="text-[10px] font-bold uppercase tracking-wider text-zinc-400 mb-2">Filter CRM contacts</p>
                        <div className="grid grid-cols-1 sm:grid-cols-3 gap-3">
                            <Field label="Lifecycle stage">
                                <select value={f.stage} onChange={e => set({ stage: e.target.value })} className={inCls}>
                                    <option value="any">Any stage</option>
                                    {FILTER_OPTIONS.stages.map(s => <option key={s} value={s}>{s}</option>)}
                                </select>
                            </Field>
                            <Field label="Source">
                                <select value={f.source} onChange={e => set({ source: e.target.value })} className={inCls}>
                                    <option value="any">Any source</option>
                                    {FILTER_OPTIONS.sources.map(s => <option key={s} value={s}>{s}</option>)}
                                </select>
                            </Field>
                            <Field label="Service">
                                <select value={f.service} onChange={e => set({ service: e.target.value })} className={inCls}>
                                    <option value="any">Any service</option>
                                    {FILTER_OPTIONS.services.map(s => <option key={s} value={s}>{s}</option>)}
                                </select>
                            </Field>
                            <Field label="Last job within">
                                <select value={f.lastJobWithinDays || ''} onChange={e => set({ lastJobWithinDays: e.target.value ? Number(e.target.value) : null })} className={inCls}>
                                    {LAST_JOB_OPTIONS.map(([v, l]) => <option key={v} value={v}>{l}</option>)}
                                </select>
                            </Field>
                            <Field label="Frequency cap (per week)">
                                <input type="number" min={0} max={14} value={f.frequencyCap ?? ''} onChange={e => set({ frequencyCap: e.target.value ? Number(e.target.value) : null })} className={inCls} />
                            </Field>
                        </div>
                    </div>

                    {/* Geography */}
                    <Field label={<span className="flex items-center gap-1"><MapPin size={11} /> Geography (service-area ZIPs)</span>}>
                        <div className="flex flex-wrap gap-1.5">
                            {FILTER_OPTIONS.zips.map(z => (
                                <button key={z} onClick={() => toggleZip(z)}
                                    className={`px-2.5 py-1 rounded-lg text-xs font-mono font-semibold transition-colors ${f.geo.includes(z) ? 'bg-amber-500 text-white' : 'bg-zinc-100 dark:bg-white/5 text-zinc-600 dark:text-zinc-300 hover:bg-zinc-200 dark:hover:bg-white/10'}`}>
                                    {z}
                                </button>
                            ))}
                            {f.geo.length > 0 && <button onClick={() => set({ geo: [] })} className="px-2.5 py-1 rounded-lg text-xs text-zinc-400 hover:text-red-500">clear</button>}
                        </div>
                    </Field>

                    {/* Mandatory consent + suppression (spec §6) */}
                    <div className="rounded-xl border border-emerald-200 dark:border-emerald-500/20 bg-emerald-50/60 dark:bg-emerald-500/5 p-3 space-y-1.5">
                        <p className="text-[11px] font-semibold text-emerald-700 dark:text-emerald-400 flex items-center gap-1.5"><Lock size={12} /> Always applied (mandatory)</p>
                        <p className="text-[11px] text-zinc-600 dark:text-zinc-300 flex items-center gap-1.5"><ShieldCheck size={12} className="text-emerald-500" /> Consent filter — only opted-in contacts are reachable.</p>
                        <p className="text-[11px] text-zinc-600 dark:text-zinc-300 flex items-center gap-1.5"><ShieldX size={12} className="text-red-500" /> Suppression list — opt-outs/DNC removed, including for retargeting.</p>
                        <p className="text-[11px] text-zinc-500 flex items-start gap-1.5 pt-1 border-t border-emerald-200/50 dark:border-emerald-500/10"><ShieldQuestion size={12} className="text-zinc-400 mt-0.5 shrink-0" /> No sensitive-attribute targeting — only the CRM fields above can be used.</p>
                    </div>

                    {/* Live preview (spec §8 / §12 E2: count respects opt-outs + suppressions) */}
                    <div className="rounded-xl border border-zinc-200 dark:border-white/10 bg-zinc-50 dark:bg-white/[0.02] p-4">
                        <p className="text-[10px] font-bold uppercase tracking-wider text-zinc-400 mb-3">Estimated reach (live)</p>
                        <div className="flex items-center justify-between gap-2 flex-wrap">
                            <FunnelStep label="Matched" value={preview.matched} />
                            <FunnelArrow note={`− ${optOuts.toLocaleString()} no consent`} />
                            <FunnelStep label="Consented" value={preview.consented} />
                            <FunnelArrow note={`− ${preview.suppressed.toLocaleString()} suppressed`} />
                            <FunnelStep label="Eligible" value={preview.eligible} highlight />
                        </div>
                    </div>
                </div>

                {/* Footer */}
                <div className="sticky bottom-0 bg-white/95 dark:bg-zinc-900/95 backdrop-blur border-t border-zinc-200 dark:border-white/10 px-5 py-3 flex justify-end gap-2">
                    <Btn variant="ghost" onClick={onClose}>Cancel</Btn>
                    <Btn variant="primary" icon={Target} onClick={() => onSave({ name, segmentType, filterDef: f })}>
                        {audience ? 'Save segment' : 'Create segment'} · {preview.eligible.toLocaleString()} eligible
                    </Btn>
                </div>
            </div>
        </div>,
        document.body,
    );
}

const inCls = 'w-full rounded-lg border border-zinc-200 dark:border-white/10 bg-white dark:bg-zinc-900 px-2.5 py-2 text-sm text-zinc-800 dark:text-zinc-100 focus:outline-none focus:ring-2 focus:ring-amber-500';

function Field({ label, children }) {
    return (
        <label className="block">
            <span className="text-[11px] font-semibold text-zinc-500 dark:text-zinc-400 mb-1 block">{label}</span>
            {children}
        </label>
    );
}

function FunnelStep({ label, value, highlight }) {
    return (
        <div className="text-center">
            <p className={`text-xl font-mono font-bold ${highlight ? 'text-emerald-600 dark:text-emerald-400' : 'text-zinc-800 dark:text-zinc-100'}`}>{value.toLocaleString()}</p>
            <p className="text-[10px] uppercase tracking-wider text-zinc-400">{label}</p>
        </div>
    );
}

function FunnelArrow({ note }) {
    return (
        <div className="flex flex-col items-center text-zinc-400 min-w-0">
            <span className="text-lg leading-none">→</span>
            <span className="text-[9px] text-red-400 whitespace-nowrap">{note}</span>
        </div>
    );
}
