import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react';
import {
    ArrowLeft,
    ClipboardCopy,
    ExternalLink,
    ImagePlus,
    Loader2,
    Plus,
    Sparkles,
    Trash2,
} from 'lucide-react';
import { Button } from '@/components/ui/button';
import { Input } from '@/components/ui/input';
import { Textarea } from '@/components/ui/textarea';
import {
    Select,
    SelectContent,
    SelectItem,
    SelectTrigger,
    SelectValue,
} from '@/components/ui/select';
import AppShell from '@/components/layout/AppShell';
import LandingPageTemplate from '@/components/landing/LandingPageTemplate';
import { apiFetch } from '@/lib/api';
import { cn } from '@/lib/utils';

const AUTOSAVE_MS = 700;

function emptyDraft() {
    return {
        name: 'New landing page',
        prompt: '',
        content: {
            headline: '',
            subheadline: '',
            benefits: [
                { title: 'Benefit 1', body: '' },
                { title: 'Benefit 2', body: '' },
                { title: 'Benefit 3', body: '' },
            ],
            form_heading: 'Book a demo',
            form_subtext: '',
            footer_text: '',
        },
        cta_form_id: null,
        banner_url: null,
        logo_url: null,
        public_url: '',
        cta_form_public_id: null,
    };
}

function draftFromPage(p) {
    const c = p.content || {};
    const benefits = (c.benefits || []).map((b) => ({ ...b }));
    while (benefits.length < 3) {
        benefits.push({ title: `Benefit ${benefits.length + 1}`, body: '' });
    }
    return {
        name: p.name,
        prompt: p.prompt || '',
        content: {
            headline: c.headline || '',
            subheadline: c.subheadline || '',
            benefits: benefits.slice(0, 3),
            form_heading: c.form_heading || 'Book a demo',
            form_subtext: c.form_subtext || '',
            footer_text: c.footer_text || '',
        },
        cta_form_id: p.cta_form_id ?? null,
        banner_url: p.banner_url || null,
        logo_url: p.logo_url || null,
        public_url: p.public_url || '',
        cta_form_public_id: p.cta_form_public_id || null,
    };
}

function draftSnapshot(draft) {
    return JSON.stringify({
        name: (draft.name || '').trim(),
        prompt: draft.prompt || '',
        content: draft.content,
        cta_form_id: draft.cta_form_id,
    });
}

function SaveIndicator({ state }) {
    if (state === 'saving') {
        return (
            <span className="inline-flex items-center gap-1.5 text-xs text-slate-500">
                <Loader2 className="h-3 w-3 animate-spin" />
                Saving…
            </span>
        );
    }
    if (state === 'saved') return <span className="text-xs text-green-600">Saved</span>;
    if (state === 'error') return <span className="text-xs text-red-600">Could not save</span>;
    return null;
}

