/**
 * Tests for ResearchStates (config/constants.js)
 *
 * Tests the status predicate helpers and formatting utilities
 * that are used throughout the frontend to determine research state.
 */

// Stub the backend-injected constants before loading the module
window.RESEARCH_STATUS = {
    IN_PROGRESS: 'in_progress',
    COMPLETED: 'completed',
    FAILED: 'failed',
    SUSPENDED: 'suspended',
    CANCELLED: 'cancelled',
    QUEUED: 'queued',
    PENDING: 'pending',
    ERROR: 'error',
};

window.RESEARCH_TERMINAL_STATES = new Set([
    'completed', 'suspended', 'failed', 'error', 'cancelled',
]);

// Load the module — attaches window.LDR_CONSTANTS and window.ResearchStates
import '@js/config/constants.js';

const RS = window.ResearchStates;

describe('LDR_CONSTANTS', () => {
    it('defines SEARCH_MODE values', () => {
        expect(window.LDR_CONSTANTS.SEARCH_MODE.HYBRID).toBe('hybrid');
        expect(window.LDR_CONSTANTS.SEARCH_MODE.TEXT).toBe('text');
        expect(window.LDR_CONSTANTS.SEARCH_MODE.SEMANTIC).toBe('semantic');
    });
});

describe('ResearchStates', () => {
    describe('isTerminal', () => {
        it('returns true for completed', () => {
            expect(RS.isTerminal('completed')).toBe(true);
        });

        it('returns true for failed', () => {
            expect(RS.isTerminal('failed')).toBe(true);
        });

        it('returns true for error', () => {
            expect(RS.isTerminal('error')).toBe(true);
        });

        it('returns true for suspended', () => {
            expect(RS.isTerminal('suspended')).toBe(true);
        });

        it('returns true for cancelled', () => {
            expect(RS.isTerminal('cancelled')).toBe(true);
        });

        it('returns false for in_progress', () => {
            expect(RS.isTerminal('in_progress')).toBe(false);
        });

        it('returns false for queued', () => {
            expect(RS.isTerminal('queued')).toBe(false);
        });

        it('returns false for pending', () => {
            expect(RS.isTerminal('pending')).toBe(false);
        });
    });

    describe('isCompleted', () => {
        it('returns true only for completed status', () => {
            expect(RS.isCompleted('completed')).toBe(true);
        });

        it('returns false for failed', () => {
            expect(RS.isCompleted('failed')).toBe(false);
        });

        it('returns false for in_progress', () => {
            expect(RS.isCompleted('in_progress')).toBe(false);
        });
    });

    describe('isFailed', () => {
        it('returns true for failed', () => {
            expect(RS.isFailed('failed')).toBe(true);
        });

        it('returns true for legacy error status', () => {
            expect(RS.isFailed('error')).toBe(true);
        });

        it('returns false for completed', () => {
            expect(RS.isFailed('completed')).toBe(false);
        });

        it('returns false for cancelled', () => {
            expect(RS.isFailed('cancelled')).toBe(false);
        });
    });

    describe('isCancelled', () => {
        it('returns true for cancelled', () => {
            expect(RS.isCancelled('cancelled')).toBe(true);
        });

        it('returns true for suspended', () => {
            expect(RS.isCancelled('suspended')).toBe(true);
        });

        it('returns false for failed', () => {
            expect(RS.isCancelled('failed')).toBe(false);
        });

        it('returns false for completed', () => {
            expect(RS.isCancelled('completed')).toBe(false);
        });
    });

    describe('isInProgress', () => {
        it('returns true for in_progress', () => {
            expect(RS.isInProgress('in_progress')).toBe(true);
        });

        it('returns false for queued', () => {
            expect(RS.isInProgress('queued')).toBe(false);
        });

        it('returns false for completed', () => {
            expect(RS.isInProgress('completed')).toBe(false);
        });
    });

    describe('isActive', () => {
        it('returns true for in_progress', () => {
            expect(RS.isActive('in_progress')).toBe(true);
        });

        it('returns true for queued', () => {
            expect(RS.isActive('queued')).toBe(true);
        });

        it('returns true for pending', () => {
            expect(RS.isActive('pending')).toBe(true);
        });

        it('returns false for completed', () => {
            expect(RS.isActive('completed')).toBe(false);
        });

        it('returns false for failed', () => {
            expect(RS.isActive('failed')).toBe(false);
        });
    });

    describe('formatStatus', () => {
        it('maps in_progress to In Progress', () => {
            expect(RS.formatStatus('in_progress')).toBe('In Progress');
        });

        it('maps completed to Completed', () => {
            expect(RS.formatStatus('completed')).toBe('Completed');
        });

        it('maps failed to Failed', () => {
            expect(RS.formatStatus('failed')).toBe('Failed');
        });

        it('maps suspended to Cancelled', () => {
            expect(RS.formatStatus('suspended')).toBe('Cancelled');
        });

        it('maps cancelled to Cancelled', () => {
            expect(RS.formatStatus('cancelled')).toBe('Cancelled');
        });

        it('maps queued to Queued', () => {
            expect(RS.formatStatus('queued')).toBe('Queued');
        });

        it('maps pending to Pending', () => {
            expect(RS.formatStatus('pending')).toBe('Pending');
        });

        it('maps error to Error', () => {
            expect(RS.formatStatus('error')).toBe('Error');
        });

        it('maps not_started to Not Started', () => {
            expect(RS.formatStatus('not_started')).toBe('Not Started');
        });

        it('capitalizes unknown statuses and replaces underscores', () => {
            expect(RS.formatStatus('some_custom_status')).toBe('Some custom status');
        });

        it('returns Unknown for falsy input', () => {
            expect(RS.formatStatus(null)).toBe('Unknown');
            expect(RS.formatStatus(undefined)).toBe('Unknown');
            expect(RS.formatStatus('')).toBe('Unknown');
        });
    });

    describe('logLevel', () => {
        it('returns error for error status', () => {
            expect(RS.logLevel('error')).toBe('error');
        });

        it('returns error for statuses containing "error"', () => {
            expect(RS.logLevel('some_error_state')).toBe('error');
        });

        it('returns milestone for terminal states (non-error)', () => {
            expect(RS.logLevel('completed')).toBe('milestone');
            expect(RS.logLevel('failed')).toBe('milestone');
            expect(RS.logLevel('cancelled')).toBe('milestone');
        });

        it('returns info for active states', () => {
            expect(RS.logLevel('in_progress')).toBe('info');
            expect(RS.logLevel('queued')).toBe('info');
            expect(RS.logLevel('pending')).toBe('info');
        });

        it('returns info for falsy input', () => {
            expect(RS.logLevel(null)).toBe('info');
            expect(RS.logLevel(undefined)).toBe('info');
            expect(RS.logLevel('')).toBe('info');
        });
    });

    it('is frozen (immutable)', () => {
        expect(Object.isFrozen(RS)).toBe(true);
    });
});
