/**
 * Köa AI-översättning (TRANSLATE_RECIPE) för ALLA publicerade recept × målspråk.
 * Hoppar över (recept, språk) som redan har en översättningsrad – idempotent och
 * resumbar, så du kan köra om utan att betala för samma jobb två gånger.
 *
 * Workern (Fönster C) MÅSTE köra med en RIKTIG AI-nyckel (inte mock) för att
 * jobben ska bli riktiga översättningar. Jobben sparas som utkast (draft_ai) –
 * publicera dem sedan med publish-translations.ts.
 *
 * Kör från repo-roten:
 *   pnpm --filter @app/worker exec tsx scripts/translate-recipes.ts es      # bara spanska (testa först!)
 *   pnpm --filter @app/worker exec tsx scripts/translate-recipes.ts es,de   # flera
 *   pnpm --filter @app/worker exec tsx scripts/translate-recipes.ts all     # alla 11 språk
 *
 * Kräver DATABASE_URL och REDIS_URL i miljön (samma som API/worker använder).
 */
import { config as loadDotenv } from "dotenv";
import { existsSync } from "node:fs";
import path from "node:path";
import IORedis from "ioredis";
import { Queue } from "bullmq";
import { eq } from "drizzle-orm";
import { createDatabase, schema } from "@app/database";
import { JOB_QUEUE_NAME } from "@app/shared-types";

// Ladda .env (samma sökning som worker/seed) så DATABASE_URL/REDIS_URL finns
// även när skriptet körs fristående via `pnpm exec tsx`.
for (const candidate of [".env", "../.env", "../../.env"]) {
  const p = path.resolve(process.cwd(), candidate);
  if (existsSync(p)) {
    loadDotenv({ path: p });
    break;
  }
}

const LANGS = ["en", "da", "de", "es", "fi", "fr", "it", "nb", "nl", "pl", "pt"];

async function main() {
  if (!process.env.DATABASE_URL) throw new Error("Sätt DATABASE_URL.");
  const arg = (process.argv[2] ?? "all").toLowerCase();
  const targets =
    arg === "all" ? LANGS : arg.split(",").map((s) => s.trim()).filter(Boolean);
  for (const l of targets) {
    if (!LANGS.includes(l)) throw new Error(`Okänt språk: ${l}. Giltiga: ${LANGS.join(", ")}, all`);
  }

  const { db, pool } = createDatabase(process.env.DATABASE_URL);
  const connection = new IORedis(process.env.REDIS_URL ?? "redis://localhost:6379", {
    maxRetriesPerRequest: null,
  });
  const queue = new Queue(JOB_QUEUE_NAME, { connection });

  const recipes = await db
    .select({ id: schema.recipes.id })
    .from(schema.recipes)
    .where(eq(schema.recipes.status, "published"));
  const existing = await db
    .select({ r: schema.recipeTranslations.recipeId, l: schema.recipeTranslations.languageTag })
    .from(schema.recipeTranslations);
  const have = new Set(existing.map((e) => `${e.r}|${e.l}`));

  const jobs: { name: string; data: unknown }[] = [];
  let skip = 0;
  for (const r of recipes) {
    for (const lang of targets) {
      if (have.has(`${r.id}|${lang}`)) {
        skip++;
        continue;
      }
      jobs.push({
        name: "TRANSLATE_RECIPE",
        data: { jobType: "TRANSLATE_RECIPE", recipeId: r.id, targetLanguageTag: lang },
      });
    }
  }
  // Köa i klumpar (snabbare än en add per jobb).
  for (let i = 0; i < jobs.length; i += 500) {
    await queue.addBulk(jobs.slice(i, i + 500) as never);
  }

  console.log(
    `Köade ${jobs.length} översättningsjobb (hoppade ${skip} som redan finns). ` +
      `Recept: ${recipes.length}, språk: ${targets.join(", ")}.`,
  );
  console.log(
    "Workern (med riktig AI-nyckel) processar dem nu. När kön tömts: kör publish-translations.ts.",
  );
  await queue.close();
  await connection.quit();
  await pool.end();
}
main().then(
  () => process.exit(0),
  (e) => {
    console.error(e);
    process.exit(1);
  },
);
