/**
 * Shared constants for the Local Deep Research frontend.
 * Loaded globally via base.html — available to all pages.
 *
 * Research status values (window.RESEARCH_STATUS) are injected from
 * the Python backend via Jinja2 context processor in:
 *   src/local_deep_research/web/app_factory.py  (inject_frontend_constants)
 *
 * The single source of truth for all status values is:
 *   src/local_deep_research/constants.py::ResearchStatus
 *
 * The template injection happens in:
 *   src/local_deep_research/web/templates/base.html
 *
 * No fallback strings are used — if RESEARCH_STATUS is not injected,
 * the app is broken anyway (base.html renders every page).
 */

if (typeof LDR_CONSTANTS !== 'undefined') {
    if (typeof SafeLogger !== 'undefined') {
        SafeLogger.warn('LDR_CONSTANTS already defined, skipping redeclaration');
    }
} else {
    window.LDR_CONSTANTS = {
        SEARCH_MODE: {
            HYBRID: 'hybrid',
            TEXT: 'text',
            SEMANTIC: 'semantic',
        },
        DEFAULT_LOCAL_SEARCH_TEXT_SEPARATORS: ["\n\n", "\n", ". ", " ", ""],
    };
}

/**
 * Research status predicate helpers and formatting utilities.
 *
 * Uses window.RESEARCH_STATUS (injected from Python via base.html)
 * and window.RESEARCH_TERMINAL_STATES for O(1) terminal-state lookups.
 *
 * Usage:
 *   if (ResearchStates.isTerminal(data.status)) { ... }
 *   if (ResearchStates.isCancelled(data.status)) { ... }
 *   label.textContent = ResearchStates.formatStatus(data.status);
 */
window.ResearchStates = Object.freeze({
    /** True for completed, suspended, failed, error, cancelled */
    isTerminal(status) {
        return window.RESEARCH_TERMINAL_STATES.has(status);
    },

    /** True only for successfully completed research */
    isCompleted(status) {
        return status === window.RESEARCH_STATUS.COMPLETED;
    },

    /** True for failed research (unrecoverable error, includes legacy 'error' status) */
    isFailed(status) {
        return status === window.RESEARCH_STATUS.FAILED
            || status === window.RESEARCH_STATUS.ERROR;
    },

    /** True for user-cancelled research (cancelled or suspended) */
    isCancelled(status) {
        return status === window.RESEARCH_STATUS.CANCELLED
            || status === window.RESEARCH_STATUS.SUSPENDED;
    },

    /** True only for research currently executing (not queued/pending) */
    isInProgress(status) {
        return status === window.RESEARCH_STATUS.IN_PROGRESS;
    },

    /** True for actively running or waiting research */
    isActive(status) {
        return status === window.RESEARCH_STATUS.IN_PROGRESS
            || status === window.RESEARCH_STATUS.QUEUED
            || status === window.RESEARCH_STATUS.PENDING;
    },

    /** Map status to human-readable display label */
    formatStatus(status) {
        const RS = window.RESEARCH_STATUS;
        const labels = {};
        labels[RS.IN_PROGRESS] = 'In Progress';
        labels[RS.COMPLETED] = 'Completed';
        labels[RS.FAILED] = 'Failed';
        labels[RS.SUSPENDED] = 'Cancelled';
        labels[RS.CANCELLED] = 'Cancelled';
        labels[RS.QUEUED] = 'Queued';
        labels[RS.PENDING] = 'Pending';
        labels[RS.ERROR] = 'Error';
        labels['not_started'] = 'Not Started';

        return labels[status] || (status
            ? status.charAt(0).toUpperCase() + status.slice(1).replace(/_/g, ' ')
            : 'Unknown');
    },

    /** Determine log level for a given research status */
    logLevel(status) {
        if (!status) return 'info';
        // Check error before terminal — 'error' is in terminal set but should log as error
        if (status === window.RESEARCH_STATUS.ERROR
            || (typeof status === 'string' && status.includes('error'))) {
            return 'error';
        }
        if (window.RESEARCH_TERMINAL_STATES.has(status)) {
            return 'milestone';
        }
        return 'info';
    },
});
