/**
 * Shared seed helpers so specs don't each hand-roll the upload/comment create
 * flow. Centralising the API contract (routes, field names, expected statuses)
 * means an API change is a one-file edit, not a 7-file hunt.
 */
import { readFileSync } from 'node:fs';
import { join } from 'node:path';
import { uploadRaw } from './upload-client';
import { db } from '../fixtures/db';
import { BASE } from './env';

// A real, decodable JPEG. Magic-bytes-only fakes now get auto-cleaned by the
// backend when compression fails (a failed transcode refunds quota + deletes the
// row), which would delete the seeded upload out from under the test. Read lazily
// at call time (cwd is the e2e dir at runtime, like the gallery-path spec) so test
// collection can't trip on a module-load read.
let sampleJpg: Buffer | null = null;
function sampleImage(): Buffer {
  if (!sampleJpg) {
    sampleJpg = readFileSync(join(process.cwd(), 'fixtures', 'media', 'sample.jpg'));
  }
  return sampleJpg;
}

export type SeedUploadOptions = {
  caption?: string;
  /** Mark compression done so the card is fully rendered in the feed. Default true. */
  visible?: boolean;
};

/** Seed a real, accepted upload owned by `jwt` and return its id. */
export async function seedUpload(jwt: string, opts: SeedUploadOptions = {}): Promise<string> {
  const res = await uploadRaw(jwt, sampleImage(), {
    filename: 'a.jpg',
    contentType: 'image/jpeg',
    caption: opts.caption,
  });
  if (res.status !== 201) throw new Error(`seedUpload failed: ${res.status} ${await res.text()}`);
  const { id } = await res.json();
  if (opts.visible !== false) await db.setUploadCompressionStatus(id, 'done');
  return id;
}

/** Seed a comment on `uploadId` authored by `jwt`; return its id. */
export async function seedComment(jwt: string, uploadId: string, body: string): Promise<string> {
  const res = await fetch(`${BASE}/api/v1/upload/${uploadId}/comments`, {
    method: 'POST',
    headers: { Authorization: `Bearer ${jwt}`, 'Content-Type': 'application/json' },
    body: JSON.stringify({ body }),
  });
  if (res.status !== 201) throw new Error(`seedComment failed: ${res.status} ${await res.text()}`);
  return (await res.json()).id;
}

/** Read the comments for an upload as `jwt`. */
export async function listComments(jwt: string, uploadId: string): Promise<any[]> {
  const res = await fetch(`${BASE}/api/v1/upload/${uploadId}/comments`, {
    headers: { Authorization: `Bearer ${jwt}` },
  });
  return res.json();
}

/** Resolve a single upload row from a feed response whose envelope shape isn't pinned. */
export function findFeedRow(feed: any, id: string): any {
  const list: any[] = feed.uploads ?? feed.items ?? feed;
  return Array.isArray(list) ? list.find((u: any) => u.id === id) : undefined;
}