export default function LandingPagesSettings({ onBack }) {
    const [pages, setPages] = useState([]);
    const [ctaForms, setCtaForms] = useState([]);
    const [loading, setLoading] = useState(true);
    const [selectedId, setSelectedId] = useState(null);
    const [draft, setDraft] = useState(emptyDraft());
    const [saveState, setSaveState] = useState('idle');
    const [creating, setCreating] = useState(false);
    const [generating, setGenerating] = useState(false);
    const [uploadingBanner, setUploadingBanner] = useState(false);
    const [uploadingLogo, setUploadingLogo] = useState(false);
    const [error, setError] = useState('');

    const skipAutosaveRef = useRef(true);
    const saveTimerRef = useRef(null);
    const lastSavedSnapshotRef = useRef('');
    const savedFadeTimerRef = useRef(null);

    const selected = useMemo(
        () => pages.find((p) => p.id === selectedId) || null,
        [pages, selectedId]
    );

    const loadPages = useCallback(async () => {
        setLoading(true);
        setError('');
        try {
            const [pr, fr] = await Promise.all([
                apiFetch('/api/landing-pages'),
                apiFetch('/api/landing-pages/cta-form-options'),
            ]);
            const pdata = pr.ok ? await pr.json() : { pages: [] };
            const fdata = fr.ok ? await fr.json() : { forms: [] };
            if (!pr.ok) throw new Error(pdata.detail || 'Could not load pages');
            const list = pdata.pages || [];
            setPages(list);
            setCtaForms(fdata.forms || []);
            setSelectedId((prev) => {
                if (prev && list.some((p) => p.id === prev)) return prev;
                return list.length ? list[0].id : null;
            });
        } catch (e) {
            setError(e.message || 'Load failed');
            setPages([]);
        } finally {
            setLoading(false);
        }
    }, []);

    useEffect(() => {
        loadPages();
    }, [loadPages]);

    useEffect(() => {
        if (!selected) return;
        const next = draftFromPage(selected);
        skipAutosaveRef.current = true;
        lastSavedSnapshotRef.current = draftSnapshot(next);
        setDraft(next);
        setSaveState('idle');
    }, [selected?.id]);

    useEffect(() => {
        if (!selectedId) return;
        if (skipAutosaveRef.current) {
            skipAutosaveRef.current = false;
            return;
        }
        const snapshot = draftSnapshot(draft);
        if (snapshot === lastSavedSnapshotRef.current) return;
        const name = draft.name?.trim();
        if (!name) return;

        if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
        saveTimerRef.current = setTimeout(async () => {
            if (snapshot !== draftSnapshot(draft)) return;
            setSaveState('saving');
            try {
                const payload = JSON.parse(snapshot);
                const res = await apiFetch(`/api/landing-pages/${selectedId}`, {
                    method: 'PATCH',
                    headers: { 'Content-Type': 'application/json' },
                    body: JSON.stringify({
                        name: payload.name,
                        prompt: payload.prompt,
                        content: payload.content,
                        cta_form_id: payload.cta_form_id,
                    }),
                });
                const data = await res.json();
                if (!res.ok) throw new Error(data.detail || 'Save failed');
                lastSavedSnapshotRef.current = snapshot;
                setPages((prev) => prev.map((p) => (p.id === data.id ? data : p)));
                setDraft((d) => ({
                    ...d,
                    public_url: data.public_url || d.public_url,
                    banner_url: data.banner_url ?? d.banner_url,
                    logo_url: data.logo_url ?? d.logo_url,
                    cta_form_public_id: data.cta_form_public_id ?? d.cta_form_public_id,
                }));
                if (savedFadeTimerRef.current) clearTimeout(savedFadeTimerRef.current);
                setSaveState('saved');
                savedFadeTimerRef.current = window.setTimeout(() => setSaveState('idle'), 2000);
            } catch (e) {
                setError(e.message || 'Save failed');
                setSaveState('error');
            }
        }, AUTOSAVE_MS);

        return () => {
            if (saveTimerRef.current) clearTimeout(saveTimerRef.current);
        };
    }, [draft, selectedId]);

    const selectPage = (p) => {
        const next = draftFromPage(p);
        setSelectedId(p.id);
        skipAutosaveRef.current = true;
        lastSavedSnapshotRef.current = draftSnapshot(next);
        setDraft(next);
        setSaveState('idle');
    };

    const createPage = async () => {
        setCreating(true);
        setError('');
        try {
            const res = await apiFetch('/api/landing-pages', {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ name: 'New landing page', prompt: '' }),
            });
            const data = await res.json();
            if (!res.ok) throw new Error(data.detail || 'Create failed');
            await loadPages();
            setSelectedId(data.id);
            const next = draftFromPage(data);
            skipAutosaveRef.current = true;
            lastSavedSnapshotRef.current = draftSnapshot(next);
            setDraft(next);
        } catch (e) {
            setError(e.message || 'Create failed');
        } finally {
            setCreating(false);
        }
    };

    const deletePage = async () => {
        if (!selectedId) return;
        if (!window.confirm('Delete this landing page? The public link will stop working.')) return;
        try {
            const res = await apiFetch(`/api/landing-pages/${selectedId}`, { method: 'DELETE' });
            if (!res.ok) {
                const data = await res.json().catch(() => ({}));
                throw new Error(data.detail || 'Delete failed');
            }
            setSelectedId(null);
            setDraft(emptyDraft());
            await loadPages();
        } catch (e) {
            setError(e.message || 'Delete failed');
        }
    };

    const generateFromPrompt = async () => {
        if (!selectedId) return;
        const prompt = draft.prompt?.trim();
        if (!prompt || prompt.length < 8) {
            setError('Enter a prompt with at least 8 characters to generate.');
            return;
        }
        setGenerating(true);
        setError('');
        try {
            const res = await apiFetch(`/api/landing-pages/${selectedId}/generate`, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify({ prompt }),
            });
            const data = await res.json();
            if (!res.ok) throw new Error(data.detail || 'Generation failed');
            setPages((prev) => prev.map((p) => (p.id === data.id ? data : p)));
            const next = draftFromPage(data);
            skipAutosaveRef.current = true;
            lastSavedSnapshotRef.current = draftSnapshot(next);
            setDraft(next);
            setSaveState('saved');
        } catch (e) {
            setError(e.message || 'Generation failed');
        } finally {
            setGenerating(false);
        }
    };

    const uploadAsset = async (kind, file) => {
        if (!selectedId || !file) return;
        const setter = kind === 'banner' ? setUploadingBanner : setUploadingLogo;
        setter(true);
        setError('');
        try {
            const fd = new FormData();
            fd.append('file', file);
            const res = await apiFetch(`/api/landing-pages/${selectedId}/${kind}`, {
                method: 'POST',
                body: fd,
            });
            const data = await res.json();
            if (!res.ok) throw new Error(data.detail || 'Upload failed');
            setPages((prev) => prev.map((p) => (p.id === data.id ? data : p)));
            setDraft((d) => ({
                ...d,
                banner_url: data.banner_url ?? d.banner_url,
                logo_url: data.logo_url ?? d.logo_url,
                public_url: data.public_url || d.public_url,
            }));
        } catch (e) {
            setError(e.message || 'Upload failed');
        } finally {
            setter(false);
        }
    };

    const updateContent = (key, value) => {
        setDraft((d) => ({
            ...d,
            content: { ...d.content, [key]: value },
        }));
    };

    const updateBenefit = (idx, patch) => {
        setDraft((d) => ({
            ...d,
            content: {
                ...d.content,
                benefits: d.content.benefits.map((b, i) => (i === idx ? { ...b, ...patch } : b)),
            },
        }));
    };

    const previewCtaPublicId = useMemo(() => {
        if (draft.cta_form_public_id) return draft.cta_form_public_id;
        const form = ctaForms.find((f) => f.id === draft.cta_form_id);
        return form?.public_id || null;
    }, [draft.cta_form_id, draft.cta_form_public_id, ctaForms]);

    const publicUrl = draft.public_url || (selected?.public_url ?? '');

    return (
        <AppShell
            title="Landing Pages"
            subtitle="Generate appointment-style pages from a prompt, add your branding, and embed a CTA form."
        >
            <div className="w-full max-w-[1600px]">
                <div className="mb-6 flex flex-wrap items-center gap-3">
                    <Button type="button" variant="outline" className="gap-2" onClick={onBack}>
                        <ArrowLeft className="h-4 w-4" aria-hidden />
                        Back to settings
                    </Button>
                    <Button type="button" onClick={createPage} disabled={creating} className="gap-2">
                        {creating ? <Loader2 className="h-4 w-4 animate-spin" /> : <Plus className="h-4 w-4" />}
                        New page
                    </Button>
                </div>

                {error ? (
                    <p className="mb-4 text-sm text-red-600 rounded-lg border border-red-200 bg-red-50 px-3 py-2">
                        {error}
                    </p>
                ) : null}

                {loading ? (
                    <div className="flex justify-center py-20 text-slate-400">
                        <Loader2 className="h-10 w-10 animate-spin" />
                    </div>
                ) : (
                    <div className="grid gap-6 lg:grid-cols-[200px_minmax(0,1fr)] xl:grid-cols-[200px_minmax(280px,1fr)_minmax(520px,1.15fr)] 2xl:grid-cols-[200px_minmax(320px,0.95fr)_minmax(600px,1.25fr)]">
                        <aside className="rounded-2xl border border-slate-200 bg-white p-3 shadow-sm h-fit">
                            <p className="px-2 py-1 text-xs font-semibold uppercase tracking-wide text-slate-500">
                                Your pages
                            </p>
                            {pages.length === 0 ? (
                                <p className="px-2 py-4 text-sm text-slate-500">No pages yet.</p>
                            ) : (
                                <ul className="space-y-1">
                                    {pages.map((p) => (
                                        <li key={p.id}>
                                            <button
                                                type="button"
                                                onClick={() => selectPage(p)}
                                                className={cn(
                                                    'w-full rounded-lg px-3 py-2 text-left text-sm transition-colors',
                                                    selectedId === p.id
                                                        ? 'bg-violet-100 text-violet-800 font-medium'
                                                        : 'text-slate-700 hover:bg-slate-50'
                                                )}
                                            >
                                                {p.name || 'Untitled'}
                                            </button>
                                        </li>
                                    ))}
                                </ul>
                            )}
                        </aside>

                        <div className="space-y-6 min-w-0">
                            {!selected ? (
                                <div className="rounded-2xl border border-dashed border-slate-200 bg-white p-10 text-center text-slate-500">
                                    Create a landing page to generate copy and share a public link.
                                </div>
                            ) : (
                                <>
                                    <section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm space-y-4">
                                        <div className="flex flex-wrap items-end gap-3 justify-between">
                                            <div className="flex-1 min-w-[12rem]">
                                                <label className="text-xs font-medium text-slate-600">
                                                    Page name
                                                </label>
                                                <Input
                                                    value={draft.name}
                                                    onChange={(e) =>
                                                        setDraft((d) => ({ ...d, name: e.target.value }))
                                                    }
                                                    className="mt-1"
                                                />
                                            </div>
                                            <div className="flex items-center gap-3 pb-1">
                                                <SaveIndicator state={saveState} />
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    size="sm"
                                                    className="text-red-600"
                                                    onClick={deletePage}
                                                >
                                                    <Trash2 className="h-4 w-4" />
                                                </Button>
                                            </div>
                                        </div>

                                        <div>
                                            <label className="text-xs font-medium text-slate-600">
                                                AI prompt
                                            </label>
                                            <p className="text-[10px] text-slate-400 mt-0.5">
                                                Describe your offer, audience, and goal — AI fills the
                                                page template
                                            </p>
                                            <Textarea
                                                value={draft.prompt}
                                                onChange={(e) =>
                                                    setDraft((d) => ({ ...d, prompt: e.target.value }))
                                                }
                                                rows={3}
                                                className="mt-1 text-sm"
                                                placeholder="e.g. B2B demo booking page for our AI document platform targeting operations leaders..."
                                            />
                                            <Button
                                                type="button"
                                                className="mt-2 gap-2"
                                                onClick={generateFromPrompt}
                                                disabled={generating}
                                            >
                                                {generating ? (
                                                    <Loader2 className="h-4 w-4 animate-spin" />
                                                ) : (
                                                    <Sparkles className="h-4 w-4" />
                                                )}
                                                Generate page content
                                            </Button>
                                        </div>

                                        <div className="grid gap-4 sm:grid-cols-2">
                                            <div>
                                                <label className="text-xs font-medium text-slate-600">
                                                    Banner image
                                                </label>
                                                <label className="mt-1 flex cursor-pointer items-center gap-2 rounded-lg border border-dashed border-slate-200 px-3 py-2 text-xs text-slate-600 hover:bg-slate-50">
                                                    <ImagePlus className="h-4 w-4" />
                                                    {uploadingBanner ? 'Uploading…' : 'Upload banner'}
                                                    <input
                                                        type="file"
                                                        accept="image/*"
                                                        className="sr-only"
                                                        disabled={uploadingBanner}
                                                        onChange={(e) => {
                                                            const f = e.target.files?.[0];
                                                            if (f) uploadAsset('banner', f);
                                                            e.target.value = '';
                                                        }}
                                                    />
                                                </label>
                                            </div>
                                            <div>
                                                <label className="text-xs font-medium text-slate-600">
                                                    Logo
                                                </label>
                                                <label className="mt-1 flex cursor-pointer items-center gap-2 rounded-lg border border-dashed border-slate-200 px-3 py-2 text-xs text-slate-600 hover:bg-slate-50">
                                                    <ImagePlus className="h-4 w-4" />
                                                    {uploadingLogo ? 'Uploading…' : 'Upload logo'}
                                                    <input
                                                        type="file"
                                                        accept="image/*"
                                                        className="sr-only"
                                                        disabled={uploadingLogo}
                                                        onChange={(e) => {
                                                            const f = e.target.files?.[0];
                                                            if (f) uploadAsset('logo', f);
                                                            e.target.value = '';
                                                        }}
                                                    />
                                                </label>
                                            </div>
                                        </div>

                                        <div>
                                            <label className="text-xs font-medium text-slate-600">
                                                CTA form
                                            </label>
                                            <Select
                                                value={
                                                    draft.cta_form_id != null
                                                        ? String(draft.cta_form_id)
                                                        : 'none'
                                                }
                                                onValueChange={(v) => {
                                                    const id = v === 'none' ? null : parseInt(v, 10);
                                                    const form = ctaForms.find((f) => f.id === id);
                                                    setDraft((d) => ({
                                                        ...d,
                                                        cta_form_id: id,
                                                        cta_form_public_id: form?.public_id || null,
                                                    }));
                                                }}
                                            >
                                                <SelectTrigger className="mt-1 h-9 text-sm">
                                                    <SelectValue placeholder="Select a form" />
                                                </SelectTrigger>
                                                <SelectContent>
                                                    <SelectItem value="none">No form</SelectItem>
                                                    {ctaForms.map((f) => (
                                                        <SelectItem key={f.id} value={String(f.id)}>
                                                            {f.name}
                                                        </SelectItem>
                                                    ))}
                                                </SelectContent>
                                            </Select>
                                            {ctaForms.length === 0 ? (
                                                <p className="text-[10px] text-amber-600 mt-1">
                                                    Create a CTA form first under Manage CTA forms.
                                                </p>
                                            ) : null}
                                        </div>
                                    </section>

                                    <section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm space-y-4">
                                        <p className="text-xs font-semibold uppercase tracking-wide text-slate-500">
                                            Page copy
                                        </p>
                                        <div>
                                            <label className="text-[10px] text-slate-500">Headline</label>
                                            <Input
                                                value={draft.content.headline}
                                                onChange={(e) => updateContent('headline', e.target.value)}
                                                className="mt-0.5 h-9 text-sm"
                                            />
                                        </div>
                                        <div>
                                            <label className="text-[10px] text-slate-500">Subheadline</label>
                                            <Textarea
                                                value={draft.content.subheadline}
                                                onChange={(e) =>
                                                    updateContent('subheadline', e.target.value)
                                                }
                                                rows={2}
                                                className="text-sm"
                                            />
                                        </div>
                                        {draft.content.benefits.map((b, idx) => (
                                            <div
                                                key={idx}
                                                className="rounded-xl border border-slate-100 bg-slate-50/80 p-3 space-y-2"
                                            >
                                                <Input
                                                    value={b.title}
                                                    onChange={(e) =>
                                                        updateBenefit(idx, { title: e.target.value })
                                                    }
                                                    placeholder={`Benefit ${idx + 1} title`}
                                                    className="h-8 text-sm font-medium"
                                                />
                                                <Textarea
                                                    value={b.body}
                                                    onChange={(e) =>
                                                        updateBenefit(idx, { body: e.target.value })
                                                    }
                                                    rows={2}
                                                    className="text-sm"
                                                />
                                            </div>
                                        ))}
                                        <div>
                                            <label className="text-[10px] text-slate-500">
                                                Form heading
                                            </label>
                                            <Input
                                                value={draft.content.form_heading}
                                                onChange={(e) =>
                                                    updateContent('form_heading', e.target.value)
                                                }
                                                className="mt-0.5 h-9 text-sm"
                                            />
                                        </div>
                                        <div>
                                            <label className="text-[10px] text-slate-500">
                                                Form subtext
                                            </label>
                                            <Textarea
                                                value={draft.content.form_subtext}
                                                onChange={(e) =>
                                                    updateContent('form_subtext', e.target.value)
                                                }
                                                rows={2}
                                                className="text-sm"
                                            />
                                        </div>
                                        <div>
                                            <label className="text-[10px] text-slate-500">Footer</label>
                                            <Input
                                                value={draft.content.footer_text}
                                                onChange={(e) =>
                                                    updateContent('footer_text', e.target.value)
                                                }
                                                className="mt-0.5 h-9 text-sm"
                                            />
                                        </div>
                                    </section>

                                    <section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm space-y-3 xl:hidden">
                                        <PreviewBlock
                                            draft={draft}
                                            previewCtaPublicId={previewCtaPublicId}
                                            publicUrl={publicUrl}
                                        />
                                    </section>

                                    {publicUrl ? (
                                        <section className="rounded-2xl border border-slate-200 bg-white p-6 shadow-sm space-y-2">
                                            <p className="text-sm font-semibold text-slate-800">
                                                Public link
                                            </p>
                                            <p className="text-xs text-slate-500">
                                                Share on LinkedIn, email, or ads. Submissions go to your
                                                embedded CTA form → Leads.
                                            </p>
                                            <div className="flex flex-wrap items-center gap-2">
                                                <code className="text-xs bg-slate-100 px-2 py-1.5 rounded break-all flex-1 min-w-[12rem]">
                                                    {publicUrl}
                                                </code>
                                                <Button
                                                    type="button"
                                                    variant="outline"
                                                    size="sm"
                                                    className="gap-1"
                                                    onClick={() =>
                                                        publicUrl &&
                                                        navigator.clipboard.writeText(publicUrl)
                                                    }
                                                >
                                                    <ClipboardCopy className="h-3.5 w-3.5" />
                                                    Copy
                                                </Button>
                                                <a
                                                    href={publicUrl}
                                                    target="_blank"
                                                    rel="noreferrer"
                                                    className="inline-flex h-9 items-center justify-center rounded-md border border-slate-200 bg-white px-3 text-sm font-medium hover:bg-slate-50 gap-1"
                                                >
                                                    Open
                                                    <ExternalLink className="h-3.5 w-3.5" />
                                                </a>
                                            </div>
                                        </section>
                                    ) : null}
                                </>
                            )}
                        </div>

                        {selected ? (
                            <aside className="hidden xl:block min-w-0">
                                <div className="sticky top-4 rounded-2xl border border-slate-200 bg-white p-3 shadow-sm w-full">
                                    <PreviewBlock
                                        draft={draft}
                                        previewCtaPublicId={previewCtaPublicId}
                                        publicUrl={publicUrl}
                                    />
                                </div>
                            </aside>
                        ) : null}
                    </div>
                )}
            </div>
        </AppShell>
    );
}

function PreviewBlock({ draft, previewCtaPublicId, publicUrl }) {
    return (
        <div className="space-y-2">
            <div className="flex items-center justify-between gap-2 px-1">
                <p className="text-sm font-semibold text-slate-800">Live preview</p>
                {publicUrl ? (
                    <a
                        href={publicUrl}
                        target="_blank"
                        rel="noreferrer"
                        className="inline-flex items-center gap-1 text-xs text-violet-600 hover:underline"
                    >
                        Open tab
                        <ExternalLink className="h-3 w-3" />
                    </a>
                ) : null}
            </div>
            <div className="max-h-[78vh] overflow-y-auto overflow-x-auto rounded-xl w-full">
                <LandingPageTemplate
                    preview
                    className="w-full"
                    content={draft.content}
                    bannerUrl={draft.banner_url}
                    logoUrl={draft.logo_url}
                    ctaFormPublicId={previewCtaPublicId}
                />
            </div>
        </div>
    );
}
