import { createHash } from "node:crypto";
import { basename, extname, normalize } from "node:path";
import { getStorageService, inferContentType } from "@reactive-resume/api/features/storage";

export async function handleUpload(request: Request) {
	const { userId, filePath } = parseRouteParams(request.url);

	if (!userId || !filePath) return new Response("Bad Request", { status: 400 });

	if (!isValidPath(userId) || !isValidPathSegments(filePath)) return new Response("Forbidden", { status: 403 });
	if (isPrivateUploadPath(filePath)) return new Response("Not Found", { status: 404 });

	const storageService = getStorageService();
	const key = `uploads/${userId}/${filePath}`;
	const storedFile = await storageService.read(key);
	if (!storedFile) return new Response("Not Found", { status: 404 });

	const filename = filePath.split("/").pop() ?? filePath;
	const ext = extname(filename).toLowerCase();
	const contentType = storedFile.contentType ?? inferContentType(filename);
	const etag = createEtag(storedFile);

	if (isNotModified(request.headers, etag)) return makeNotModifiedResponse(etag);

	const shouldForceDownload = [".pdf"].includes(ext);

	const headers = new Headers();
	headers.set("Content-Type", shouldForceDownload ? "application/octet-stream" : contentType);
	headers.set("Content-Length", storedFile.size.toString());

	if (shouldForceDownload) {
		headers.set("Content-Disposition", `attachment; filename="${encodeURIComponent(basename(filename))}"`);
	}

	headers.set("Cache-Control", "public, max-age=31536000, immutable");
	headers.set("ETag", etag);
	headers.set("X-Content-Type-Options", "nosniff");
	headers.set("X-Robots-Tag", "noindex, nofollow");
	headers.set("Cross-Origin-Resource-Policy", "same-site");
	headers.set("Referrer-Policy", "strict-origin-when-cross-origin");
	headers.set("X-Frame-Options", "DENY");
	headers.set("X-Download-Options", "noopen");

	return new Response(toArrayBuffer(storedFile.data), { headers });
}

function parseRouteParams(url: string): { userId: string | undefined; filePath: string | undefined } {
	const pathname = new URL(url).pathname;
	const [, pathAfterUploads] = pathname.split("/uploads/");
	if (!pathAfterUploads) return { userId: undefined, filePath: undefined };
	const firstSlashIndex = pathAfterUploads.indexOf("/");

	if (firstSlashIndex === -1) {
		return { userId: pathAfterUploads, filePath: undefined };
	}

	const userId = pathAfterUploads.slice(0, firstSlashIndex);
	const filePath = pathAfterUploads.slice(firstSlashIndex + 1);

	return { userId, filePath: filePath || undefined };
}

function isValidPath(segment: string): boolean {
	const normalized = normalize(segment).replace(/^(\.\.(\/|\\|$))+/, "");

	return normalized === segment;
}

function isValidPathSegments(path: string): boolean {
	const segments = path.split("/");

	return segments.every((segment) => isValidPath(segment));
}

function isPrivateUploadPath(path: string): boolean {
	return path.split("/")[0] === "agent";
}

function isNotModified(headers: Headers, etag: string): boolean {
	const ifNoneMatch = headers.get("If-None-Match");
	const candidates = ifNoneMatch?.split(",").map((s) => s.trim()) ?? [];

	return candidates.includes(etag);
}

function makeNotModifiedResponse(etag: string): Response {
	return new Response(null, {
		status: 304,
		headers: { ETag: etag, "Cache-Control": "public, max-age=31536000, immutable" },
	});
}

function toArrayBuffer(data: Uint8Array): ArrayBuffer {
	return data.byteOffset === 0 && data.byteLength === data.buffer.byteLength
		? (data.buffer as ArrayBuffer)
		: (data.slice().buffer as ArrayBuffer);
}

function createEtag(storedFile: { data: Uint8Array; size: number; etag?: string }): string {
	if (storedFile.etag) {
		const tag = storedFile.etag.trim();

		if (tag.startsWith("W/") || tag.startsWith('"')) {
			return tag;
		}
		return `"${tag}"`;
	}

	const hash = createHash("sha256").update(storedFile.data).digest("hex");

	return `"${storedFile.size}-${hash}"`;
}
