import { csrfHeaders } from '@/admin/settings/types';
import { Button, Card, Field } from '@/Components/ui';
import type { PageConfig, Section } from '@/marketing/cms-types';
import {
    AlertCircle,
    ArrowLeft,
    ExternalLink,
    Eye,
    EyeOff,
    Plus,
    Trash2,
} from 'lucide-react';
import { useState, type SubmitEvent as ReactSubmitEvent } from 'react';
import WelcomeEditor from './WelcomeEditor';
import type { PageSeoOverride } from '@/marketing/cms-types';

export type CustomPage = {
    slug: string;
    title: string;
    enabled: boolean;
    sections: Section[];
    seo?: PageSeoOverride;
};

export type CustomPagesPayload = {
    version: number;
    pages: CustomPage[];
};

type Props = {
    value: CustomPagesPayload;
    reservedSlugs: string[];
    onSaved: (next: CustomPagesPayload) => void;
};

/**
 * Admin UI for managing custom marketing pages. Two views:
 *   - List: all pages + Add affordance + per-row enable/delete
 *   - Edit: WelcomeEditor with saveOverride wired to the per-slug endpoint
 * Selected slug lives in local state; transitioning back to list returns
 * to the list view without losing parent state (other tabs etc).
 */
export default function CustomPagesManager({ value, reservedSlugs, onSaved }: Props) {
    const [editingSlug, setEditingSlug] = useState<string | null>(null);

    const editingPage = editingSlug
        ? value.pages.find((p) => p.slug === editingSlug) ?? null
        : null;

    if (editingPage) {
        return (
            <EditView
                page={editingPage}
                onBack={() => setEditingSlug(null)}
                onSaved={onSaved}
            />
        );
    }

    return (
        <ListView
            value={value}
            reservedSlugs={reservedSlugs}
            onSaved={onSaved}
            onEdit={setEditingSlug}
        />
    );
}

/* ─────────────────────────────────────────────────── List view ── */

function ListView({
    value,
    reservedSlugs,
    onSaved,
    onEdit,
}: {
    value: CustomPagesPayload;
    reservedSlugs: string[];
    onSaved: (next: CustomPagesPayload) => void;
    onEdit: (slug: string) => void;
}) {
    const [addOpen, setAddOpen] = useState(false);

    return (
        <Card padding="lg">
            <header className="mb-5 flex items-start justify-between gap-4">
                <div>
                    <h2 className="text-base font-semibold tracking-tight text-foreground">
                        Custom pages
                    </h2>
                    <p className="mt-1 text-[12px] text-muted-foreground">
                        Admin-created marketing pages (changelog, case studies,
                        feature deep-dives, etc). Each lives at{' '}
                        <code className="rounded bg-muted/40 px-1 py-0.5 text-[11px]">
                            /{'{slug}'}
                        </code>{' '}
                        and uses the same section types as built-in pages. Link to
                        them from the Header or Footer editor.
                    </p>
                </div>
                {!addOpen && (
                    <Button
                        type="button"
                        variant="primary"
                        size="sm"
                        onClick={() => setAddOpen(true)}
                        data-testid="admin-marketing-custom-pages-add"
                    >
                        <Plus className="h-3.5 w-3.5" strokeWidth={2.5} />
                        Add page
                    </Button>
                )}
            </header>

            {addOpen && (
                <AddPageForm
                    reservedSlugs={reservedSlugs}
                    existingSlugs={value.pages.map((p) => p.slug)}
                    onCancel={() => setAddOpen(false)}
                    onSaved={(next) => {
                        onSaved(next);
                        setAddOpen(false);
                    }}
                />
            )}

            {value.pages.length === 0 && !addOpen && (
                <p className="rounded-lg border border-dashed border-border bg-muted/20 px-3 py-6 text-center text-[12px] text-muted-foreground">
                    No custom pages yet. Click <strong>Add page</strong> to
                    create one.
                </p>
            )}

            {value.pages.length > 0 && (
                <ul className="space-y-2">
                    {value.pages.map((page) => (
                        <PageRow
                            key={page.slug}
                            page={page}
                            onSaved={onSaved}
                            onEdit={() => onEdit(page.slug)}
                        />
                    ))}
                </ul>
            )}
        </Card>
    );
}

