import { checkConnectionAvailability } from "../../services/editService";
import { getSystemStatus } from "../../services/systemService";
import { setupWizardService } from "../../../setup/services/setupWizardService";
const systemStatusActions = {
    "license-expiring": {
        targetPanel: "about",
        targetHash: "edit-license",
        actionLabel: "Edit License",
    },
    "models-missing-pricing": {
        targetPanel: "ai-models",
        actionLabel: "Open Models",
    },
    "search-index-low-items": {
        targetPanel: "search-index",
        actionLabel: "View Index Status",
    },
    "search-index-queue-stalled": {
        targetPanel: "search-index",
        actionLabel: "View Index Status",
    },
};
function getSystemStatusAction(message) {
    if (!message.code) {
        return undefined;
    }
    return systemStatusActions[message.code];
}
function createEphemeralSessionId() {
    if (typeof crypto !== "undefined" && "randomUUID" in crypto) {
        return crypto.randomUUID();
    }
    return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, (c) => {
        const r = (Math.random() * 16) | 0;
        const v = c === "x" ? r : (r & 0x3) | 0x8;
        return v.toString(16);
    });
}
function isSessionOrAuthRejection(closeCode, closeReason) {
    if (closeCode === 1008)
        return true;
    if (!closeReason)
        return false;
    const reason = closeReason.toLowerCase();
    return (reason.includes("session") ||
        reason.includes("revoked") ||
        reason.includes("unauthor") ||
        reason.includes("forbidden") ||
        reason.includes("policy"));
}
async function isUserAuthenticatedForEditor() {
    try {
        const response = await fetch("/parhelia/userinfo", {
            method: "GET",
            credentials: "include",
            headers: {
                "Cache-Control": "no-cache",
            },
        });
        if (response.status === 401 || response.status === 403) {
            return false;
        }
        return true;
    }
    catch {
        // Unknown if auth is valid (network error, startup race, etc.)
        return undefined;
    }
}
/**
 * Check that WebSocket connections are supported by the server (IIS).
 * WebSocket is required for real-time editing, live updates, and AI features.
 *
 * The most common failure case is IIS not having the "WebSocket Protocol"
 * feature installed under Application Development.
 */
export const webSocketCheck = {
    id: "websocket",
    name: "WebSocket Support",
    isBlocking: true,
    check: async () => {
        // 1. Check browser support
        if (typeof WebSocket === "undefined") {
            return [
                {
                    id: "websocket-browser-unsupported",
                    title: "Browser Does Not Support WebSockets",
                    description: "Your browser does not support WebSocket connections, which are required for the editor to function. " +
                        "Please use a modern browser such as Chrome, Firefox, Edge, or Safari.",
                    severity: "error",
                },
            ];
        }
        // 2. Test server-side WebSocket support by attempting a real connection
        try {
            const host = window.location.hostname;
            const protocol = window.location.protocol === "https:" ? "wss:" : "ws:";
            const port = window.location.port ? `:${window.location.port}` : "";
            // Use a unique, throwaway session id for the probe to avoid collisions
            // with existing sessions from previous tabs or test runs.
            const testSessionId = createEphemeralSessionId();
            const socketUrl = `${protocol}//${host}${port}/parhelia/socket?sessionId=${testSessionId}`;
            const result = await new Promise((resolve) => {
                let settled = false;
                let hadError = false;
                let closeCode;
                let closeReason;
                const timeout = setTimeout(() => {
                    if (!settled) {
                        settled = true;
                        try {
                            socket.close();
                        }
                        catch {
                            /* ignore */
                        }
                        resolve({
                            status: "failed",
                            closeCode,
                            closeReason,
                            hadError,
                            timedOut: true,
                        });
                    }
                }, 10000);
                const socket = new WebSocket(socketUrl);
                socket.addEventListener("open", () => {
                    if (!settled) {
                        settled = true;
                        clearTimeout(timeout);
                        try {
                            socket.close(1000);
                        }
                        catch {
                            /* ignore */
                        }
                        resolve({ status: "ok" });
                    }
                });
                socket.addEventListener("error", () => {
                    hadError = true;
                    // The error event is always followed by a close event.
                    // We handle the failure in the close listener.
                });
                socket.addEventListener("close", (event) => {
                    closeCode = event.code;
                    closeReason = event.reason;
                    if (!settled) {
                        settled = true;
                        clearTimeout(timeout);
                        resolve({
                            status: "failed",
                            closeCode,
                            closeReason,
                            hadError,
                            timedOut: false,
                        });
                    }
                });
            });
            if (result.status === "ok") {
                return [];
            }
            // Concurrent user limit rejects the WebSocket upgrade; server/IIS WebSockets are fine.
            try {
                const avail = await checkConnectionAvailability(testSessionId);
                if (avail.allowed === false &&
                    avail.message &&
                    /concurrent|maximum concurrent users/i.test(avail.message)) {
                    return [];
                }
            }
            catch {
                /* ignore */
            }
            const looksLikeSessionOrAuthFailure = isSessionOrAuthRejection(result.closeCode, result.closeReason);
            const authState = await isUserAuthenticatedForEditor();
            if (looksLikeSessionOrAuthFailure || authState === false) {
                return [
                    {
                        id: "websocket-session-or-auth-rejected",
                        title: "WebSocket Session Rejected",
                        description: "The server rejected the WebSocket session/authentication check. " +
                            "This is usually a session ownership or login issue, not missing IIS WebSocket support.\n\n" +
                            "Try refreshing the page or signing in again. If this happens in automated tests, " +
                            "ensure each run uses valid auth cookies and avoids reusing stale sessions across browsers/workers.",
                        severity: "error",
                    },
                ];
            }
            return [
                {
                    id: "websocket-server-unavailable",
                    title: "WebSocket Connection Failed",
                    description: "Unable to establish a WebSocket connection to the server. " +
                        "The editor requires WebSocket support for real-time editing, live updates, and AI features.\n\n" +
                        "The most common cause is the WebSocket Protocol feature not being enabled in IIS:\n" +
                        "1. Open Server Manager → Manage → Add Roles and Features\n" +
                        "2. Navigate to Server Roles → Web Server (IIS) → Web Server → Application Development\n" +
                        "3. Enable 'WebSocket Protocol' and complete the installation\n" +
                        "4. Restart IIS (iisreset) and reload this page\n\n" +
                        "If you are using a reverse proxy or load balancer, ensure it is configured to support WebSocket connections.",
                    severity: "error",
                },
            ];
        }
        catch (e) {
            return [
                {
                    id: "websocket-check-error",
                    title: "WebSocket Support Check Failed",
                    description: e?.message || "An unexpected error occurred while verifying WebSocket support.",
                    severity: "error",
                },
            ];
        }
    },
};
/**
 * Check for database migration issues and system warnings
 */
