import { intentCategories, intents, targetCapabilities, usagePatterns, } from './registry.js';
import { INTENT_OUTPUT_NAME, INTENT_POLICY_LAYER_NAME, INTENT_RESOLUTION_PROCESS_NAME, } from './types.js';
const normalize = (value) => value.trim().toLowerCase();
const DEFAULT_PHASE = 'experimental';
const ALL_PHASES = ['experimental', 'preview', 'stable', 'deprecated'];
const TARGET_KINDS = [
    'asset',
    'component',
    'style',
];
const isTargetKind = (value) => TARGET_KINDS.includes(value);
const isIntentPhase = (value) => ALL_PHASES.includes(value);
const normalizePhase = (phase) => {
    if (!phase) {
        return DEFAULT_PHASE;
    }
    const normalized = normalize(phase);
    return isIntentPhase(normalized) ? normalized : DEFAULT_PHASE;
};
const normalizePhaseFilter = (phases) => {
    if (!phases || phases.length === 0) {
        return new Set([DEFAULT_PHASE]);
    }
    const normalized = phases
        .map((phase) => normalizePhase(phase))
        .filter((phase, index, list) => list.indexOf(phase) === index);
    return new Set(normalized.length > 0 ? normalized : [DEFAULT_PHASE]);
};
const isAllowedPhase = (phase, allowedPhases) => allowedPhases.has(phase);
const withCategoryPhase = (category) => ({
    ...category,
    phase: normalizePhase(category.phase),
});
const withIntentPhase = (intent) => ({
    ...intent,
    phase: normalizePhase(intent.phase),
});
const withCapabilityPhase = (capability) => ({
    ...capability,
    phase: normalizePhase(capability.phase),
});
const withPatternPhase = (pattern) => ({
    ...pattern,
    phase: normalizePhase(pattern.phase),
});
/**
 * Normalize an intent ID for deterministic registry lookup.
 */
export const normalizeIntentId = (intentId) => normalize(intentId);
/**
 * Normalize a target reference so matching stays deterministic across registry lookups.
 */
export const normalizeTargetRef = (target) => {
    const normalizedKind = normalize(target.kind);
    const kind = isTargetKind(normalizedKind) ? normalizedKind : 'component';
    const classes = target.classes
        ?.map((entry) => normalize(entry).replace(/^\./, ''))
        .filter(Boolean);
    const normalized = {
        kind,
    };
    if (target.id) {
        normalized.id = normalize(target.id);
    }
    if (target.name) {
        normalized.name = normalize(target.name);
    }
    if (target.selector) {
        normalized.selector = normalize(target.selector);
    }
    if (target.layer) {
        normalized.layer = normalize(target.layer);
    }
    if (classes && classes.length > 0) {
        normalized.classes = Array.from(new Set(classes)).sort();
    }
    return normalized;
};
const targetKey = (target) => {
    const normalized = normalizeTargetRef(target);
    if (normalized.id) {
        return `${normalized.kind}|id:${normalized.id}`;
    }
    if (normalized.selector) {
        return `${normalized.kind}|selector:${normalized.selector}`;
    }
    if (normalized.classes && normalized.classes.length > 0) {
        return `${normalized.kind}|classes:${normalized.classes.join('.')}`;
    }
    if (normalized.name) {
        return `${normalized.kind}|name:${normalized.name}`;
    }
    return `${normalized.kind}|unknown`;
};
const getCapabilityTarget = (capability) => normalizeTargetRef(capability.target);
const getPatternTarget = (pattern) => normalizeTargetRef(pattern.target);
/**
 * List intent categories from the in-memory registry.
 */
export const listIntentCategoriesFromRegistry = (phases) => {
    const allowedPhases = normalizePhaseFilter(phases);
    return structuredClone(intentCategories)
        .map(withCategoryPhase)
        .filter((category) => isAllowedPhase(category.phase ?? DEFAULT_PHASE, allowedPhases));
};
/**
 * List intent definitions from the in-memory registry.
 */
