/**
 * V2 Request Type Definitions
 *
 * A Request represents a single user goal — "one thing the user wants
 * the system to accomplish." Requests are the primary user-facing object
 * in V2 architecture.
 *
 * @module types/v2/request.types
 */
import { v4 as uuidv4 } from 'uuid';
/** All valid RequestStatus values as a readonly array. */
export const REQUEST_STATUSES = [
    'open',
    'ready',
    'running',
    'blocked',
    'waiting_confirmation',
    'done',
    'cancelled',
];
/** Terminal statuses — no further transitions allowed (except cancel). */
export const TERMINAL_REQUEST_STATUSES = new Set([
    'done',
    'cancelled',
]);
/** All valid IntentCategory values. */
export const INTENT_CATEGORIES = [
    'query',
    'code_change',
    'debugging',
    'deployment',
    'research',
    'review',
    'planning',
    'communication',
    'other',
];
// ---------------------------------------------------------------------------
// Valid State Transitions
// ---------------------------------------------------------------------------
/**
 * Map of valid status transitions.
 * Key = current status, Value = set of allowed next statuses.
 */
export const REQUEST_TRANSITIONS = {
    open: new Set(['ready', 'done', 'cancelled']),
    ready: new Set(['running', 'cancelled']),
    running: new Set(['blocked', 'waiting_confirmation', 'done', 'cancelled']),
    blocked: new Set(['running', 'cancelled']),
    waiting_confirmation: new Set(['done', 'running', 'cancelled']),
    done: new Set(),
    cancelled: new Set(),
};
// ---------------------------------------------------------------------------
// Type Guards
// ---------------------------------------------------------------------------
/**
 * Checks whether a string is a valid RequestStatus.
 *
 * @param value - The string to check
 * @returns True if value is a valid RequestStatus
 */
export function isValidRequestStatus(value) {
    return REQUEST_STATUSES.includes(value);
}
/**
 * Checks whether a string is a valid IntentCategory.
 *
 * @param value - The string to check
 * @returns True if value is a valid IntentCategory
 */
export function isValidIntentCategory(value) {
    return INTENT_CATEGORIES.includes(value);
}
/**
 * Checks whether a status transition is valid according to the state machine.
 *
 * @param from - Current status
 * @param to - Desired next status
 * @returns True if transition is allowed
 */
export function isValidRequestTransition(from, to) {
    return REQUEST_TRANSITIONS[from].has(to);
}
/**
 * Validates that an object is structurally a valid Request.
 *
 * @param value - Unknown value to validate
 * @returns True if value conforms to the Request interface
 */
export function isRequest(value) {
    if (typeof value !== 'object' || value === null)
        return false;
    const obj = value;
    return (typeof obj.id === 'string' &&
        typeof obj.sourceConversationItemId === 'string' &&
        typeof obj.title === 'string' &&
        typeof obj.description === 'string' &&
        typeof obj.status === 'string' &&
        isValidRequestStatus(obj.status) &&
        typeof obj.createdAt === 'string' &&
        typeof obj.updatedAt === 'string' &&
        Array.isArray(obj.workItemIds));
}
// ---------------------------------------------------------------------------
// Validation
// ---------------------------------------------------------------------------
/**
 * Validates CreateRequestInput and returns an array of error messages.
 * Empty array means input is valid.
 *
 * @param input - The creation input to validate
 * @returns Array of validation error strings (empty = valid)
 */
export function validateCreateRequestInput(input) {
    const errors = [];
    if (!input.sourceConversationItemId || typeof input.sourceConversationItemId !== 'string') {
        errors.push('sourceConversationItemId is required and must be a string');
    }
    if (!input.title || typeof input.title !== 'string') {
        errors.push('title is required and must be a non-empty string');
    }
    if (!input.description || typeof input.description !== 'string') {
        errors.push('description is required and must be a non-empty string');
    }
    if (input.priority && !['low', 'normal', 'high'].includes(input.priority)) {
        errors.push('priority must be one of: low, normal, high');
    }
    if (input.intentCategory && !isValidIntentCategory(input.intentCategory)) {
        errors.push(`intentCategory must be one of: ${INTENT_CATEGORIES.join(', ')}`);
    }
    if (input.intentLevel && !['L0', 'L1', 'L2', 'L3'].includes(input.intentLevel)) {
        errors.push('intentLevel must be one of: L0, L1, L2, L3');
    }
    return errors;
}
// ---------------------------------------------------------------------------
// Factory
// ---------------------------------------------------------------------------
/**
 * Creates a new Request with sensible defaults.
 *
 * @param input - Required and optional creation fields
 * @returns A fully populated Request object
 *
 * @example
 * ```typescript
 * const request = createRequest({
 *   sourceConversationItemId: 'conv-123',
 *   title: 'Deploy staging',
 *   description: 'Deploy the current build to staging env',
 * });
 * ```
 */
export function createRequest(input) {
    const now = new Date().toISOString();
    return {
        id: uuidv4(),
        sourceConversationItemId: input.sourceConversationItemId,
        title: input.title,
        description: input.description,
        status: 'open',
        priority: input.priority ?? 'normal',
        requiresConfirmation: input.requiresConfirmation ?? false,
        confirmationReason: input.confirmationReason,
        workItemIds: [],
        missionId: input.missionId,
        intentLevel: input.intentLevel ?? 'L1',
        intentCategory: input.intentCategory ?? 'other',
        tags: input.tags ?? [],
        createdAt: now,
        updatedAt: now,
        totalInputTokens: 0,
        totalOutputTokens: 0,
        totalCost: 0,
    };
}
//# sourceMappingURL=request.types.js.map