import { SEEDED_TEST_CONTENT } from "../../fixtures/test-constants"
import { createCollectionEntry, deleteCollectionEntry, listCollectionEntries } from "./admin-api"

type ContentEntry = {
    id?: string
    _id?: string | { $oid?: string }
    _testdata?: boolean
    translationKey?: string
    path?: string
    title?: string
    [key: string]: unknown
}

function getEntryId(entry: ContentEntry): string | undefined {
    if (typeof entry.id === "string") return entry.id
    if (typeof entry._id === "string") return entry._id
    if (entry._id && typeof entry._id === "object" && typeof entry._id.$oid === "string") return entry._id.$oid
    return undefined
}

const SEEDED_TRANSLATION_KEYS = new Set<string>(Object.values(SEEDED_TEST_CONTENT).map((entry) => entry.translationKey))
const SEEDED_PATHS = new Set<string>(Object.values(SEEDED_TEST_CONTENT).map((entry) => entry.path))
const SEEDED_MEDIA_DATA_URI =
    "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVQIHWP4////fwAJ+wP9KobjigAAAABJRU5ErkJggg=="

function isSeededContentEntry(entry: ContentEntry): boolean {
    if (entry._testdata === true) {
        return true
    }

    if (typeof entry.translationKey === "string" && SEEDED_TRANSLATION_KEYS.has(entry.translationKey)) {
        return true
    }

    if (typeof entry.path === "string" && SEEDED_PATHS.has(entry.path)) {
        return true
    }

    return false
}

function isSeededMedialibEntry(entry: ContentEntry): boolean {
    return entry._testdata === true
}

const SEEDED_MEDIALIB_ENTRIES = [
    {
        _testdata: true,
        title: "Playwright Seed Image",
        alt: {
            de: "Playwright Seed Bild",
            en: "Playwright seed image",
        },
        description: "Deterministisches Medialib-Bild fuer Admin- und Preview-Tests.",
        tags: ["playwright", "seed", "preview"],
        file: {
            src: SEEDED_MEDIA_DATA_URI,
        },
    },
] as const

