const GATEWAY_EMBED_URL = 'https://ai-gateway.vercel.sh/v1/embeddings';
const DEFAULT_EMBED_MODEL = process.env.SCAN_EMBED_MODEL || 'cohere/embed-v4.0';

/** Output dimension — must match migrations/1782000000001_add-card-embeddings.js. */
export const EMBED_DIMENSION = Number(process.env.SCAN_EMBED_DIMENSION || 1024);

export class EmbedApiError extends Error {
  constructor(message, { status } = {}) {
    super(message);
    this.name = 'EmbedApiError';
    this.status = status;
  }
}

function parseEmbeddingResponse(data) {
  const embedding =
    data?.data?.[0]?.embedding ||
    data?.embeddings?.[0]?.values ||
    data?.embeddings?.[0] ||
    data?.embedding;

  if (!Array.isArray(embedding) || embedding.length === 0) {
    throw new EmbedApiError('Embedding API returned no vector');
  }

  return embedding.map((value) => Number(value));
}

function isValidEmbedInput(value) {
  if (typeof value !== 'string' || !value.trim()) {
    return false;
  }

  if (value.startsWith('data:')) {
    return value.includes(',');
  }

  return value.startsWith('http://') || value.startsWith('https://');
}

function buildEmbedInput(value) {
  if (typeof value === 'string') {
    return value;
  }

  if (value?.imageUrl) {
    return value.imageUrl;
  }

  if (value?.imageDataUrl) {
    return value.imageDataUrl;
  }

  throw new EmbedApiError('Invalid embed input');
}

function normalizeEmbeddingDimensions(embedding) {
  if (embedding.length === EMBED_DIMENSION) {
    return embedding;
  }

  if (embedding.length > EMBED_DIMENSION) {
    // Gateway ignores matryoshka `dimensions` for multimodal — truncate to catalog width.
    return embedding.slice(0, EMBED_DIMENSION);
  }

  throw new EmbedApiError(
    `Embedding API returned ${embedding.length} dimensions; expected ${EMBED_DIMENSION}`
  );
}

/**
 * Embed image content via Vercel AI Gateway (server-only).
 * Accepts a JPEG data URL string, HTTPS image URL string, or { imageUrl } / { imageDataUrl }.
 */
export async function embedCardImage(input) {
  const apiKey = process.env.AI_GATEWAY_API_KEY;
  if (!apiKey) {
    throw new EmbedApiError('AI_GATEWAY_API_KEY is not configured on the server');
  }

  const payloadInput = buildEmbedInput(input);
  if (!isValidEmbedInput(payloadInput)) {
    throw new EmbedApiError('Invalid image data format');
  }

  const response = await fetch(GATEWAY_EMBED_URL, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${apiKey}`,
    },
    body: JSON.stringify({
      model: DEFAULT_EMBED_MODEL,
      input: payloadInput,
      dimensions: EMBED_DIMENSION,
    }),
  });

  if (!response.ok) {
    const errorData = await response.json().catch(() => ({}));
    const message = errorData.error?.message || errorData.message || 'Unknown error';
    throw new EmbedApiError(`Embedding API error: ${response.status} - ${message}`, {
      status: response.status,
    });
  }

  return normalizeEmbeddingDimensions(parseEmbeddingResponse(await response.json()));
}

/** Format a float array for pgvector tagged-template queries. */
export function formatEmbeddingForPg(embedding) {
  return `[${embedding.map((value) => Number(value).toFixed(8)).join(',')}]`;
}