function PageRow({
    page,
    onSaved,
    onEdit,
}: {
    page: CustomPage;
    onSaved: (next: CustomPagesPayload) => void;
    onEdit: () => void;
}) {
    const [busy, setBusy] = useState(false);
    const [confirmDelete, setConfirmDelete] = useState(false);

    const togglePublish = async () => {
        if (busy) return;
        setBusy(true);
        try {
            const res = await fetch(`/admin/marketing/custom-pages/${page.slug}`, {
                method: 'PATCH',
                credentials: 'same-origin',
                headers: csrfHeaders(),
                body: JSON.stringify({
                    sections: page.sections,
                    enabled: !page.enabled,
                    title: page.title,
                }),
            });
            if (!res.ok) return;
            const body = (await res.json()) as { customPages: CustomPagesPayload };
            if (body?.customPages) onSaved(body.customPages);
        } finally {
            setBusy(false);
        }
    };

    const remove = async () => {
        if (busy) return;
        setBusy(true);
        try {
            const res = await fetch(`/admin/marketing/custom-pages/${page.slug}`, {
                method: 'DELETE',
                credentials: 'same-origin',
                headers: csrfHeaders(),
            });
            if (!res.ok) return;
            const body = (await res.json()) as { customPages: CustomPagesPayload };
            if (body?.customPages) onSaved(body.customPages);
        } finally {
            setBusy(false);
            setConfirmDelete(false);
        }
    };

    return (
        <li
            className="rounded-lg border border-border bg-background"
            data-testid={`admin-marketing-custom-page-${page.slug}`}
        >
            <div className="flex flex-wrap items-center gap-3 p-3">
                <button
                    type="button"
                    onClick={onEdit}
                    className="min-w-0 flex-1 text-left"
                    data-testid={`admin-marketing-custom-page-${page.slug}-edit`}
                >
                    <div className="flex items-center gap-2">
                        <span className="text-[13px] font-semibold text-foreground">
                            {page.title}
                        </span>
                        <span
                            className={
                                'rounded px-1.5 py-0.5 text-[10px] font-medium uppercase tracking-wide ' +
                                (page.enabled
                                    ? 'bg-accent/15 text-accent'
                                    : 'bg-muted text-muted-foreground')
                            }
                        >
                            {page.enabled ? 'Published' : 'Draft'}
                        </span>
                    </div>
                    <p className="mt-0.5 text-[11px] text-muted-foreground">
                        /{page.slug} · {page.sections.length} section
                        {page.sections.length === 1 ? '' : 's'}
                    </p>
                </button>
                <div className="flex items-center gap-2">
                    {page.enabled && (
                        <a
                            href={`/${page.slug}`}
                            target="_blank"
                            rel="noopener noreferrer"
                            className="inline-flex items-center gap-1 text-[11px] font-medium text-accent transition-opacity hover:opacity-80"
                            title="Open in new tab"
                        >
                            <ExternalLink className="h-3 w-3" />
                            View
                        </a>
                    )}
                    <Button
                        type="button"
                        variant="secondary"
                        size="sm"
                        onClick={togglePublish}
                        disabled={busy}
                        title={page.enabled ? 'Unpublish' : 'Publish'}
                    >
                        {page.enabled ? (
                            <EyeOff className="h-3.5 w-3.5" />
                        ) : (
                            <Eye className="h-3.5 w-3.5" />
                        )}
                    </Button>
                    <Button
                        type="button"
                        variant="secondary"
                        size="sm"
                        onClick={() => setConfirmDelete((v) => !v)}
                        disabled={busy}
                        title="Delete page"
                        data-testid={`admin-marketing-custom-page-${page.slug}-delete`}
                    >
                        <Trash2 className="h-3.5 w-3.5 text-destructive" />
                    </Button>
                </div>
            </div>
            {confirmDelete && (
                <div className="border-t border-border bg-destructive/5 px-3 py-2 text-[12px]">
                    <div className="flex flex-wrap items-center justify-between gap-3">
                        <span>
                            Delete <strong>{page.title}</strong>? This can't be undone.
                        </span>
                        <div className="flex gap-2">
                            <Button
                                type="button"
                                variant="ghost"
                                size="sm"
                                onClick={() => setConfirmDelete(false)}
                                disabled={busy}
                            >
                                Cancel
                            </Button>
                            <Button
                                type="button"
                                variant="primary"
                                size="sm"
                                onClick={remove}
                                disabled={busy}
                            >
                                Delete
                            </Button>
                        </div>
                    </div>
                </div>
            )}
        </li>
    );
}

