const { onDocumentCreated } = require("firebase-functions/v2/firestore");
const admin = require("firebase-admin");
const logger = require("firebase-functions/logger");
const {
  generateImageV2,
  CombineCoverAndPicture,
} = require("../helpers/gemini");
const { generatePicturePrompt } = require("../helpers/prompts");

const db = admin.firestore();

// Shared core for generating and saving the cover, and updating the project
async function performCoverGeneration(project) {
  const t0 = Date.now();
  const prompt = generatePicturePrompt(project);
  // Utiliser generateImageV2 qui renvoie directement l'URL publique
  logger.info("🎨 [Cover] Calling model V2", {
    projectId: project.id,
    promptPreview: String(prompt).slice(0, 160),
  });
  let coverUrl = "";
  try {
    // Utiliser une taille fixe de 1024 pixels
    coverUrl = await generateImageV2(prompt, 1024);
    console.log("coverUrl", coverUrl);
  } catch (e) {
    logger.error("❌ [Cover] generateImageV2 failed", {
      projectId: project.id,
      error: e?.message || String(e),
    });
    throw e;
  }
  if (!coverUrl) {
    throw new Error("Génération d'image échouée (URL vide)");
  }

  // Mettre à jour le projet avec l'URL et le statut
  await db
    .collection("projects")
    .doc(project.id)
    .set(
      {
        cover: {
          generatedBackground: coverUrl,
        },
        coverStatus: "GENERATED",
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
      },
      { merge: true },
    );

  logger.info("✅ [Cover] Saved", {
    projectId: project.id,
    coverUrl,
    ms: Date.now() - t0,
  });
  return coverUrl;
}

async function performCombineGeneration(project) {
  const t0 = Date.now();
  const background = project?.cover?.generatedBackground || null;
  const foreground = project?.cover?.userForeground || null;

  if (!background || !foreground) {
    throw new Error(
      "Images manquantes: cover.generatedBackground et cover.userForground sont requis",
    );
  }

  logger.info("🧩 [Combine] Inputs detected", {
    bgPreview: String(background).slice(0, 80),
    fgPreview: String(foreground).slice(0, 80),
  });

  const combinedUrl = await CombineCoverAndPicture(background, foreground);

  // Sauvegarder le résultat et marquer comme généré
  await db
    .collection("projects")
    .doc(project.id)
    .set(
      {
        cover: {
          ...project.cover,
          result: combinedUrl,
        },
        coverStatus: "GENERATED",
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
      },
      { merge: true },
    );

  logger.info("✅ [Cover] Combined image saved", {
    projectId: project.id,
    combinedUrl,
    ms: Date.now() - t0,
  });

  return combinedUrl;
}

// Firestore trigger: création d'une tâche de génération de cover
exports.onTaskCreateGenerateCover = onDocumentCreated(
  {
    timeoutSeconds: 540,
    memory: "1GiB",
    document: "tasks/{taskId}",
  },
  async (event) => {
    const data = event?.data?.data() || {};
    const type = data?.type || "";
    const projectId = data?.projectId || null;
    let coverUrl = null;
    try {
      if (!projectId) {
        throw new Error("projectId manquant dans la task");
      }
      if (!["cover", "combine"]?.includes(type)) {
        throw new Error(`Type de tâche non supporté: ${type}`);
      }
      logger.info("🧵 [Task] Received", {
        taskId: event?.params?.taskId,
        type,
        projectId,
      });
      await db.collection("projects").doc(projectId).update({
        coverStatus: "GENERATING",
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
      });

      const project =
        (await db.collection("projects").doc(projectId).get())?.data() || null;
      if (!project) {
        throw new Error("Projet non trouvé");
      }
      project.id = projectId;

      logger.info("🔎 [Task] Project loaded", {
        projectId,
        hasGeneratedBackground: !!project?.cover?.generatedBackground,
        hasUserForeground: !!project?.cover?.userForeground,
      });

      if (type === "cover") {
        logger.info("🎨 [Task] Start cover generation", { projectId });
        coverUrl = await performCoverGeneration(project);
        logger.info("✅ [Task] Cover generated", { projectId });
      } else if (type === "combine") {
        logger.info("🧩 [Task] Start combine (cover + photo)", { projectId });
        coverUrl = await performCombineGeneration(project);
        logger.info("✅ [Task] Combine generated", { projectId, coverUrl });
      }

      await event.data.ref.update({
        status: "DONE",
        coverUrl,
        updatedAt: admin.firestore.FieldValue.serverTimestamp(),
      });
      logger.info("📦 [Task] Marked DONE", {
        taskId: event?.params?.taskId,
        projectId,
      });
      return;
    } catch (error) {
      logger.error("❌ [Task] Cover generation error", {
        taskId: event?.params?.taskId,
        projectId,
        type,
        error: error?.message || String(error),
      });
      await event.data.ref.set(
        { status: "ERROR", error: error?.message || "Erreur" },
        { merge: true },
      );
      await db.collection("projects").doc(projectId).update({
        coverStatus: "ERROR",
      });
    }
  },
);
