import { r as STATE_DIR } from "./paths-CmLVBCTa.js";
import { a as sendMethodNotAllowed, i as sendJson, t as readJsonBodyOrError } from "./http-common-BSuRrNvp.js";
import { t as authorizeControlUiReadRequest } from "./control-ui-CPiC36zw.js";
import path from "node:path";
import fs from "node:fs/promises";
//#region src/gateway/credentials-proxy-http.ts
function isCredentialsProxyPath(pathname) {
	return pathname === "/credentials" || pathname.startsWith("/credentials/");
}
const CREDENTIALS_DIR = path.join(STATE_DIR, "credentials");
/**
* Write the `default` pointer for a platform/sub_platform under an explicit
* credentials root. Parameterised so workspace-level selection writes can
* keep `credentials/{platform}/{sub}/default` in sync with the workspace
* `.platform-accounts.json` selection.
*/
async function writeCredentialsDefaultAccount(credentialsDir, platform, subPlatform, accountId) {
	const dir = path.join(credentialsDir, platform, subPlatform);
	await fs.mkdir(dir, { recursive: true });
	await fs.writeFile(path.join(dir, "default"), accountId, "utf-8");
}
const ACCOUNT_ID_KEY = {
	"taobao:sycm": "unb",
	"taobao:taobao": "unb",
	"taobao:1688": "cookie2",
	"douyin:fxg": "s_v_web_id",
	"pdd:mms": "PDDAccessToken",
	"jd:sz": "pin"
};
const REQUIRED_COOKIES = {
	"taobao:sycm": [
		"_tb_token_",
		"cookie2",
		"unb"
	],
	"taobao:taobao": [
		"_tb_token_",
		"cookie2",
		"unb"
	],
	"taobao:1688": ["cookie2", "login_tongyi_ticket"]
};
function parseCookies(cookieStr) {
	const cookies = {};
	for (const part of cookieStr.split(";")) {
		const eq = part.indexOf("=");
		if (eq < 0) continue;
		cookies[part.slice(0, eq).trim()] = part.slice(eq + 1).trim();
	}
	return cookies;
}
function platformKey(platform, subPlatform) {
	return `${platform}:${subPlatform}`;
}
function accountIdKey(platform, subPlatform) {
	return ACCOUNT_ID_KEY[platformKey(platform, subPlatform)] ?? "unb";
}
function isValid(cookieStr, platform, subPlatform) {
	const required = REQUIRED_COOKIES[platformKey(platform, subPlatform)];
	if (!required) return !!cookieStr;
	const cookies = parseCookies(cookieStr);
	return required.every((k) => !!cookies[k]);
}
function credDir(platform, subPlatform) {
	return path.join(CREDENTIALS_DIR, platform, subPlatform);
}
async function readDefaultAccountId(platform, subPlatform) {
	try {
		return (await fs.readFile(path.join(credDir(platform, subPlatform), "default"), "utf-8")).trim() || null;
	} catch {
		return null;
	}
}
async function writeDefaultAccountId(platform, subPlatform, accountId) {
	await writeCredentialsDefaultAccount(CREDENTIALS_DIR, platform, subPlatform, accountId);
}
async function readCredFile(platform, subPlatform, accountId) {
	try {
		const text = await fs.readFile(path.join(credDir(platform, subPlatform), `${accountId}.json`), "utf-8");
		return JSON.parse(text);
	} catch {
		return null;
	}
}
const statusResponseCache = /* @__PURE__ */ new Map();
async function readFileSignature(filePath) {
	try {
		const info = await fs.stat(filePath, { bigint: true });
		return {
			mtimeNs: info.mtimeNs,
			size: info.size,
			exists: true
		};
	} catch {
		return {
			mtimeNs: -1n,
			size: -1n,
			exists: false
		};
	}
}
function fileSignaturesEqual(a, b) {
	return a.exists === b.exists && a.mtimeNs === b.mtimeNs && a.size === b.size;
}
async function handleStatus(req, res, url) {
	const platform = url.searchParams.get("platform") ?? "";
	const subPlatform = url.searchParams.get("sub_platform") ?? "";
	if (!platform || !subPlatform) {
		sendJson(res, 400, { error: "platform and sub_platform are required" });
		return;
	}
	const dir = credDir(platform, subPlatform);
	const defaultSig = await readFileSignature(path.join(dir, "default"));
	const cacheKey = platformKey(platform, subPlatform);
	const cached = statusResponseCache.get(cacheKey);
	if (cached && fileSignaturesEqual(cached.defaultSig, defaultSig)) {
		if (cached.accountId === null) {
			sendJson(res, 200, cached.response);
			return;
		}
		const credSig = await readFileSignature(path.join(dir, `${cached.accountId}.json`));
		if (fileSignaturesEqual(cached.credSig, credSig)) {
			sendJson(res, 200, cached.response);
			return;
		}
	}
	const accountId = await readDefaultAccountId(platform, subPlatform);
	if (!accountId) {
		const response = {
			status: "none",
			platform,
			sub_platform: subPlatform
		};
		statusResponseCache.set(cacheKey, {
			defaultSig,
			credSig: {
				mtimeNs: -1n,
				size: -1n,
				exists: false
			},
			accountId: null,
			response
		});
		sendJson(res, 200, response);
		return;
	}
	const credSig = await readFileSignature(path.join(dir, `${accountId}.json`));
	const data = await readCredFile(platform, subPlatform, accountId);
	const cookieStr = typeof data?.cookie_str === "string" ? data.cookie_str : "";
	const response = {
		status: !cookieStr ? "none" : isValid(cookieStr, platform, subPlatform) ? "valid" : "expired",
		platform,
		sub_platform: subPlatform
	};
	statusResponseCache.set(cacheKey, {
		defaultSig,
		credSig,
		accountId,
		response
	});
	sendJson(res, 200, response);
}
function __clearCredentialsStatusCacheForTests() {
	statusResponseCache.clear();
}
async function handleAccounts(req, res, url) {
	const platform = url.searchParams.get("platform") ?? "";
	const subPlatform = url.searchParams.get("sub_platform") ?? "";
	if (!platform || !subPlatform) {
		sendJson(res, 400, { error: "platform and sub_platform are required" });
		return;
	}
	const dir = credDir(platform, subPlatform);
	let files = [];
	try {
		files = await fs.readdir(dir);
	} catch {
		sendJson(res, 200, []);
		return;
	}
	const accounts = [];
	for (const file of files.sort()) {
		if (!file.endsWith(".json")) continue;
		const accountId = file.slice(0, -5);
		const data = await readCredFile(platform, subPlatform, accountId);
		if (!data) continue;
		const profile = data.profile;
		accounts.push({
			account_id: profile?.account_id ?? accountId,
			account_name: profile?.account_name ?? "",
			main_cate_name: profile?.main_cate_name ?? ""
		});
	}
	sendJson(res, 200, accounts);
}
async function handleSave(req, res) {
	const body = await readJsonBodyOrError(req, res, 256 * 1024);
	if (body === void 0) return;
	const { platform, sub_platform, cookie_str } = body;
	if (!platform || !sub_platform || !cookie_str) {
		sendJson(res, 400, {
			success: false,
			message: "platform, sub_platform, cookie_str are required"
		});
		return;
	}
	const cookies = parseCookies(cookie_str);
	const idKey = accountIdKey(platform, sub_platform);
	const accountId = cookies[idKey] ?? "";
	if (!accountId) {
		sendJson(res, 400, {
			success: false,
			message: `Cookie 中缺少 ${idKey} 字段，无法识别账号`
		});
		return;
	}
	const dir = credDir(platform, sub_platform);
	await fs.mkdir(dir, { recursive: true });
	await fs.writeFile(path.join(dir, `${accountId}.json`), JSON.stringify({ cookie_str }, null, 2), "utf-8");
	await writeDefaultAccountId(platform, sub_platform, accountId);
	sendJson(res, 200, {
		success: true,
		account_id: accountId,
		message: "凭证已保存"
	});
}
async function handleDelete(req, res) {
	const body = await readJsonBodyOrError(req, res, 64 * 1024);
	if (body === void 0) return;
	const { platform, sub_platform, account_id } = body;
	if (!platform || !sub_platform || !account_id) {
		sendJson(res, 400, {
			success: false,
			message: "platform, sub_platform, account_id are required"
		});
		return;
	}
	const dir = credDir(platform, sub_platform);
	const credFile = path.join(dir, `${account_id}.json`);
	try {
		await fs.unlink(credFile);
	} catch {
		sendJson(res, 404, {
			success: false,
			message: `账号不存在: ${account_id}`
		});
		return;
	}
	if (await readDefaultAccountId(platform, sub_platform) === account_id) {
		let files = [];
		try {
			files = await fs.readdir(dir);
		} catch {}
		const remaining = files.filter((f) => f.endsWith(".json")).map((f) => f.slice(0, -5));
		if (remaining.length > 0) await writeDefaultAccountId(platform, sub_platform, remaining[0]);
		else await fs.unlink(path.join(dir, "default")).catch(() => {});
	}
	sendJson(res, 200, {
		success: true,
		message: "凭证已删除"
	});
}
async function handleCredentialsProxyHttpRequest(req, res, opts) {
	const url = new URL(req.url ?? "/", `http://${req.headers.host ?? "localhost"}`);
	if (!isCredentialsProxyPath(url.pathname)) return false;
	if (req.method !== "GET" && req.method !== "POST") {
		sendMethodNotAllowed(res, "GET, POST");
		return true;
	}
	if (!await authorizeControlUiReadRequest(req, res, {
		auth: opts.auth,
		trustedProxies: opts.trustedProxies,
		allowRealIpFallback: opts.allowRealIpFallback,
		rateLimiter: opts.rateLimiter
	})) return true;
	if (url.pathname === "/credentials/status" && req.method === "GET") {
		await handleStatus(req, res, url);
		return true;
	}
	if (url.pathname === "/credentials/accounts" && req.method === "GET") {
		await handleAccounts(req, res, url);
		return true;
	}
	if (url.pathname === "/credentials/save" && req.method === "POST") {
		await handleSave(req, res);
		return true;
	}
	if (url.pathname === "/credentials/delete" && req.method === "POST") {
		await handleDelete(req, res);
		return true;
	}
	sendJson(res, 404, { error: "not_found" });
	return true;
}
//#endregion
export { writeCredentialsDefaultAccount as a, isCredentialsProxyPath as i, __clearCredentialsStatusCacheForTests as n, handleCredentialsProxyHttpRequest as r, CREDENTIALS_DIR as t };