function AddPageForm({
    reservedSlugs,
    existingSlugs,
    onCancel,
    onSaved,
}: {
    reservedSlugs: string[];
    existingSlugs: string[];
    onCancel: () => void;
    onSaved: (next: CustomPagesPayload) => void;
}) {
    const [slug, setSlug] = useState('');
    const [title, setTitle] = useState('');
    const [error, setError] = useState<string | null>(null);
    const [saving, setSaving] = useState(false);

    const submit = async (e: ReactSubmitEvent) => {
        e.preventDefault();
        setError(null);

        const trimmedSlug = slug.trim().toLowerCase();
        const trimmedTitle = title.trim();

        if (!/^[a-z0-9-]+$/.test(trimmedSlug)) {
            setError('Slug must be lowercase letters, numbers, and hyphens only.');
            return;
        }
        if (reservedSlugs.includes(trimmedSlug)) {
            setError(`"${trimmedSlug}" is a reserved path.`);
            return;
        }
        if (existingSlugs.includes(trimmedSlug)) {
            setError(`A page with slug "${trimmedSlug}" already exists.`);
            return;
        }
        if (!trimmedTitle) {
            setError('Title is required.');
            return;
        }

        setSaving(true);
        try {
            const res = await fetch('/admin/marketing/custom-pages', {
                method: 'POST',
                credentials: 'same-origin',
                headers: csrfHeaders(),
                body: JSON.stringify({ slug: trimmedSlug, title: trimmedTitle }),
            });
            if (res.status === 422) {
                const body = await res.json().catch(() => null);
                const firstError =
                    body?.errors?.slug?.[0] ??
                    body?.errors?.title?.[0] ??
                    body?.message ??
                    'Validation failed.';
                setError(firstError);
                return;
            }
            if (!res.ok) {
                setError(`Save failed (${res.status}).`);
                return;
            }
            const body = (await res.json()) as { customPages: CustomPagesPayload };
            if (body?.customPages) onSaved(body.customPages);
        } catch {
            setError('Network error. Try again.');
        } finally {
            setSaving(false);
        }
    };

    return (
        <form
            onSubmit={submit}
            className="mb-3 rounded-lg border border-accent/40 bg-accent/5 p-4"
            data-testid="admin-marketing-custom-pages-add-form"
        >
            <p className="mb-3 text-[11px] font-medium uppercase tracking-wide text-muted-foreground">
                New page
            </p>
            <div className="grid gap-3 sm:grid-cols-[1fr_1fr]">
                <Field
                    id="custom-page-slug"
                    label="Slug"
                    value={slug}
                    onChange={(ev) => setSlug(ev.target.value)}
                    placeholder="changelog"
                    hint="Lowercase letters, numbers, hyphens. Lives at /your-slug."
                    labelClassName="text-[11px] font-medium"
                />
                <Field
                    id="custom-page-title"
                    label="Title"
                    value={title}
                    onChange={(ev) => setTitle(ev.target.value)}
                    placeholder="Changelog"
                    hint="Shown in browser tab + can be referenced from your hero block."
                    labelClassName="text-[11px] font-medium"
                />
            </div>
            {error && (
                <div
                    className="mt-3 flex items-start gap-2 rounded-md border border-destructive/40 bg-destructive/5 px-3 py-2 text-[12px] text-destructive"
                    role="alert"
                >
                    <AlertCircle className="mt-0.5 h-3.5 w-3.5" />
                    <span>{error}</span>
                </div>
            )}
            <div className="mt-3 flex items-center gap-2">
                <Button type="submit" variant="primary" size="sm" disabled={saving}>
                    {saving ? 'Creating…' : 'Create page'}
                </Button>
                <Button
                    type="button"
                    variant="ghost"
                    size="sm"
                    onClick={onCancel}
                    disabled={saving}
                >
                    Cancel
                </Button>
            </div>
        </form>
    );
}

/* ────────────────────────────────────────────────── Edit view ── */

function EditView({
    page,
    onBack,
    onSaved,
}: {
    page: CustomPage;
    onBack: () => void;
    onSaved: (next: CustomPagesPayload) => void;
}) {
    const value: PageConfig = {
        version: 1,
        sections: page.sections,
        enabled: page.enabled,
        seo: page.seo,
    };

    return (
        <div className="space-y-4">
            <div className="flex flex-wrap items-center justify-between gap-3">
                <button
                    type="button"
                    onClick={onBack}
                    className="inline-flex items-center gap-1.5 text-[12px] font-medium text-accent transition-opacity hover:opacity-80"
                >
                    <ArrowLeft className="h-3.5 w-3.5" />
                    All custom pages
                </button>
                <a
                    href={`/${page.slug}`}
                    target="_blank"
                    rel="noopener noreferrer"
                    className="inline-flex items-center gap-1.5 text-[12px] text-muted-foreground transition-colors hover:text-accent"
                >
                    <ExternalLink className="h-3.5 w-3.5" />
                    /{page.slug}
                </a>
            </div>
            <WelcomeEditor
                value={value}
                pageKey="about"
                headerCopyOverride={{
                    heading: page.title,
                    description: `Editing /${page.slug}. Unpublished pages 404 — flip the publish toggle when ready.`,
                }}
                saveOverride={async ({ sections, enabled, seo }) => {
                    const res = await fetch(
                        `/admin/marketing/custom-pages/${page.slug}`,
                        {
                            method: 'PATCH',
                            credentials: 'same-origin',
                            headers: csrfHeaders(),
                            body: JSON.stringify({
                                sections,
                                enabled,
                                title: page.title,
                                seo,
                            }),
                        },
                    );
                    if (!res.ok) {
                        throw new Error(`Save failed (${res.status}).`);
                    }
                    const body = (await res.json()) as { customPages: CustomPagesPayload };
                    onSaved(body.customPages);
                    // Find the saved version of this page in the response.
                    const updated = body.customPages.pages.find(
                        (p) => p.slug === page.slug,
                    );
                    return {
                        version: 1,
                        sections: updated?.sections ?? sections,
                        enabled: updated?.enabled ?? enabled,
                        seo: updated?.seo ?? seo,
                    };
                }}
                onSaved={() => {
                    // Handled inside saveOverride above (parent already got the new state).
                }}
            />
        </div>
    );
}
