import Cookies from "universal-cookie";
import { get, post } from "./serviceHelper";
/**
 * Checks if a WebSocket connection is allowed before attempting to connect.
 * Returns connection availability status.
 */
export async function checkConnectionAvailability(sessionId) {
    try {
        const response = await fetch(`/parhelia/checkConnectionAvailability?sessionId=${sessionId}`, {
            method: "GET",
            credentials: "include",
            headers: {
                Accept: "application/json",
            },
        });
        if (!response.ok) {
            return {
                allowed: false,
                message: `Failed to check connection availability: ${response.status}`,
            };
        }
        return await response.json();
    }
    catch (error) {
        return {
            allowed: false,
            message: error instanceof Error
                ? error.message
                : "Failed to check connection availability",
        };
    }
}
/**
 * Sitecore administrators only: users currently using a concurrent license seat.
 */
export async function getActiveLicenseUsers() {
    const response = await fetch("/parhelia/activeLicenseUsers", {
        method: "GET",
        credentials: "include",
        headers: {
            Accept: "application/json",
        },
    });
    if (!response.ok) {
        throw new Error(`Failed to load active users: ${response.status}`);
    }
    return await response.json();
}
/**
 * Sitecore administrators only: disconnect all editor sessions for a user (frees a seat).
 */
export async function disconnectLicenseUser(userName) {
    const response = await fetch("/parhelia/disconnectLicenseUser", {
        method: "POST",
        credentials: "include",
        headers: {
            Accept: "application/json",
            "Content-Type": "application/json",
        },
        body: JSON.stringify({ userName }),
    });
    if (!response.ok) {
        let detail = `Failed to disconnect user: ${response.status}`;
        try {
            const err = (await response.json());
            if (err.summary)
                detail = err.summary;
        }
        catch {
            /* ignore */
        }
        throw new Error(detail);
    }
    return await response.json();
}
export async function getImageModels() {
    return get("/api/ai/image-models");
}
export async function startImageJob(request, sessionId) {
    return post("/api/ai/image-job", request, sessionId);
}
export function connectSocket(sessionId) {
    const host = window.location.hostname;
    const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
    const port = window.location.port ? `:${window.location.port}` : "";
    const socketUrl = `${protocol}//${host}${port}/parhelia/socket?sessionId=${sessionId}`;
    console.log("Connect to socket: " + socketUrl);
    return new WebSocket(socketUrl);
}
export async function reconnectSession(sessionId) {
    return post("/parhelia/reconnect", {
        sessionId,
    });
}
export async function getPictureValue(field, pictureRawValue, site, sessionId) {
    const fieldItem = field.descriptor.item;
    if (!fieldItem)
        return;
    const response = await fetch("/parhelia/getPictureValue?sessionId=" + sessionId, {
        method: "POST",
        body: JSON.stringify({
            site,
            itemId: fieldItem.id,
            itemLanguage: fieldItem.language,
            itemVersion: fieldItem.version,
            pictureFieldId: field.id,
            pictureValue: JSON.stringify(pictureRawValue),
        }),
        credentials: "include",
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    return await response.json();
}
export async function executeEditOperation(editOperation, sessionId) {
    editOperation.sessionId = sessionId;
    return post("/parhelia/edit", editOperation, sessionId);
}
export async function executeUndo(sessionId, editOperationIds) {
    return post("/parhelia/undo", { editOperationIds }, sessionId);
}
export async function executeRedo(sessionId, editOperationId) {
    return post("/parhelia/redo", { editOperationIds: [editOperationId] }, sessionId);
}
export async function checkOperationImpact(sessionId, operationId, action) {
    return post("/parhelia/operationImpact", { operationId, action }, sessionId);
}
export async function executeDeleteItems(items) {
    return post("/parhelia/deleteItems", items);
}
export async function checkItemReferences(items) {
    return post("/parhelia/checkItemReferences", items);
}
function getItemDescriptor(item) {
    return {
        id: item.id,
        language: item.language,
        version: item.version,
    };
}
export async function lockItems(items) {
    const response = await post("/parhelia/lock", items.map(getItemDescriptor));
    return response;
}
export async function unlockItems(items) {
    const response = await post("/parhelia/unlock", items.map(getItemDescriptor));
    return response;
}
export async function lockField(item, fieldId, sessionId) {
    const response = await post("/parhelia/lockField", {
        item,
        fieldId: fieldId,
        sessionId: sessionId,
    });
    return response;
}
export async function releaseFieldLocks(sessionId) {
    const response = await post("/parhelia/releaseFieldLocks", {
        sessionId,
    });
    return response;
}
export async function forceUnlockField(sessionIdToUnlock, item, fieldId) {
    return post("/parhelia/forceUnlockField", {
        sessionIdToUnlock,
        item,
        fieldId,
    });
}
export async function validateItems(items, sessionId) {
    const response = await post("/parhelia/validate", items.map(getItemDescriptor), sessionId);
    if (response.type !== "success")
        return response;
    return await response;
}
export async function executeWorkflowCommand(item, commandId, comment) {
    const response = await post("/parhelia/executeWorkflowCommand", {
        item,
        commandId,
        comment,
    });
    return response;
}
export async function executeFieldAction(item, fieldId, pageItem, action, sessionId, selectedText, parameters, callback) {
    const response = await fetch("/parhelia/executeFieldAction?sessionId=" + sessionId, {
        method: "POST",
        body: JSON.stringify({
            item,
            pageItem,
            fieldId,
            action,
            selectedText,
            sessionId,
            parameters,
        }),
        credentials: "include",
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    if (response.redirected || response.status === 401) {
        if (typeof window !== "undefined") {
            window.dispatchEvent(new CustomEvent("parhelia:session-expired", {
                detail: {
                    reason: response.redirected ? "login-redirect" : "unauthorized",
                },
            }));
        }
        return {
            type: "unauthorized",
            summary: "Session expired",
            details: "Please login again to continue.",
            response,
        };
    }
    if (response.status === 500) {
        return {
            type: "error",
            summary: "Error",
            details: "An error occured executing the field action.",
            response,
        };
    }
    if (!response?.body)
        return {
            type: "error",
            summary: "Error",
            details: "An error occured.",
            response,
        };
    const reader = response.body.getReader();
    const decoder = new TextDecoder();
    let buffer = "";
    let result = null;
    while (true) {
        const { done, value } = await reader.read();
        if (done) {
            break;
        }
        buffer += decoder.decode(value, { stream: true }); // 'stream: true' ensures that any incomplete multi-byte characters aren't malformed.
        // Split the buffer by newline and keep the last partial line for the next iteration.
        const lines = buffer.split("\n");
        if (lines.length > 0) {
            buffer = lines.pop() || ""; // Incomplete line (if any) is kept for the next iteration.
            for (let line of lines) {
                if (line.trim() === "")
                    continue; // Skip empty lines if any.
                try {
                    const jsonData = JSON.parse(line);
                    callback(jsonData);
                    result = jsonData;
                }
                catch (e) {
                    console.error("Error parsing line:" + line, e);
                }
            }
        }
    }
    // If there's any remaining content in the buffer after processing all chunks, try to process it.
    if (buffer.trim() !== "") {
        try {
            const jsonData = JSON.parse(buffer);
            result = jsonData;
        }
        catch (e) {
            console.error("Error parsing the final buffer content:", e);
        }
    }
    callback(result);
    return result;
}
export async function createVersion(page, sessionId) {
    const response = await fetch(
    // configuration.services.editorService.baseUrl +
    "/parhelia/createVersion?sessionId=" + sessionId, {
        method: "POST",
        body: JSON.stringify({
            item: page,
        }),
        credentials: "include",
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    if (response.ok)
        return { type: "success", response };
    else {
        if (response.redirected || response.status === 401) {
            if (typeof window !== "undefined") {
                window.dispatchEvent(new CustomEvent("parhelia:session-expired", {
                    detail: {
                        reason: response.redirected ? "login-redirect" : "unauthorized",
                    },
                }));
            }
            return {
                type: "unauthorized",
                summary: "Session expired",
                details: "Please login again to continue.",
                response,
            };
        }
        return {
            type: "error",
            summary: "Error",
            details: "An error occured while saving changes.",
            response,
        };
    }
}
export async function createVersionsBatch(items, sessionId) {
    return post("/parhelia/createVersionsBatch", {
        items: items,
    }, sessionId);
}
export async function deleteVersion(page, sessionId) {
    const url = "/parhelia/deleteVersion?sessionId=" + sessionId;
    return await post(url, { item: getItemDescriptor(page) });
}
export async function loadInsertOptions(item) {
    let url = 
    //configuration.services.editorService.baseUrl +
    "/parhelia/insertoptions";
    const response = await fetch(url, {
        method: "POST",
        credentials: "include",
        body: JSON.stringify(item),
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    return await response.json();
}
export async function loadPlaceholderInsertOptions(pageItem, placeholderKeys, layoutMode = "final") {
    let url = "/parhelia/placeholderinsertoptions";
    const response = await fetch(url, {
        method: "POST",
        credentials: "include",
        body: JSON.stringify({ pageItem, placeholderKeys, layoutMode }),
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    const result = await response.json();
    return result;
}
export async function getSharedComponentTarget(pageItem, componentId) {
    const url = "/parhelia/getsharedcomponenttarget";
    const response = await fetch(url, {
        method: "POST",
        credentials: "include",
        body: JSON.stringify({ pageItem, componentId }),
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    return await response.json();
}
export async function loadRenderingParametersSchema(pageItem, componentId) {
    const response = await fetch("/parhelia/getrenderingparameters", {
        method: "POST",
        credentials: "include",
        body: JSON.stringify({ pageItem, componentId }),
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    return await response.json();
}
export async function loadFieldButtons(field) {
    let url = 
    //configuration.services.editorService.baseUrl +
    "/parhelia/fieldbuttons";
    const response = await fetch(url, {
        method: "POST",
        credentials: "include",
        body: JSON.stringify(field),
        headers: {
            "Content-Type": "application/json",
            Cookie: new Cookies().getAll(),
        },
    });
    return await response.json();
}
export async function getLookupSources(field) {
    let url = "/parhelia/getlookupsources";
    const fieldItem = field.descriptor.item;
    const response = await post(url, {
        item: fieldItem,
        fieldId: field.id,
    });
    return (await response.data) || { items: [], database: "master" };
}
export async function executeCreateItem(parent, templateId, name, sessionId, branchId) {
    let url = "/parhelia/createItem";
    const response = post(url, { parent, templateId, name, ...(branchId && { branchId }) }, sessionId);
    return response;
}
export async function getEditHistory(options) {
    const params = new URLSearchParams();
    if (options?.item) {
        params.append("itemId", options.item.id);
        params.append("language", options.item.language);
        params.append("version", options.item.version.toString());
    }
    if (options?.sessionId) {
        params.append("sessionId", options.sessionId);
    }
    if (options?.limit !== undefined) {
        params.append("limit", options.limit.toString());
    }
    // Language filter for global mode (without itemId)
    if (options?.language && !options?.item) {
        params.append("language", options.language);
    }
    if (options?.query?.trim()) {
        params.append("query", options.query.trim());
    }
    const url = `/parhelia/editHistory${params.toString() ? `?${params.toString()}` : ""}`;
    const result = get(url);
    return result;
}
export async function getEditOperation(operationId) {
    const url = `/parhelia/editOperation?id=${encodeURIComponent(operationId)}`;
    return get(url);
}
export async function getAgentHistory(agentId, limit = 1000) {
    const url = `/parhelia/agentHistory?agentId=${encodeURIComponent(agentId)}&limit=${limit}`;
    const result = get(url);
    return result;
}
/**
 * Gets all currently executing long-running operations for the current user.
 * Used for resuming UI state after client reconnect.
 */
export async function getRunningOperations() {
    const url = `/parhelia/runningOperations`;
    const result = get(url);
    return result;
}
export async function getFieldHistory(item, fieldId) {
    let url = "/parhelia/fieldHistory?itemId=" +
        item.id +
        "&language=" +
        item.language +
        "&version=" +
        item.version +
        "&fieldId=" +
        fieldId;
    const result = get(url);
    return result;
}
export async function getUserInfo() {
    return await get("/parhelia/userinfo");
}
export async function getItemVisitors(item) {
    const url = `/parhelia/itemVisitors?itemId=${item.id}&language=${item.language}&version=${item.version}`;
    return get(url);
}
export async function executeMoveItems(items, target, index) {
    return post("/parhelia/moveItems", {
        items: items.map(getItemDescriptor),
        target: getItemDescriptor(target),
        index,
    });
}
export async function executeCopyItems(items, target, index, sessionId) {
    return post("/parhelia/copyItems", {
        items: items.map(getItemDescriptor),
        target: getItemDescriptor(target),
        index,
    }, sessionId);
}
export async function executeDuplicateItem(item, target, name, sessionId) {
    return post("/parhelia/duplicateItem", {
        item: getItemDescriptor(item),
        target: getItemDescriptor(target),
        name,
    }, sessionId);
}
export async function executeChangeTemplate(item, newTemplateId, sessionId) {
    return post("/parhelia/changeTemplate", {
        item: getItemDescriptor(item),
        newTemplateId,
    }, sessionId);
}
//# sourceMappingURL=editService.js.map