let activeContext = null;
let activeSuggestion = null;
let activeStatus = null;
let activeMode = "closed";
let initialized = false;
let provider = null;
let appliedHandler = null;
function element(id) {
    return document.getElementById(id);
}
function isRecord(value) {
    return typeof value === "object" && value !== null && !Array.isArray(value);
}
async function requestJson(path, init = {}) {
    const response = await fetch(path, {
        credentials: "same-origin",
        headers: { "Content-Type": "application/json", Accept: "application/json" },
        ...init,
    });
    const text = await response.text();
    let payload = {};
    try {
        payload = text ? JSON.parse(text) : {};
    }
    catch (_error) {
        payload = {};
    }
    if (!response.ok || !isRecord(payload) || payload.ok === false) {
        const error = isRecord(payload) && typeof payload.error === "string"
            ? payload.error
            : response.statusText;
        throw new Error(error || "Réponse Datafix invalide");
    }
    return payload;
}
function confidencePercentage(value) {
    const parsed = Number(value || 0);
    const percentage = parsed >= 0 && parsed <= 1 ? parsed * 100 : parsed;
    return Math.round(Math.max(0, Math.min(100, percentage)));
}
function declinedStorageKey(batch) {
    return `datafix:integral-keying-declined:${batch}`;
}
function setPanelVisible(visible) {
    const panel = element("pageStructureSuggestionPanel");
    const backdrop = element("pageStructureSuggestionBackdrop");
    if (panel)
        panel.hidden = !visible;
    if (backdrop)
        backdrop.hidden = !visible;
    if (!visible)
        activeMode = "closed";
}
function setTitle(text) {
    const title = element("pageStructureSuggestionTitle");
    if (title)
        title.textContent = text;
}
function setStatus(text, isError = false) {
    const status = element("pageStructureSuggestionStatus");
    if (!status)
        return;
    status.textContent = text;
    status.dataset.kind = isError ? "error" : "neutral";
}
function setSummary(text) {
    const summary = element("pageStructureSuggestionSummary");
    if (summary)
        summary.textContent = text;
}
function clearFeedback() {
    var _a;
    (_a = element("pageStructureResults")) === null || _a === void 0 ? void 0 : _a.replaceChildren();
}
function appendFeedback(feedback) {
    const list = element("pageStructureResults");
    if (!list)
        return;
    const item = document.createElement("li");
    item.className = "page-structure-suggestion__result page-structure-suggestion__result--success";
    item.textContent = `Image ${feedback.image_id} — ${feedback.doctype} — `
        + `${confidencePercentage(feedback.confidence)} % — `
        + `${feedback.header_count} Header(s), ${feedback.record_count} Record(s)`;
    list.appendChild(item);
    item.scrollIntoView({ block: "nearest" });
}
function appendFailure(imageId, message) {
    const list = element("pageStructureResults");
    if (!list)
        return;
    const item = document.createElement("li");
    item.className = "page-structure-suggestion__result page-structure-suggestion__result--error";
    item.textContent = `Image ${imageId} — échec : ${message}`;
    list.appendChild(item);
    item.scrollIntoView({ block: "nearest" });
}
function setProgress(completed, total) {
    const progress = element("pageStructureProgress");
    const label = element("pageStructureProgressLabel");
    const safeTotal = Math.max(0, total);
    const safeCompleted = Math.max(0, Math.min(safeTotal, completed));
    if (progress) {
        progress.hidden = safeTotal === 0;
        progress.max = Math.max(1, safeTotal);
        progress.value = safeCompleted;
    }
    if (label) {
        label.hidden = safeTotal === 0;
        label.textContent = `${safeCompleted} / ${safeTotal} pages traitées`;
    }
}
function configureActions(primary, secondary, primaryVisible = true) {
    const apply = element("btnPageStructureSuggestionApply");
    const cancel = element("btnPageStructureSuggestionCancel");
    const close = element("btnPageStructureSuggestionClose");
    if (apply) {
        apply.hidden = !primaryVisible;
        apply.disabled = false;
        apply.textContent = primary;
    }
    if (cancel) {
        cancel.hidden = false;
        cancel.disabled = false;
        cancel.textContent = secondary;
    }
    if (close)
        close.disabled = false;
}
function setActionsRunning() {
    const apply = element("btnPageStructureSuggestionApply");
    const cancel = element("btnPageStructureSuggestionCancel");
    const close = element("btnPageStructureSuggestionClose");
    if (apply)
        apply.hidden = true;
    if (cancel)
        cancel.hidden = true;
    if (close)
        close.disabled = true;
}
function syncTopbarVisibility(status) {
    // Auto-Correct / Page Fill stay available except on fully AI-keyed Integral lots.
    // AI Structure is Integral Keying only — hide for every other lot/sub-project.
    const integralCompleted = Boolean((status === null || status === void 0 ? void 0 : status.integral_keying) && status.completed);
    const showStructure = Boolean((status === null || status === void 0 ? void 0 : status.integral_keying) && !status.completed);
    const autoCorrect = element("btnApplyDictionaryCorrections");
    const structure = element("btnAiPageStructure");
    const pageFill = element("btnAiPageFill");
    if (autoCorrect)
        autoCorrect.hidden = integralCompleted;
    if (structure)
        structure.hidden = !showStructure;
    if (pageFill)
        pageFill.hidden = integralCompleted;
}
async function getIntegralStatus(context) {
    const response = await requestJson(`/api/batch/${encodeURIComponent(context.batch)}/integral-keying-status`
        + `?sub_project_id=${encodeURIComponent(String(context.subProjectId))}`);
    return response.status;
}
function openIntegralOffer(context, status) {
    activeContext = context;
    activeStatus = status;
    activeSuggestion = null;
    activeMode = "offer";
    setPanelVisible(true);
    setTitle("Integral Keying par AI");
    clearFeedback();
    setProgress(status.processed_pages, status.total_pages);
    const remaining = status.remaining_image_ids.length;
    setStatus("Lot Integral Keying détecté.");
    setSummary(`${remaining} page(s) restante(s) sur ${status.total_pages}. `
        + "Chaque page sera analysée, structurée et keyée dans une requête AI indépendante.");
    configureActions("Lancer sur le lot", "Plus tard");
}
async function maybeOfferIntegralKeying() {
    if (activeMode === "running" || !provider)
        return;
    const context = provider();
    if (!context) {
        syncTopbarVisibility(null);
        return;
    }
    try {
        const status = await getIntegralStatus(context);
        syncTopbarVisibility(status);
        if (!status.integral_keying || !status.eligible || status.completed)
            return;
        if (localStorage.getItem(declinedStorageKey(context.batch)) === "1")
            return;
        openIntegralOffer(context, status);
    }
    catch (_error) {
        syncTopbarVisibility(null);
    }
}
async function requestManualSuggestion(context) {
    activeContext = context;
    activeStatus = null;
    activeSuggestion = null;
    activeMode = "manual";
    setPanelVisible(true);
    setTitle("Structure et keying proposés par l'AI");
    setStatus("Analyse de la page en cours…");
    setSummary("");
    clearFeedback();
    setProgress(0, 0);
    setActionsRunning();
    try {
        const neighbors = {};
        if (context.previousImageId != null)
            neighbors.previous = context.previousImageId;
        if (context.nextImageId != null)
            neighbors.next = context.nextImageId;
        const response = await requestJson("/api/ai/page-structure-suggestion", {
            method: "POST",
            body: JSON.stringify({
                batch: context.batch,
                image_id: context.imageId,
                sub_project_id: context.subProjectId,
                current_doctype: context.currentDoctype,
                current_header_count: context.currentHeaderCount,
                current_record_count: context.currentRecordCount,
                neighbors,
            }),
        });
        activeSuggestion = response.suggestion;
        const suggestion = response.suggestion;
        setStatus("Vérifiez le résultat avant de l'appliquer à cette page.");
        setSummary(`${suggestion.doctype} — ${suggestion.header_count} Header(s), `
            + `${suggestion.record_count} Record(s) — confiance `
            + `${confidencePercentage(suggestion.confidence)} %. Les champs lisibles seront également keyés.`);
        configureActions("Appliquer à cette page", "Annuler");
    }
    catch (error) {
        const message = error instanceof Error ? error.message : "Analyse de la page impossible";
        setStatus(message, true);
        configureActions("Réessayer", "Fermer");
        activeSuggestion = null;
    }
}
async function runIntegralLot() {
    var _a;
    if (!activeContext || !activeStatus)
        return;
    const context = activeContext;
    localStorage.removeItem(declinedStorageKey(context.batch));
    activeMode = "running";
    setTitle("Integral Keying par AI — traitement en cours");
    clearFeedback();
    setActionsRunning();
    const imageIds = [...activeStatus.remaining_image_ids];
    const total = activeStatus.total_pages;
    let completed = activeStatus.processed_pages;
    let failures = 0;
    setProgress(completed, total);
    for (const imageId of imageIds) {
        setStatus(`Analyse de l'image ${imageId}…`);
        try {
            const response = await requestJson(`/api/batch/${encodeURIComponent(context.batch)}/image/${imageId}/ai-structure`, {
                method: "POST",
                body: JSON.stringify({
                    confirmed_lot: true,
                    sub_project_id: context.subProjectId,
                }),
            });
            if (response.feedback)
                appendFeedback(response.feedback);
            completed += 1;
        }
        catch (error) {
            failures += 1;
            const message = error instanceof Error ? error.message : "Erreur inconnue";
            appendFailure(imageId, message);
            completed += 1;
        }
        setProgress(completed, total);
    }
    try {
        activeStatus = await getIntegralStatus(context);
    }
    catch (_error) {
        // Keep the last page response status when the final refresh is unavailable.
    }
    syncTopbarVisibility(activeStatus);
    activeMode = "result";
    if (activeStatus === null || activeStatus === void 0 ? void 0 : activeStatus.completed) {
        setTitle("Integral Keying par AI — terminé");
        setStatus("Toutes les pages ont été structurées et keyées.");
        setSummary(`${activeStatus.processed_pages} page(s) traitée(s) avec succès.`);
        configureActions("", "Fermer", false);
        localStorage.removeItem(declinedStorageKey(context.batch));
    }
    else {
        const remaining = (_a = activeStatus === null || activeStatus === void 0 ? void 0 : activeStatus.remaining_image_ids.length) !== null && _a !== void 0 ? _a : failures;
        setTitle("Integral Keying par AI — traitement incomplet");
        setStatus(`${remaining} page(s) restent à traiter.`, true);
        setSummary("Les pages réussies sont enregistrées. Vous pouvez réessayer uniquement les pages restantes.");
        configureActions("Réessayer les pages restantes", "Fermer");
    }
    if (appliedHandler)
        await appliedHandler();
}
async function applyManualSuggestion() {
    if (!activeContext)
        return;
    if (!activeSuggestion) {
        await requestManualSuggestion(activeContext);
        return;
    }
    const apply = element("btnPageStructureSuggestionApply");
    if (apply)
        apply.disabled = true;
    setStatus("Création et keying confirmés en cours…");
    try {
        await requestJson(`/api/batch/${encodeURIComponent(activeContext.batch)}`
            + `/image/${activeContext.imageId}/structure/apply`, {
            method: "POST",
            body: JSON.stringify({
                confirmed: true,
                sub_project_id: activeContext.subProjectId,
                suggestion: activeSuggestion,
            }),
        });
        setPanelVisible(false);
        if (appliedHandler)
            await appliedHandler();
    }
    catch (error) {
        const message = error instanceof Error ? error.message : "Création de la structure impossible";
        setStatus(message, true);
        if (apply)
            apply.disabled = false;
    }
}
async function openFromTopbar() {
    if (!provider)
        return;
    const context = provider();
    if (!context) {
        syncTopbarVisibility(null);
        setPanelVisible(true);
        setStatus("Aucun sous-projet CI actif pour cette page.", true);
        return;
    }
    try {
        const status = await getIntegralStatus(context);
        syncTopbarVisibility(status);
        if (!status.integral_keying || status.completed)
            return;
        if (status.eligible) {
            openIntegralOffer(context, status);
            return;
        }
    }
    catch (_error) {
        syncTopbarVisibility(null);
        return;
    }
    // Integral template without a CI profile: allow a one-page structure suggestion.
    await requestManualSuggestion(context);
}
function closePanel(rememberDecline = false) {
    if (activeMode === "running")
        return;
    if (rememberDecline && activeMode === "offer" && activeContext) {
        localStorage.setItem(declinedStorageKey(activeContext.batch), "1");
    }
    activeContext = null;
    activeSuggestion = null;
    activeStatus = null;
    setPanelVisible(false);
}
async function primaryAction() {
    if (activeMode === "offer" || activeMode === "result") {
        if (activeMode === "result" && activeContext) {
            activeStatus = await getIntegralStatus(activeContext);
        }
        await runIntegralLot();
        return;
    }
    if (activeMode === "manual")
        await applyManualSuggestion();
}
export function initPageStructureSuggestion(contextProvider, onApplied) {
    var _a, _b, _c, _d, _e;
    if (initialized)
        return;
    initialized = true;
    provider = contextProvider;
    appliedHandler = onApplied;
    (_a = element("btnAiPageStructure")) === null || _a === void 0 ? void 0 : _a.addEventListener("click", () => {
        void openFromTopbar();
    });
    (_b = element("btnPageStructureSuggestionApply")) === null || _b === void 0 ? void 0 : _b.addEventListener("click", () => {
        void primaryAction();
    });
    (_c = element("btnPageStructureSuggestionCancel")) === null || _c === void 0 ? void 0 : _c.addEventListener("click", () => {
        closePanel(true);
    });
    (_d = element("btnPageStructureSuggestionClose")) === null || _d === void 0 ? void 0 : _d.addEventListener("click", () => {
        closePanel(true);
    });
    (_e = element("pageStructureSuggestionBackdrop")) === null || _e === void 0 ? void 0 : _e.addEventListener("click", () => {
        closePanel(true);
    });
    document.addEventListener("datafix:batch-loaded", () => {
        void maybeOfferIntegralKeying();
    });
}
