import { createDbService } from '@/server/services/db.js';
/**
 * Slug regeneration module — Plan 4 Task 3.
 *
 * Writes a deal_slug_redirects row for the current slug, then nulls out
 * the slug + titleSourceHash so the worker re-pins a new slug after
 * re-translating the title.
 *
 * Invariant (Plan 2): ensureSlugPinned only writes when slug is null.
 * This module deliberately nulls the slug → next translation re-pins it.
 * Stale URLs are handled by the redirect row written atomically here.
 */

import { dealTranslations } from '@/server/db/schema.js';
import { and, eq } from 'drizzle-orm';
import { env } from '@/server/env.js';
import { enqueueDealTranslation } from '@/server/translation/jobs/enqueue.js';
import { regenerateDealTranslationSlug } from '@/server/db/queries/translation/deal-translations.js';

export async function regenerateSlug(input: {
  dealId: string;
  locale: string;
  actorId: string;
}): Promise<void> {
  const db = createDbService({ DATABASE_URL: env.DATABASE_URL });

  await db.transaction(async (tx) => {
    const row = await tx.query.dealTranslations.findFirst({
      where: and(
        eq(dealTranslations.dealId, input.dealId),
        eq(dealTranslations.locale, input.locale),
      ),
    });

    if (!row) throw new Error('translation row missing');
    if (!row.slug) throw new Error('slug not yet pinned — nothing to regenerate');

    // Write the redirect row first (idempotent on unique (locale, oldSlug)).
    await regenerateDealTranslationSlug(tx, {
      dealId: input.dealId,
      locale: input.locale,
      oldSlug: row.slug,
    });
  });

  // Re-enqueue translation outside the transaction (idempotent).
  await enqueueDealTranslation(db, input.dealId, { targetLocales: [input.locale] });
}
