const csrf = () =>
	document.cookie
		.split("; ")
		.find((v) => v.startsWith("rp_csrf="))
		?.split("=")[1] || "";
const setText = (el, text, error = false) => {
	const node = document.createElement("p");
	node.textContent = text;
	if (error) node.style.color = "#a8371a";
	el.replaceChildren(node);
};
export function initAlogPanel({
	state,
	recompute,
	getRemotePlanId,
	flushCurrentPlan,
}) {
	const fileInput = document.getElementById("alog-file"),
		libraryBtn = document.getElementById("alog-library-refresh"),
		libraryList = document.getElementById("alog-library-list"),
		resultEl = document.getElementById("alog-result"),
		actualInput = document.getElementById("actual-alog-file"),
		actualResultEl = document.getElementById("actual-alog-result");
	fileInput.addEventListener("change", async (e) => {
		const file = e.target.files?.[0];
		if (!file) return;
		setText(resultEl, "Parsing…");
		try {
			const res = await fetch("/api/alog", {
				method: "POST",
				headers: { "content-type": "application/json", "x-csrf-token": csrf() },
				body: JSON.stringify({
					filename: file.name,
					content: await file.text(),
				}),
			});
			applyResult(await res.json());
		} catch (err) {
			setText(resultEl, err.message, true);
		}
	});
	libraryBtn.addEventListener("click", async () => {
		libraryList.classList.remove("hidden");
		libraryList.replaceChildren(
			Object.assign(document.createElement("li"), { textContent: "Loading…" }),
		);
		try {
			const body = await (await fetch("/api/alog/library")).json();
			if (!body.ok || !body.files.length) {
				libraryList.replaceChildren(
					Object.assign(document.createElement("li"), {
						textContent:
							"No .alog files found. Set ALOG_DIR or drop files in ~/Roastetta.",
					}),
				);
				return;
			}
			libraryList.replaceChildren(
				...body.files.map((f) => {
					const li = document.createElement("li");
					li.textContent = `${f.filename} (${Math.round(f.sizeBytes / 1024)} KB)`;
					li.onclick = async () => {
						setText(resultEl, "Loading…");
						applyResult(
							await (
								await fetch(
									`/api/alog/library/${encodeURIComponent(f.filename)}`,
								)
							).json(),
						);
					};
					return li;
				}),
			);
		} catch (err) {
			const li = document.createElement("li");
			li.textContent = err.message;
			li.style.color = "#a8371a";
			libraryList.replaceChildren(li);
		}
	});
	// Finished-roast uploads: each file becomes an actual_roasts row attached to the open plan
	// (which must exist server-side first — hence the flush), and the LLM reviews it
	// asynchronously; the roast history page is where results land.
	actualInput?.addEventListener("change", async (e) => {
		const files = [...(e.target.files ?? [])];
		e.target.value = "";
		if (!files.length) return;
		setText(actualResultEl, "Syncing plan…");
		await flushCurrentPlan();
		const planId = getRemotePlanId();
		if (!planId) {
			setText(
				actualResultEl,
				"Could not sync this plan to the server — connect and try again, or upload from the Roasts page without a plan.",
				true,
			);
			return;
		}
		let uploaded = 0;
		for (const file of files) {
			setText(actualResultEl, `Uploading ${file.name}…`);
			try {
				const res = await fetch("/api/roasts", {
					method: "POST",
					headers: { "content-type": "application/json", "x-csrf-token": csrf() },
					body: JSON.stringify({
						roastPlanId: planId,
						filename: file.name,
						content: await file.text(),
					}),
				});
				const body = await res.json();
				if (!body.ok) throw new Error(body.error ?? body.code);
				uploaded++;
			} catch (err) {
				setText(actualResultEl, `${file.name}: ${err.message}`, true);
				return;
			}
		}
		const node = document.createElement("p");
		node.append(
			`Uploaded ${uploaded} roast${uploaded === 1 ? "" : "s"} to this plan. `,
		);
		const link = document.createElement("a");
		link.href = "/roasts";
		link.textContent = "See the review →";
		node.append(link);
		actualResultEl.replaceChildren(node);
	});
	function applyResult(body) {
		if (!body.ok) {
			setText(resultEl, body.error ?? body.code, true);
			return;
		}
		state.plan.reference = body;
		recompute();
		setText(
			resultEl,
			`${body.roast.title} — ${body.roast.roastDate || "no date"}; first crack ${fmt(body.derived?.firstCrackS)}; development ${fmt(body.derived?.developmentS)}; drop ${fmt(body.derived?.dropS)}; DTR ${body.derived?.dtrPct ?? "—"}%.`,
		);
	}
}
function fmt(seconds) {
	if (seconds == null) return "—";
	const s = Math.round(seconds);
	return `${Math.floor(s / 60)}:${String(s % 60).padStart(2, "0")}`;
}
