/* ---- settings view ---- */
function renderSettings() {
	if (!CFG) { fetchConfig().then(() => CFG && renderSettings()); return; }
	const envs = CFG.envs || [];
	$("#sDefEnv").innerHTML = envs.length
		? envs.map((e) => `<option value="${escHtml(e.key)}"${(SETTINGS.defaultEnv || envs[0].key) === e.key ? " selected" : ""}>${escHtml(e.name || e.key)}</option>`).join("")
		: `<option value="">no environments yet</option>`;
	$("#sGithubRepo").value = CFG.github?.repo || "";
	$("#sLiveMs").value = SETTINGS.liveMs;
	$("#sLogMs").value = SETTINGS.logMs;
	$("#sNotif").checked = SETTINGS.notif;
	$("#sSound").checked = SETTINGS.sound;
	$("#sMemWarn").value = SETTINGS.memWarn;
	$("#sMemCrit").value = SETTINGS.memCrit;
	$("#sQueueMax").value = SETTINGS.queueMax;
	renderAiCard();
	renderEnvEditor();
}
const AI_PROVIDERS = [
	{ key: "bedrock", name: "Bedrock (AWS)", model: "sonnet" },
	{ key: "anthropic", name: "Anthropic API", model: "claude-opus-4-8" },
	{ key: "openai", name: "OpenAI API", model: "gpt-5" },
	{ key: "gemini", name: "Google Gemini", model: "gemini-2.5-pro" },
	{ key: "deepseek", name: "DeepSeek API", model: "deepseek-v4-flash" },
];
function aiSectionHtml(x) {
	return `
	<div class="cfg-row"><label>Provider</label><select id="${x}Provider">${AI_PROVIDERS.map((p) => `<option value="${p.key}">${p.name}</option>`).join("")}</select></div>
	<div class="cfg-row"><label>Model</label><div class="model-row"><input id="${x}Model" list="${x}ModelList"><datalist id="${x}ModelList"></datalist><button class="btn" id="${x}LoadModels" type="button">Load models</button></div></div>
	<div class="model-hint" id="${x}ModelsOut"></div>
	<div id="${x}ModelPick" class="model-pick hidden"></div>
	<div class="cfg-row" id="${x}KeyRow"><label>API key</label><input id="${x}Key" type="password" autocomplete="new-password"></div>
	<div style="display:flex;gap:8px;margin-top:8px;align-items:center">
		<button class="btn" id="${x}Test">Test</button><span class="hint" id="${x}TestOut"></span>
	</div>`;
}
function renderAiCard() {
	if (!$("#sAiProvider")) {
		$("#sAiModel").closest(".card").innerHTML = `
		<h3>AI provider</h3>
		<p class="cfg-note">Global default, used by every workspace without an override below. Test and Load models here act on the global values.</p>
		${aiSectionHtml("sAi")}
		<h4 class="ws-ai-head">Workspace override</h4>
		<div class="cfg-row"><label id="sAiWsLabel">Override for this workspace</label><input type="checkbox" id="sAiWsOn"></div>
		<div id="sAiWsBody">${aiSectionHtml("sAiWs")}</div>
		<p class="cfg-note">Bedrock runs on the configured AWS profile and bills to that AWS account. Anthropic, OpenAI, Gemini, and DeepSeek use your personal API key, stored only in myeye.config.json on this machine. Load models lists what the provider offers right now; any model id typed by hand is accepted as-is.</p>`;
		wireAiSection("sAi");
		wireAiSection("sAiWs");
		$("#sAiWsOn").onchange = syncAiCard;
	}
	$("#sAiProvider").value = CFG.ai?.provider || "bedrock";
	$("#sAiModel").value = CFG.ai?.model || "";
	$("#sAiKey").value = "";
	$("#sAiWsOn").checked = !!CFG.workspaceAi;
	$("#sAiWsProvider").value = CFG.workspaceAi?.provider || "bedrock";
	$("#sAiWsModel").value = CFG.workspaceAi?.model || "";
	$("#sAiWsKey").value = "";
	syncAiCard();
}
function wireAiSection(x) {
	$(`#${x}Provider`).onchange = () => syncAiSection(x);
	$(`#${x}Test`).onclick = () => runAiTest(x);
	$(`#${x}LoadModels`).onclick = () => loadAiModels(x);
}
function syncAiSection(x) {
	const p = AI_PROVIDERS.find((v) => v.key === $(`#${x}Provider`).value) || AI_PROVIDERS[0];
	$(`#${x}Model`).placeholder = p.model;
	$(`#${x}KeyRow`).style.display = p.key === "bedrock" ? "none" : "";
	const keySet = x === "sAiWs" ? CFG?.workspaceAi?.apiKeySet : CFG?.ai?.apiKeySet;
	$(`#${x}Key`).placeholder = keySet ? "configured" : "not set";
	$(`#${x}TestOut`).textContent = "";
	$(`#${x}ModelsOut`).textContent = "";
	$(`#${x}ModelList`).innerHTML = "";
	const pick = $(`#${x}ModelPick`);
	pick.innerHTML = "";
	pick.classList.add("hidden");
}
function syncAiCard() {
	syncAiSection("sAi");
	syncAiSection("sAiWs");
	const ws = CFG?.workspace;
	$("#sAiWsLabel").textContent = ws ? `Override for workspace "${ws.name}"` : "Override for this workspace (no active workspace)";
	$("#sAiWsOn").disabled = !ws;
	$("#sAiWsBody").style.display = ws && $("#sAiWsOn").checked ? "" : "none";
}
async function runAiTest(x) {
	const btn = $(`#${x}Test`), out = $(`#${x}TestOut`);
	btn.disabled = true;
	out.textContent = x === "sAiWs" ? "testing workspace override…" : "testing global default…";
	const body = { provider: $(`#${x}Provider`).value };
	if ($(`#${x}Model`).value.trim()) body.model = $(`#${x}Model`).value.trim();
	if ($(`#${x}Key`).value) body.apiKey = $(`#${x}Key`).value;
	try {
		const r = await fetch("/api/ai/test", { method: "POST", body: JSON.stringify(body) });
		const d = await r.json();
		out.innerHTML = d.ok
			? `<span class="env-ok">connected — ${d.model}</span>`
			: `<span class="env-bad">${d.reason || "test failed"}</span>`;
	} catch { out.innerHTML = `<span class="env-bad">server unreachable</span>`; }
	btn.disabled = false;
}
async function loadAiModels(x) {
	const btn = $(`#${x}LoadModels`), out = $(`#${x}ModelsOut`), pick = $(`#${x}ModelPick`);
	btn.disabled = true;
	out.textContent = "loading…";
	pick.innerHTML = "";
	pick.classList.add("hidden");
	const body = { provider: $(`#${x}Provider`).value };
	if ($(`#${x}Key`).value.trim()) body.apiKey = $(`#${x}Key`).value.trim();
	try {
		const r = await fetch("/api/ai/models", { method: "POST", body: JSON.stringify(body) });
		const d = await r.json();
		if (!d.ok) {
			out.innerHTML = `<span class="env-bad">${escHtml(d.reason || "model listing failed")}</span>`;
		} else if (!d.models.length) {
			out.textContent = "the provider returned no models";
		} else {
			$(`#${x}ModelList`).innerHTML = d.models.map((m) => `<option value="${escHtml(m.id)}">`).join("");
			pick.innerHTML = `<input type="text" class="model-search" id="${x}ModelSearch" placeholder="Search ${d.models.length} models…">` +
				`<div class="model-opts">` + d.models.map((m) => `<button type="button" class="model-opt" data-id="${escHtml(m.id)}">${escHtml(m.id)}${m.label && m.label !== m.id ? `<span class="model-opt-label">${escHtml(m.label)}</span>` : ""}</button>`).join("") + `</div>`;
			pick.classList.remove("hidden");
			$$(".model-opt", pick).forEach((b) => b.onclick = () => { $(`#${x}Model`).value = b.dataset.id; });
			const search = $(`#${x}ModelSearch`);
			search.oninput = () => {
				const q = search.value.trim().toLowerCase();
				let shown = 0;
				$$(".model-opt", pick).forEach((b) => {
					const hit = !q || b.textContent.toLowerCase().includes(q);
					b.style.display = hit ? "" : "none";
					if (hit) shown++;
				});
				out.textContent = q ? `${shown} of ${d.models.length} models match` : `${d.models.length} models available — click one or keep typing`;
			};
			search.focus();
			out.textContent = `${d.models.length} models available — click one or keep typing`;
		}
	} catch { out.innerHTML = `<span class="env-bad">server unreachable</span>`; }
	btn.disabled = false;
}
function renderEnvEditor() {
	if (!Array.isArray(CFG.envs)) CFG.envs = [];
	if (!CFG.envs.length) {
		$("#sEnvList").innerHTML = `<p class="cfg-note" style="margin-bottom:6px">No environments yet. Use "Add environment" to connect this workspace to an AWS account, then save.</p>`;
		return;
	}
	$("#sEnvList").innerHTML = CFG.envs.map((e, i) => `
	<div class="env-edit" data-i="${i}">
		<div class="cfg-row"><label>Name</label><input data-f="name" value="${e.name || ""}"></div>
		<div class="cfg-row"><label>Key</label><input data-f="key" value="${e.key || ""}"></div>
		<div class="cfg-row"><label>Profiles (priority order)</label><input data-f="profiles" value="${(e.profiles || []).join(", ")}"></div>
		<div class="cfg-row"><label>Region</label><input data-f="region" value="${e.region || ""}"></div>
		<div class="cfg-row"><label>Account</label><input data-f="account" value="${e.account || ""}"></div>
		<details><summary>Resources and endpoints</summary>
			${["api", "app", "cluster", "service", "alb", "tg", "ecr", "logGroup", "branch"].map((f) => `<div class="cfg-row"><label>${f}</label><input data-f="${f}" value="${e[f] || ""}"></div>`).join("")}
		</details>
		<div style="display:flex;gap:8px;margin-top:6px;align-items:center">
			<button class="btn" data-test="${i}">Test profiles</button><span class="hint" data-testout="${i}"></span>
			<span style="flex:1"></span><button class="btn" data-del="${i}">Remove</button>
		</div>
	</div>`).join("");
	$$("#sEnvList [data-test]").forEach((b) => b.onclick = async () => {
		const i = +b.dataset.test, out = $(`[data-testout="${i}"]`);
		out.textContent = "testing…";
		const profs = readEnvEditor()[i].profiles;
		const results = [];
		for (const p of profs) {
			try {
				const r = await fetch(`/api/validate?profile=${encodeURIComponent(p)}&env=${ENV}`);
				const d = await r.json();
				results.push(`<span class="${d.ok ? "env-ok" : "env-bad"}">${p} ${d.ok ? "· " + d.account : "· no session"}</span>`);
			} catch { results.push(`<span class="env-bad">${p} · unreachable</span>`); }
		}
		out.innerHTML = results.join(" &nbsp; ");
	});
	$$("#sEnvList [data-del]").forEach((b) => b.onclick = () => {
		CFG.envs.splice(+b.dataset.del, 1);
		renderEnvEditor();
	});
}
function readEnvEditor() {
	return $$("#sEnvList .env-edit").map((card) => {
		const o = {};
		$$("[data-f]", card).forEach((inp) => {
			o[inp.dataset.f] = inp.dataset.f === "profiles"
				? inp.value.split(",").map((x) => x.trim()).filter(Boolean)
				: inp.value.trim();
		});
		return o;
	});
}
$("#sAddEnv").onclick = () => {
	if (!CFG) return;
	CFG.envs.push({ key: "new-env", name: "new environment", profiles: [""], region: "eu-west-2", account: "", api: "", app: "", cluster: "", service: "", alb: "", tg: "", ecr: "", logGroup: "", branch: "" });
	renderEnvEditor();
};
$("#sSave").onclick = async () => {
	SETTINGS.defaultEnv = $("#sDefEnv").value;
	SETTINGS.liveMs = +$("#sLiveMs").value;
	SETTINGS.logMs = +$("#sLogMs").value;
	SETTINGS.notif = $("#sNotif").checked;
	SETTINGS.sound = $("#sSound").checked;
	SETTINGS.memWarn = +$("#sMemWarn").value;
	SETTINGS.memCrit = +$("#sMemCrit").value;
	SETTINGS.queueMax = +$("#sQueueMax").value;
	saveSettings(); schedule(); logTimer();
	const msg = $("#sSaveMsg");
	msg.textContent = "saving…";
	try {
		const body = { ...CFG, envs: readEnvEditor(), github: { ...(CFG.github || {}), repo: $("#sGithubRepo").value.trim() }, ai: { provider: $("#sAiProvider").value, model: $("#sAiModel").value.trim(), apiKey: $("#sAiKey").value } };
		body.workspaceAi = CFG.workspace
			? ($("#sAiWsOn").checked ? { provider: $("#sAiWsProvider").value, model: $("#sAiWsModel").value.trim(), apiKey: $("#sAiWsKey").value } : {})
			: null;
		const r = await fetch("/api/config", { method: "POST", body: JSON.stringify(body) });
		const d = await r.json();
		if (d.ok) { CFG = d.config; msg.textContent = "saved"; renderEnvPills(); renderEnvEditor(); await fetchConfig(); renderAiCard(); }
		else msg.textContent = d.detail || "invalid configuration";
	} catch { msg.textContent = "server unreachable"; }
	setTimeout(() => { msg.textContent = ""; }, 4000);
};
$("#cgRetry").onclick = () => { $("#cgWhy").textContent = "retrying…"; LIVE = null; fetchLive(); };
$("#cgSettings").onclick = () => {
	$("#connectGate").classList.add("hidden");
	switchTab("viewSettings");
	setTimeout(() => $("#sEnvList")?.closest(".card")?.scrollIntoView({ block: "start" }), 80);
};

let liveTimer = null, pulseTimer = null;
function schedule() {
	clearInterval(liveTimer); clearInterval(pulseTimer);
	liveTimer = setInterval(fetchLive, SETTINGS.liveMs);
	pulseTimer = setInterval(fetchPulse, 20_000);
}

