import { logger } from "../util/logger.js";
import { tempFileName } from "../util/random.js";
import { UploadMediaType } from "../api/types.js";
import { toRawIlinkUserIdForApi } from "../auth/weixin-account-id.js";
import { getUploadUrl } from "../api/api.js";
import { getExtensionFromContentTypeOrUrl } from "../media/mime.js";
import { aesEcbPaddedSize } from "./aes-ecb.js";
import { uploadBufferToCdn } from "./cdn-upload.js";
import crypto from "node:crypto";
import fs from "node:fs/promises";
import path from "node:path";
//#region extensions/weixin/src/cdn/upload.ts
/**
* Download a remote media URL (image, video, file) to a local temp file in destDir.
* Returns the local file path; extension is inferred from Content-Type / URL.
*/
async function downloadRemoteImageToTemp(url, destDir) {
	logger.debug(`downloadRemoteImageToTemp: fetching url=${url}`);
	const res = await fetch(url);
	if (!res.ok) {
		const msg = `remote media download failed: ${res.status} ${res.statusText} url=${url}`;
		logger.error(`downloadRemoteImageToTemp: ${msg}`);
		throw new Error(msg);
	}
	const buf = Buffer.from(await res.arrayBuffer());
	logger.debug(`downloadRemoteImageToTemp: downloaded ${buf.length} bytes`);
	await fs.mkdir(destDir, { recursive: true });
	const ext = getExtensionFromContentTypeOrUrl(res.headers.get("content-type"), url);
	const name = tempFileName("weixin-remote", ext);
	const filePath = path.join(destDir, name);
	await fs.writeFile(filePath, buf);
	logger.debug(`downloadRemoteImageToTemp: saved to ${filePath} ext=${ext}`);
	return filePath;
}
/**
* Common upload pipeline: read file → hash → gen aeskey → getUploadUrl → uploadBufferToCdn → return info.
*/
async function uploadMediaToCdn(params) {
	const { filePath, toUserId, opts, cdnBaseUrl, mediaType, label } = params;
	const plaintext = await fs.readFile(filePath);
	const rawsize = plaintext.length;
	const rawfilemd5 = crypto.createHash("md5").update(plaintext).digest("hex");
	const filesize = aesEcbPaddedSize(rawsize);
	const filekey = crypto.randomBytes(16).toString("hex");
	const aeskey = crypto.randomBytes(16);
	logger.debug(`${label}: file=${filePath} rawsize=${rawsize} filesize=${filesize} md5=${rawfilemd5} filekey=${filekey}`);
	const uploadUrlResp = await getUploadUrl({
		...opts,
		filekey,
		media_type: mediaType,
		to_user_id: toRawIlinkUserIdForApi(toUserId),
		rawsize,
		rawfilemd5,
		filesize,
		no_need_thumb: true,
		aeskey: aeskey.toString("hex")
	});
	const uploadFullUrl = uploadUrlResp.upload_full_url?.trim();
	const uploadParam = uploadUrlResp.upload_param;
	if (!uploadFullUrl && !uploadParam) {
		logger.error(`${label}: getUploadUrl returned no upload URL (need upload_full_url or upload_param), resp=${JSON.stringify(uploadUrlResp)}`);
		throw new Error(`${label}: getUploadUrl returned no upload URL`);
	}
	const { downloadParam: downloadEncryptedQueryParam } = await uploadBufferToCdn({
		buf: plaintext,
		uploadFullUrl: uploadFullUrl || void 0,
		uploadParam: uploadParam ?? void 0,
		filekey,
		cdnBaseUrl,
		aeskey,
		label: `${label}[orig filekey=${filekey}]`
	});
	return {
		filekey,
		downloadEncryptedQueryParam,
		aeskey: aeskey.toString("hex"),
		fileSize: rawsize,
		fileSizeCiphertext: filesize
	};
}
/** Upload a local image file to the Weixin CDN with AES-128-ECB encryption. */
async function uploadFileToWeixin(params) {
	return uploadMediaToCdn({
		...params,
		mediaType: UploadMediaType.IMAGE,
		label: "uploadFileToWeixin"
	});
}
/** Upload a local video file to the Weixin CDN. */
async function uploadVideoToWeixin(params) {
	return uploadMediaToCdn({
		...params,
		mediaType: UploadMediaType.VIDEO,
		label: "uploadVideoToWeixin"
	});
}
/**
* Upload a local file attachment (non-image, non-video) to the Weixin CDN.
* Uses media_type=FILE; no thumbnail required.
*/
async function uploadFileAttachmentToWeixin(params) {
	return uploadMediaToCdn({
		...params,
		mediaType: UploadMediaType.FILE,
		label: "uploadFileAttachmentToWeixin"
	});
}
//#endregion
export { downloadRemoteImageToTemp, uploadFileAttachmentToWeixin, uploadFileToWeixin, uploadVideoToWeixin };

//# sourceMappingURL=upload.js.map