/**
 * Google Gemini image generation via generativelanguage.googleapis.com generateContent.
 * Uses image-capable models (not gemini-flash-latest, which is text-only).
 *
 * @see https://ai.google.dev/gemini-api/docs/image-generation
 */

export interface GeminiImageConfig {
  apiKey: string;
  model: string;
  timeoutMs: number;
}

interface GeminiPart {
  text?: string;
  inlineData?: { mimeType?: string; data?: string };
  inline_data?: { mime_type?: string; data?: string };
}

interface GeminiGenerateResponse {
  candidates?: Array<{
    content?: { parts?: GeminiPart[] };
  }>;
  error?: { message?: string; code?: number };
}

/** Stable image model only — preview/exp models were removed from the API. */
const GEMINI_IMAGE_MODEL_FALLBACKS = ["gemini-2.5-flash-image"] as const;

function extractImageDataUrl(parts: GeminiPart[] | undefined): string | null {
  if (!parts?.length) return null;

  for (const part of parts) {
    const inline = part.inlineData ?? part.inline_data;
    const data = inline?.data;
    if (!data) continue;

    const mime =
      (part.inlineData?.mimeType ?? part.inline_data?.mime_type ?? "image/png").trim();
    return `data:${mime};base64,${data}`;
  }

  return null;
}

export async function requestGeminiImage(
  config: GeminiImageConfig,
  prompt: string,
): Promise<{ url: string | null; modelUsed: string; error?: string }> {
  const modelsToTry = [
    config.model,
    ...GEMINI_IMAGE_MODEL_FALLBACKS.filter((m) => m !== config.model),
  ];

  const errors: string[] = [];

  for (const model of modelsToTry) {
    const controller = new AbortController();
    const timer = setTimeout(() => controller.abort(), config.timeoutMs);

    try {
      const url = `https://generativelanguage.googleapis.com/v1beta/models/${encodeURIComponent(model)}:generateContent`;

      const res = await fetch(url, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
          "X-goog-api-key": config.apiKey,
        },
        body: JSON.stringify({
          contents: [
            {
              parts: [{ text: prompt.slice(0, 4000) }],
            },
          ],
          generationConfig: {
            responseModalities: ["TEXT", "IMAGE"],
          },
        }),
        signal: controller.signal,
      });

      const data = (await res.json()) as GeminiGenerateResponse;

      if (!res.ok) {
        const msg = data.error?.message ?? `HTTP ${res.status}`;
        errors.push(`${model}: ${msg}`);
        console.warn(`[PostSync] Gemini image (${model}) failed:`, msg);
        continue;
      }

      const parts = data.candidates?.[0]?.content?.parts;
      const imageUrl = extractImageDataUrl(parts);

      if (imageUrl) {
        return { url: imageUrl, modelUsed: model };
      }

      errors.push(`${model}: no image in response`);
    } catch (err) {
      const msg = err instanceof Error ? err.message : String(err);
      errors.push(`${model}: ${msg}`);
      console.warn("[PostSync] Gemini image request error:", err);
    } finally {
      clearTimeout(timer);
    }
  }

  return {
    url: null,
    modelUsed: config.model,
    error: errors.join("; "),
  };
}