function getSeededContentEntries(previewImageId: string) {
    return [
        {
            _testdata: true,
            active: true,
            lang: "de",
            translationKey: SEEDED_TEST_CONTENT.home.translationKey,
            name: "Playwright Startseite",
            path: SEEDED_TEST_CONTENT.home.path,
            meta: {
                title: "Playwright Startseite",
                description: "Seeded Startseite fuer stabile Playwright-Tests.",
                keywords: ["playwright", "seed", "e2e"],
            },
            blocks: [
                {
                    type: "hero",
                    headline: "Playwright Seed Startseite",
                    headlineH1: true,
                    tagline: "Deterministische Testdaten",
                    subline: "Diese Seite wird vor dem Testlauf frisch ueber die Admin-API angelegt.",
                    containerWidth: "wide",
                    callToAction: {
                        buttonText: "Zum Kontakt",
                        buttonLink: `/de${SEEDED_TEST_CONTENT.contact.path}`,
                    },
                },
                {
                    type: "features",
                    anchorId: "seed-features",
                    headline: "Stabile Grundlage fuer Frontend-Tests",
                    tagline: "Seed",
                    padding: { top: "md", bottom: "md" },
                    featureBoxes: [
                        {
                            icon: "lightning",
                            title: "Frisch angelegt",
                            text: "Die Inhalte werden in globalSetup erstellt statt aus Demo-Daten uebernommen.",
                        },
                        {
                            icon: "database",
                            title: "API-nah",
                            text: "Die Seed-Daten kommen ueber dieselben Collection-Endpunkte wie das CMS.",
                        },
                        {
                            icon: "globe",
                            title: "Mehrsprachig",
                            text: "DE und EN teilen sich denselben translationKey fuer Routing-Checks.",
                        },
                    ],
                },
                {
                    type: "richtext",
                    anchorId: "seed-richtext",
                    headline: "Mehr Kontext",
                    tagline: "API + UI",
                    padding: { top: "md", bottom: "md" },
                    imagePosition: "none",
                    text: "<p>Dieser Richtext-Block prueft, dass formatierter HTML-Inhalt im SPA gerendert wird.</p>",
                },
                {
                    type: "accordion",
                    anchorId: "seed-faq",
                    headline: "Hauefige Fragen",
                    tagline: "Verhalten",
                    padding: { top: "md", bottom: "md" },
                    accordionItems: [
                        {
                            question: "Warum Seed-Daten?",
                            answer: "<p>Damit Tests nicht blind auf bestehende Inhalte oder Demo-Routen vertrauen.</p>",
                            open: true,
                        },
                        {
                            question: "Was wird geprueft?",
                            answer: "<p>API-Antworten, Routing, Sprachwechsel und Block-Rendering.</p>",
                            open: false,
                        },
                    ],
                },
            ],
        },
        {
            _testdata: true,
            active: true,
            lang: "en",
            translationKey: SEEDED_TEST_CONTENT.home.translationKey,
            name: "Playwright Home",
            path: SEEDED_TEST_CONTENT.home.path,
            meta: {
                title: "Playwright Home",
                description: "Seeded home page for stable Playwright tests.",
                keywords: ["playwright", "seed", "home"],
            },
            blocks: [
                {
                    type: "hero",
                    headline: "Playwright Seed Home",
                    headlineH1: true,
                    tagline: "Deterministic fixtures",
                    subline: "This page is recreated before every test run through the admin API.",
                    containerWidth: "wide",
                    callToAction: {
                        buttonText: "Go to contact",
                        buttonLink: `/en${SEEDED_TEST_CONTENT.contact.path}`,
                    },
                },
                {
                    type: "features",
                    anchorId: "seed-features",
                    headline: "Stable frontend coverage",
                    tagline: "Seed",
                    padding: { top: "md", bottom: "md" },
                    featureBoxes: [
                        {
                            icon: "lightning",
                            title: "Freshly created",
                            text: "The content is created during globalSetup instead of relying on demo data.",
                        },
                        {
                            icon: "database",
                            title: "API-backed",
                            text: "The seed uses the same collection endpoints as the CMS itself.",
                        },
                        {
                            icon: "globe",
                            title: "Localized",
                            text: "DE and EN share the same translationKey for route switching checks.",
                        },
                    ],
                },
                {
                    type: "richtext",
                    anchorId: "seed-richtext",
                    headline: "More context",
                    tagline: "API + UI",
                    padding: { top: "md", bottom: "md" },
                    imagePosition: "none",
                    text: "<p>This richtext block proves that formatted HTML content renders in the SPA.</p>",
                },
                {
                    type: "accordion",
                    anchorId: "seed-faq",
                    headline: "Common questions",
                    tagline: "Behavior",
                    padding: { top: "md", bottom: "md" },
                    accordionItems: [
                        {
                            question: "Why seeded data?",
                            answer: "<p>So the tests do not depend on existing demo pages or editorial content.</p>",
                            open: true,
                        },
                        {
                            question: "What is covered?",
                            answer: "<p>API responses, routing, locale switching and block rendering.</p>",
                            open: false,
                        },
                    ],
                },
            ],
        },
        {
            _testdata: true,
            active: true,
            lang: "de",
            translationKey: SEEDED_TEST_CONTENT.pagebuilderPreview.translationKey,
            name: "Playwright Pagebuilder Preview",
            path: SEEDED_TEST_CONTENT.pagebuilderPreview.path,
            meta: {
                title: "Playwright Pagebuilder Preview",
                description: "Seeded Seite fuer Pagebuilder- und Medialib-Vorschau-Tests.",
                keywords: ["playwright", "pagebuilder", "preview"],
            },
            blocks: [
                {
                    type: "hero",
                    headline: "Playwright Registry Hero",
                    headlineH1: true,
                    tagline: "Admin Preview",
                    subline: "Dieses Hero-Preview prueft den Block-Registry-Pfad inklusive Bild.",
                    containerWidth: "wide",
                    heroImage: {
                        image: previewImageId,
                    },
                },
                {
                    type: "richtext",
                    anchorId: "pagebuilder-preview-richtext",
                    headline: "Richtext mit Bild",
                    tagline: "Shared Media Widget",
                    padding: { top: "md", bottom: "md" },
                    imagePosition: "right",
                    image: previewImageId,
                    text: "<p>Dieser Block prueft, dass ein image-gestuetzter Preview-Block im Admin ueber dieselbe Registry und dasselbe Bild-Widget rendert.</p>",
                },
            ],
        },
        {
            _testdata: true,
            active: true,
            lang: "de",
            translationKey: SEEDED_TEST_CONTENT.contact.translationKey,
            name: "Playwright Kontakt",
            path: SEEDED_TEST_CONTENT.contact.path,
            meta: {
                title: "Playwright Kontakt",
                description: "Seeded Kontaktseite fuer Playwright.",
                keywords: ["playwright", "kontakt"],
            },
            blocks: [
                {
                    type: "hero",
                    headline: "Kontakt fuer Testlauf",
                    headlineH1: true,
                    tagline: "Seed",
                    subline: "Diese Seite prueft das aktuelle ContactForm-Rendering.",
                },
                {
                    type: "contact-form",
                    anchorId: "kontaktformular",
                    headline: "Schreibe uns",
                    padding: { top: "md", bottom: "md" },
                },
            ],
        },
        {
            _testdata: true,
            active: true,
            lang: "en",
            translationKey: SEEDED_TEST_CONTENT.contact.translationKey,
            name: "Playwright Contact",
            path: SEEDED_TEST_CONTENT.contact.path,
            meta: {
                title: "Playwright Contact",
                description: "Seeded contact page for Playwright.",
                keywords: ["playwright", "contact"],
            },
            blocks: [
                {
                    type: "hero",
                    headline: "Contact for the test run",
                    headlineH1: true,
                    tagline: "Seed",
                    subline: "This page verifies the current contact form rendering.",
                },
                {
                    type: "contact-form",
                    anchorId: "contact-form",
                    headline: "Write to us",
                    padding: { top: "md", bottom: "md" },
                },
            ],
        },
        {
            _testdata: true,
            active: false,
            lang: "de",
            translationKey: SEEDED_TEST_CONTENT.inactive.translationKey,
            name: "Playwright Inaktiv",
            path: SEEDED_TEST_CONTENT.inactive.path,
            meta: {
                title: "Playwright Inaktiv",
                description: "Nicht aktive Seed-Seite fuer Routing-Tests.",
                keywords: ["playwright", "inactive"],
            },
            blocks: [
                {
                    type: "richtext",
                    anchorId: "inactive",
                    headline: "Sollte nicht sichtbar sein",
                    tagline: "Seed",
                    padding: { top: "md", bottom: "md" },
                    imagePosition: "none",
                    text: "<p>Diese Seite ist absichtlich inaktiv und darf im Frontend nicht erscheinen.</p>",
                },
            ],
        },
    ] as const
}

