/**
* suggest.js — Подсказки промптов из истории и генерация через Codex
*/
import { apiFetch } from "./api.js";
import { getState, setSuggestRunning } from "./state.js";
function applyPrompt(promptText) {
const promptInput = document.querySelector("#prompt");
const promptCounter = document.querySelector("#prompt-counter");
const editButton = document.querySelector("#edit-button");
if (!promptInput) return;
promptInput.value = promptText;
if (promptCounter) {
promptCounter.textContent = `${promptText.length} / 1000`;
}
const state = getState();
if (editButton) {
editButton.disabled = !state.currentVersionId || !promptText.trim() || state.isBusy;
}
}
export function renderSuggestChips(container, items) {
if (!container) return;
container.innerHTML = "";
for (const item of items) {
const text = String(item || "").trim();
if (!text) continue;
const chip = document.createElement("button");
chip.type = "button";
chip.className = "suggest-chip";
chip.textContent = text;
chip.addEventListener("click", () => applyPrompt(text));
container.appendChild(chip);
}
}
export async function loadSuggestHistoryChips() {
const container = document.querySelector("#suggest-history-chips");
if (!container) return;
try {
const res = await apiFetch("/api/suggest-prompts");
const prompts = Array.isArray(res?.prompts) ? res.prompts : [];
if (prompts.length === 0) {
container.innerHTML = 'В истории пока нет промптов';
return;
}
renderSuggestChips(container, prompts);
} catch {
container.innerHTML = 'Не удалось загрузить подсказки';
}
}
export function updateSuggestCodexButton() {
const suggestBtn = document.querySelector("#suggest-button");
const codexBtn = document.querySelector("#suggest-codex-button");
const state = getState();
const canSuggest = Boolean(state.currentVersionId) && !state.isBusy;
if (suggestBtn) {
suggestBtn.disabled = !canSuggest;
}
if (codexBtn) {
codexBtn.disabled = !canSuggest || state.suggestRunning;
}
}
export async function runSuggest() {
const state = getState();
if (!state.currentVersionId || state.suggestRunning || state.isBusy) {
return;
}
const statusEl = document.querySelector("#suggest-codex-status");
const chipsContainer = document.querySelector("#suggest-codex-chips");
const codexBtn = document.querySelector("#suggest-codex-button");
setSuggestRunning(true);
updateSuggestCodexButton();
if (statusEl) statusEl.textContent = "Codex анализирует кадр…";
if (chipsContainer) chipsContainer.innerHTML = "";
try {
const res = await apiFetch("/api/suggest", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ sourceId: state.currentVersionId }),
});
const jobId = res.jobId;
await pollSuggestJob(jobId);
} catch (err) {
if (statusEl) statusEl.textContent = `Ошибка: ${err.message}`;
setSuggestRunning(false);
updateSuggestCodexButton();
}
}
async function pollSuggestJob(jobId) {
const statusEl = document.querySelector("#suggest-codex-status");
const chipsContainer = document.querySelector("#suggest-codex-chips");
let failures = 0;
const poll = async () => {
try {
const data = await apiFetch(`/api/jobs/${jobId}/status`);
failures = 0;
if (data.status === "queued") {
if (statusEl) {
statusEl.textContent = data.queuePosition
? `В очереди (позиция ${data.queuePosition})…`
: "В очереди…";
}
setTimeout(poll, 1500);
return;
}
if (data.status === "running") {
if (statusEl) statusEl.textContent = "Codex генерирует варианты…";
setTimeout(poll, 1500);
return;
}
if (data.status === "done") {
if (statusEl) statusEl.textContent = "";
const suggestions = data.result?.suggestions || [];
if (suggestions.length > 0) {
renderSuggestChips(chipsContainer, suggestions);
} else {
if (statusEl) statusEl.textContent = "Codex не вернул вариантов.";
}
setSuggestRunning(false);
updateSuggestCodexButton();
return;
}
if (data.status === "error" || data.status === "interrupted") {
if (statusEl) statusEl.textContent = `Ошибка: ${data.error || "Не удалось получить подсказки."}`;
setSuggestRunning(false);
updateSuggestCodexButton();
return;
}
setTimeout(poll, 1500);
} catch (err) {
failures++;
if (failures >= 5) {
if (statusEl) statusEl.textContent = `Ошибка связи с сервером: ${err.message}`;
setSuggestRunning(false);
updateSuggestCodexButton();
return;
}
setTimeout(poll, 2000);
}
};
poll();
}
export function initSuggest() {
const suggestBtn = document.querySelector("#suggest-button");
const suggestPanel = document.querySelector("#suggest-panel");
const codexBtn = document.querySelector("#suggest-codex-button");
if (suggestBtn && suggestPanel) {
suggestBtn.addEventListener("click", () => {
const isHidden = suggestPanel.hidden;
suggestPanel.hidden = !isHidden;
if (isHidden) {
loadSuggestHistoryChips();
}
});
}
if (codexBtn) {
codexBtn.addEventListener("click", runSuggest);
}
}