export const databaseCheck = {
    id: "database",
    name: "Database",
    isBlocking: true,
    check: async () => {
        try {
            const res = await getSystemStatus();
            const messages = res?.data?.messages || [];
            const results = [];
            // Add error messages (blocking)
            const errors = messages.filter((m) => m.severity === "error");
            if (errors.length > 0) {
                results.push({
                    id: "database-errors",
                    title: "Database Migration Issues",
                    description: errors.map((x) => x.message).join("\n"),
                    severity: "error",
                    actionLabel: "View Details",
                });
            }
            // Add warning messages (non-blocking)
            const warnings = messages.filter((m) => m.severity === "warning");
            warnings.forEach((warning, index) => {
                const action = getSystemStatusAction(warning);
                results.push({
                    id: `system-warning-${index}`,
                    title: "System Warning",
                    description: warning.message,
                    severity: "warning",
                    ...action,
                });
            });
            return results;
        }
        catch (e) {
            return [
                {
                    id: "database-check-failed",
                    title: "Database Status Check Failed",
                    description: e?.message || "Failed to check database status",
                    severity: "error",
                    actionLabel: "View Details",
                },
            ];
        }
    },
};
/**
 * Combined check for AI configuration (providers, models, embeddings, agents).
 * Uses the StatusSummary endpoint which is accessible to all authenticated users,
 * not just administrators.
 */