async function cleanupSeededMedialibEntries(baseURL: string): Promise<number> {
    const medialibEntries = await listCollectionEntries<ContentEntry>(baseURL, "medialib")
    const seededEntries = medialibEntries.filter((entry) => isSeededMedialibEntry(entry))

    let deleted = 0
    for (const entry of seededEntries) {
        const entryId = getEntryId(entry)
        if (!entryId) continue

        const ok = await deleteCollectionEntry(baseURL, "medialib", entryId)
        if (ok) deleted++
    }

    return deleted
}

async function seedMedialibEntries(baseURL: string): Promise<{ created: number; previewImageId: string }> {
    let previewImageId = ""
    let created = 0

    for (const entry of SEEDED_MEDIALIB_ENTRIES) {
        const createdEntry = await createCollectionEntry<ContentEntry>(baseURL, "medialib", {
            ...(entry as Record<string, unknown>),
        })
        const entryId = getEntryId(createdEntry)
        if (!entryId) {
            throw new Error("Seeded medialib entry was created without an id")
        }

        previewImageId = entryId
        created++
    }

    return { created, previewImageId }
}

export async function cleanupSeededTestContent(baseURL: string): Promise<number> {
    const contentEntries = await listCollectionEntries<ContentEntry>(baseURL, "content")
    // Cleanup runs before every seed pass so leftovers from aborted test runs
    // are removed on the next successful global setup.
    const seededEntries = contentEntries.filter((entry) => isSeededContentEntry(entry))

    let deleted = 0
    for (const entry of seededEntries) {
        const entryId = getEntryId(entry)
        if (!entryId) continue

        const ok = await deleteCollectionEntry(baseURL, "content", entryId)
        if (ok) deleted++
    }

    const deletedMediaEntries = await cleanupSeededMedialibEntries(baseURL)
    return deleted + deletedMediaEntries
}

export async function seedTestContent(baseURL: string): Promise<number> {
    const mediaSeed = await seedMedialibEntries(baseURL)
    let created = mediaSeed.created

    for (const entry of getSeededContentEntries(mediaSeed.previewImageId)) {
        await createCollectionEntry(baseURL, "content", entry as unknown as Record<string, unknown>)
        created++
    }
    return created
}

export async function ensureSeededTestContent(baseURL: string): Promise<{ deleted: number; created: number }> {
    const deleted = await cleanupSeededTestContent(baseURL)
    const created = await seedTestContent(baseURL)
    return { deleted, created }
}
