/**
 * Server-side image generation and file upload helpers.
 *
 * These functions require filesystem access and FAL_KEY,
 * so they stay server-only (not bundled into web components).
 */

import { resolve } from "node:path";
import { mkdir, writeFile, unlink } from "node:fs/promises";

const GEN_DIR = resolve(process.env.FILES_DIR || "./data/files", "generated");

async function ensureGenDir(): Promise<string> {
	await mkdir(GEN_DIR, { recursive: true });
	return GEN_DIR;
}

// ── fal.ai image generation ──

export async function generateImageFromPrompt(prompt: string): Promise<string | null> {
	const FAL_KEY = process.env.FAL_KEY || "";
	if (!FAL_KEY) return null;

	let falRes: Response;
	try {
		falRes = await fetch("https://fal.run/fal-ai/flux-pro/v1.1", {
			method: "POST",
			headers: {
				Authorization: `Key ${FAL_KEY}`,
				"Content-Type": "application/json",
			},
			body: JSON.stringify({
				prompt,
				image_size: "landscape_4_3",
				num_images: 1,
				safety_tolerance: "2",
			}),
		});
	} catch (e: any) {
		console.error("[image-gen] fal.ai network error:", e.message);
		return null;
	}

	if (!falRes.ok) {
		const errText = await falRes.text().catch(() => "unknown");
		console.error(`[image-gen] fal.ai error (${falRes.status}):`, errText);
		return null;
	}

	const falData = await falRes.json() as { images?: { url: string }[]; output?: { url: string } };
	return falData.images?.[0]?.url || falData.output?.url || null;
}

export async function downloadAndSaveImage(cdnUrl: string, filename: string): Promise<string | null> {
	const imgRes = await fetch(cdnUrl);
	if (!imgRes.ok) return null;

	const imgBuffer = await imgRes.arrayBuffer();
	const dir = await ensureGenDir();
	await writeFile(resolve(dir, filename), Buffer.from(imgBuffer));
	return `/data/files/generated/${filename}`;
}

// ── File upload handling ──

const ALLOWED_TYPES = ["image/png", "image/jpeg", "image/webp", "image/gif"];
const MAX_SIZE = 5 * 1024 * 1024; // 5MB

export function validateImageFile(file: File): string | null {
	if (!ALLOWED_TYPES.includes(file.type)) {
		return "Invalid file type. Allowed: png, jpg, webp, gif";
	}
	if (file.size > MAX_SIZE) {
		return "File too large. Maximum 5MB";
	}
	return null;
}

export function safeExtension(filename: string): string {
	const ext = filename.split(".").pop()?.toLowerCase() || "png";
	return ["png", "jpg", "jpeg", "webp", "gif"].includes(ext) ? ext : "png";
}

export async function saveUploadedFile(buffer: Buffer, filename: string): Promise<string> {
	const dir = await ensureGenDir();
	await writeFile(resolve(dir, filename), buffer);
	return `/data/files/generated/${filename}`;
}

// ── Cleanup helpers ──

export async function deleteImageFile(imageUrl: string): Promise<void> {
	const fname = imageUrl.split("/").pop();
	if (!fname) return;
	try { await unlink(resolve(GEN_DIR, fname)); } catch { /* ignore */ }
}

export async function deleteOldImage(oldUrl: string | undefined, newFilename: string): Promise<void> {
	if (!oldUrl) return;
	const oldFilename = oldUrl.split("/").pop();
	if (oldFilename && oldFilename !== newFilename) {
		try { await unlink(resolve(GEN_DIR, oldFilename)); } catch { /* ignore */ }
	}
}
