import { updateDocumentSeoFields } from '../actions.js';
import { getActuateConfig } from '../config/runtime.js';
import { isPublicContentCollection, prepareContentStructuredData } from './schema-sync.js';
import { frontEndContentCollectionTypes } from './audit-runner.js';
function isPlainObject(v) {
    return !!v && typeof v === 'object' && !Array.isArray(v);
}
function pickString(...candidates) {
    for (const c of candidates) {
        if (typeof c === 'string' && c.trim().length > 0)
            return c.trim();
    }
    return undefined;
}
function hasJsonLdColumn(structured) {
    return !!structured && Object.keys(structured).length > 0;
}
function needsMigration(status, data, structured) {
    const hasType = pickString(data.structuredDataType, data.schemaType);
    if (!hasType)
        return true;
    if (status === 'PUBLISHED' && !hasJsonLdColumn(structured))
        return true;
    return false;
}
/**
 * Backfill schema type fields (and published JSON-LD) for content documents.
 */
export async function migrateStructuredDataFields(ctx, options = {}) {
    const dryRun = options.dryRun ?? false;
    const batchSize = options.batchSize && options.batchSize > 0 ? options.batchSize : 100;
    const config = getActuateConfig();
    const defaultCollections = Object.keys(frontEndContentCollectionTypes(config));
    const targetCollections = options.collections && options.collections.length > 0 ? options.collections : defaultCollections;
    const result = {
        scanned: 0,
        migrated: 0,
        skipped: 0,
        migratedIds: [],
    };
    if (targetCollections.length === 0) {
        return result;
    }
    // eslint-disable-next-line @typescript-eslint/no-explicit-any -- Prisma client is intentionally untyped at the core/config boundary.
    const db = ctx.db;
    let cursor;
    for (;;) {
        const batch = await db.document.findMany({
            where: {
                deletedAt: null,
                collection: { in: targetCollections },
            },
            orderBy: { id: 'asc' },
            take: batchSize,
            ...(cursor ? { skip: 1, cursor: { id: cursor } } : {}),
            select: {
                id: true,
                collection: true,
                slug: true,
                status: true,
                data: true,
                structuredData: true,
                publishedAt: true,
                updatedAt: true,
            },
        });
        if (batch.length === 0)
            break;
        cursor = batch[batch.length - 1].id;
        for (const doc of batch) {
            result.scanned++;
            const data = isPlainObject(doc.data) ? doc.data : null;
            if (!data) {
                result.skipped++;
                continue;
            }
            const collectionDef = config?.collections?.[doc.collection] ?? null;
            if (!isPublicContentCollection(collectionDef)) {
                result.skipped++;
                continue;
            }
            const structured = isPlainObject(doc.structuredData) ? doc.structuredData : null;
            if (!needsMigration(doc.status, data, structured)) {
                result.skipped++;
                continue;
            }
            const prep = prepareContentStructuredData(doc.collection, data, {
                collectionDef,
                config,
                existingStructuredData: structured,
                publishing: doc.status === 'PUBLISHED',
                doc: {
                    id: doc.id,
                    slug: doc.slug,
                    publishedAt: doc.publishedAt,
                    updatedAt: doc.updatedAt,
                },
            });
            if (!dryRun) {
                await updateDocumentSeoFields(doc.collection, doc.id, {
                    structuredDataType: prep.data.structuredDataType,
                    schemaType: prep.data.schemaType,
                }, ctx);
                if (doc.status === 'PUBLISHED' && prep.structuredData && !hasJsonLdColumn(structured)) {
                    await db.document.update({
                        where: { id: doc.id },
                        data: { structuredData: prep.structuredData },
                    });
                }
            }
            result.migrated++;
            result.migratedIds.push(doc.id);
        }
        if (batch.length < batchSize)
            break;
    }
    return result;
}
//# sourceMappingURL=migrate-schema.js.map