export const aiConfigurationCheck = {
    id: "ai-configuration",
    name: "AI Configuration",
    check: async () => {
        try {
            const summary = await setupWizardService.getStatusSummary();
            const results = [];
            // Check providers
            if (!summary.hasProviders) {
                results.push({
                    id: "no-providers",
                    title: "No AI Providers Configured",
                    description: "Configure at least one AI provider (Anthropic, OpenAI, OpenRouter, or Google Vertex AI) to enable AI features.",
                    severity: "warning",
                    targetPanel: "ai-providers",
                    actionLabel: "Add Provider",
                });
            }
            // Check models
            if (!summary.hasModels) {
                results.push({
                    id: "no-models",
                    title: "No AI Models Installed",
                    description: "Install at least one AI model to enable chat and content generation features.",
                    severity: "warning",
                    targetPanel: "ai-models",
                    actionLabel: "Add Models",
                });
            }
            // Check embeddings
            if (!summary.hasEmbeddingsModels) {
                results.push({
                    id: "no-embeddings",
                    title: "No Embeddings Model Configured",
                    description: "Install an embeddings model to enable semantic search functionality.",
                    severity: "warning",
                    targetPanel: "search-config",
                    actionLabel: "Configure Search",
                });
            }
            else if (!summary.hasEmbeddingsConfigured) {
                results.push({
                    id: "embeddings-not-selected",
                    title: "Embeddings Model Not Selected",
                    description: "An embeddings model is installed but not selected in search configuration. Select an embeddings model to enable semantic search.",
                    severity: "warning",
                    targetPanel: "search-config",
                    actionLabel: "Configure Search",
                });
            }
            return results;
        }
        catch (e) {
            return [
                {
                    id: "ai-configuration-check-failed",
                    title: "AI Configuration Check Failed",
                    description: e?.message || "Failed to check AI configuration",
                    severity: "error",
                },
            ];
        }
    },
};
// Legacy individual checks - kept for backwards compatibility but now use StatusSummary
// These are exported but not included in coreStatusChecks to avoid duplicate checks
/**
 * @deprecated Use aiConfigurationCheck instead
 */
export const providersCheck = {
    id: "providers",
    name: "AI Providers",
    check: async () => {
        try {
            const summary = await setupWizardService.getStatusSummary();
            if (!summary.hasProviders) {
                return [
                    {
                        id: "no-providers",
                        title: "No AI Providers Configured",
                        description: "Configure at least one AI provider (Anthropic, OpenAI, OpenRouter, or Google Vertex AI) to enable AI features.",
                        severity: "warning",
                        targetPanel: "ai-providers",
                        actionLabel: "Add Provider",
                    },
                ];
            }
        }
        catch (e) {
            return [
                {
                    id: "providers-check-failed",
                    title: "Provider Check Failed",
                    description: e?.message || "Failed to check AI providers",
                    severity: "error",
                    targetPanel: "ai-providers",
                    actionLabel: "View Providers",
                },
            ];
        }
        return [];
    },
};
/**
 * @deprecated Use aiConfigurationCheck instead
 */
export const modelsCheck = {
    id: "models",
    name: "AI Models",
    check: async () => {
        try {
            const summary = await setupWizardService.getStatusSummary();
            if (!summary.hasModels) {
                return [
                    {
                        id: "no-models",
                        title: "No AI Models Installed",
                        description: "Install at least one AI model to enable chat and content generation features.",
                        severity: "warning",
                        targetPanel: "ai-models",
                        actionLabel: "Add Models",
                    },
                ];
            }
        }
        catch (e) {
            return [
                {
                    id: "models-check-failed",
                    title: "Models Check Failed",
                    description: e?.message || "Failed to check AI models",
                    severity: "error",
                    targetPanel: "ai-models",
                    actionLabel: "View Models",
                },
            ];
        }
        return [];
    },
};
/**
 * @deprecated Use aiConfigurationCheck instead
 */
export const embeddingsCheck = {
    id: "embeddings",
    name: "Embeddings",
    check: async () => {
        try {
            const summary = await setupWizardService.getStatusSummary();
            if (!summary.hasEmbeddingsModels) {
                return [
                    {
                        id: "no-embeddings",
                        title: "No Embeddings Model Configured",
                        description: "Install an embeddings model to enable semantic search functionality.",
                        severity: "warning",
                        targetPanel: "search-config",
                        actionLabel: "Configure Search",
                    },
                ];
            }
            if (!summary.hasEmbeddingsConfigured) {
                return [
                    {
                        id: "embeddings-not-selected",
                        title: "Embeddings Model Not Selected",
                        description: "An embeddings model is installed but not selected in search configuration. Select an embeddings model to enable semantic search.",
                        severity: "warning",
                        targetPanel: "search-config",
                        actionLabel: "Configure Search",
                    },
                ];
            }
        }
        catch (e) {
            return [
                {
                    id: "embeddings-check-failed",
                    title: "Embeddings Check Failed",
                    description: e?.message || "Failed to check embeddings configuration",
                    severity: "error",
                    targetPanel: "search-config",
                    actionLabel: "View Search Config",
                },
            ];
        }
        return [];
    },
};
/**
 * All core status checks bundled together.
 * Uses a combined AI configuration check for efficiency and non-admin access.
 */
export const coreStatusChecks = [
    webSocketCheck,
    databaseCheck,
    aiConfigurationCheck,
];
//# sourceMappingURL=coreStatusChecks.js.map