export const listIntentsFromRegistry = (category, phases) => {
    const allowedPhases = normalizePhaseFilter(phases);
    const categoriesById = new Map(structuredClone(intentCategories)
        .map(withCategoryPhase)
        .map((entry) => [normalize(entry.id), entry]));
    const filteredIntents = structuredClone(intents)
        .map(withIntentPhase)
        .filter((intent) => {
        const intentPhase = intent.phase ?? DEFAULT_PHASE;
        if (!isAllowedPhase(intentPhase, allowedPhases)) {
            return false;
        }
        const categoryEntry = categoriesById.get(normalize(intent.category));
        const categoryPhase = categoryEntry?.phase ?? DEFAULT_PHASE;
        return isAllowedPhase(categoryPhase, allowedPhases);
    });
    if (!category) {
        return filteredIntents;
    }
    const normalizedCategory = normalize(category);
    return filteredIntents.filter((intent) => normalize(intent.category) === normalizedCategory);
};
/**
 * Return a single intent definition by ID if present and phase-compatible.
 */
export const getIntentFromRegistry = (intentId, phases) => {
    const allowedPhases = normalizePhaseFilter(phases);
    const categoriesById = new Map(structuredClone(intentCategories)
        .map(withCategoryPhase)
        .map((entry) => [normalize(entry.id), entry]));
    const normalizedIntent = normalizeIntentId(intentId);
    const intent = structuredClone(intents)
        .map(withIntentPhase)
        .find((candidate) => normalize(candidate.id) === normalizedIntent);
    if (!intent) {
        return null;
    }
    const intentPhase = intent.phase ?? DEFAULT_PHASE;
    if (!isAllowedPhase(intentPhase, allowedPhases)) {
        return null;
    }
    const categoryEntry = categoriesById.get(normalize(intent.category));
    const categoryPhase = categoryEntry?.phase ?? DEFAULT_PHASE;
    if (!isAllowedPhase(categoryPhase, allowedPhases)) {
        return null;
    }
    return intent;
};
/**
 * Return the capability declaration for a normalized target reference.
 */
export const getTargetCapabilityFromRegistry = (target, phases) => {
    const allowedPhases = normalizePhaseFilter(phases);
    const normalizedTargetKey = targetKey(target);
    const capability = structuredClone(targetCapabilities)
        .map(withCapabilityPhase)
        .find((candidate) => (targetKey(getCapabilityTarget(candidate)) === normalizedTargetKey
        && isAllowedPhase(candidate.phase ?? DEFAULT_PHASE, allowedPhases)));
    return capability ?? null;
};
/**
 * Resolve one target + intent pair to the matching usage pattern.
 */
export const resolveUsagePatternFromRegistry = (target, intentId, phases) => {
    const allowedPhases = normalizePhaseFilter(phases);
    const normalizedTargetKey = targetKey(target);
    const normalizedIntent = normalizeIntentId(intentId);
    const pattern = structuredClone(usagePatterns)
        .map(withPatternPhase)
        .find((candidate) => (targetKey(getPatternTarget(candidate)) === normalizedTargetKey
        && normalize(candidate.intent) === normalizedIntent
        && isAllowedPhase(candidate.phase ?? DEFAULT_PHASE, allowedPhases)));
    return pattern ?? null;
};
/**
 * Check whether a target is eligible to resolve a given intent.
 */
export const canTargetResolveIntent = (target, intentId, phases) => {
    const capability = getTargetCapabilityFromRegistry(target, phases);
    const intent = getIntentFromRegistry(intentId, phases);
    if (!capability || !intent) {
        return false;
    }
    return capability.categories.map(normalize).includes(normalize(intent.category));
};
/**
 * List all capabilities that support the category of a given intent.
 */
export const listCapabilitiesForIntentFromRegistry = (intentId, phases) => {
    const intent = getIntentFromRegistry(intentId, phases);
    if (!intent) {
        return [];
    }
    const allowedPhases = normalizePhaseFilter(phases);
    const normalizedCategory = normalize(intent.category);
    return structuredClone(targetCapabilities)
        .map(withCapabilityPhase)
        .filter((capability) => isAllowedPhase(capability.phase ?? DEFAULT_PHASE, allowedPhases)
        && capability.categories.map(normalize).includes(normalizedCategory));
};
/**
 * Resolve a target + intent pair to a full intent-resolution payload.
 */
export const resolveIntentFromRegistry = (target, intentId, phases) => {
    if (!canTargetResolveIntent(target, intentId, phases)) {
        return null;
    }
    const pattern = resolveUsagePatternFromRegistry(target, intentId, phases);
    if (!pattern) {
        return null;
    }
    return {
        architecture: INTENT_POLICY_LAYER_NAME,
        output: INTENT_OUTPUT_NAME,
        pattern,
        process: INTENT_RESOLUTION_PROCESS_NAME,
    };
};
