import { randomBytes } from "crypto";

/** Unique per generation so regenerate never overwrites/reuses the same media URL. */
export function createMediaAssetId(postId: string): string {
  const stamp = Date.now().toString(36);
  const rand = randomBytes(4).toString("hex");
  // Filesystem-safe, short enough for banners/videos.
  return `${postId.slice(0, 8)}-${stamp}-${rand}`;
}

/** Append cache-bust query so browsers/CDNs don't show the previous banner/video. */
export function withMediaCacheBust(url: string | null | undefined, assetId: string): string | null {
  if (!url?.trim()) return null;
  const base = url.split("?")[0] ?? url;
  return `${base}?v=${encodeURIComponent(assetId)}`;
}

/** Integer seed derived from asset id for layout/visual variation. */
export function mediaLayoutSeed(assetId: string): number {
  let h = 0;
  for (let i = 0; i < assetId.length; i++) {
    h = (h * 31 + assetId.charCodeAt(i)) >>> 0;
  }
  return h || Date.now();
}

/**
 * Per-post layout seed — combines media id, sequence post id, beat index, and caption
 * so different posts in the same project get different compositions.
 */
export function postLayoutSeed(input: {
  mediaAssetId: string;
  sequencePostId: string;
  sequenceIndex: number;
  caption?: string;
}): number {
  let h = mediaLayoutSeed(input.mediaAssetId);
  for (let i = 0; i < input.sequencePostId.length; i++) {
    h = (h * 37 + input.sequencePostId.charCodeAt(i)) >>> 0;
  }
  h = (h + input.sequenceIndex * 7919) >>> 0;
  const cap = (input.caption || "").slice(0, 200);
  for (let i = 0; i < cap.length; i++) {
    h = (h * 33 + cap.charCodeAt(i)) >>> 0;
  }
  return h || Date.now();
}
