import { BUILTIN_PROFILES, DEFAULT_BUILTIN_PROFILE_ID } from "./builtins.js";
import { mergeDimensions, validateBehaviorProfile } from "./validate.js";
export class BehaviorProfileStore {
    state;
    constructor(initial) {
        this.state = initial;
    }
    getState() {
        return this.state;
    }
    listIds() {
        const out = [];
        for (const [id, p] of Object.entries(BUILTIN_PROFILES)) {
            out.push({ id, label: p.label, kind: "builtin" });
        }
        for (const [id, p] of Object.entries(this.state.customProfiles)) {
            out.push({ id, label: p.label, kind: "custom" });
        }
        return out.sort((a, b) => a.id.localeCompare(b.id));
    }
    getRawProfile(id) {
        if (BUILTIN_PROFILES[id]) {
            return { ...BUILTIN_PROFILES[id], dimensions: { ...BUILTIN_PROFILES[id].dimensions } };
        }
        const c = this.state.customProfiles[id];
        if (!c)
            return null;
        return {
            ...c,
            dimensions: { ...c.dimensions },
            metadata: c.metadata ? { ...c.metadata } : undefined
        };
    }
    /** Resolve `extends` chain; returns null if missing or cycle (cycle truncated). */
    resolveProfile(id, stack = new Set()) {
        if (stack.has(id)) {
            return null;
        }
        stack.add(id);
        const raw = this.getRawProfile(id);
        if (!raw) {
            stack.delete(id);
            return null;
        }
        if (!raw.extends) {
            stack.delete(id);
            return raw;
        }
        const base = this.resolveProfile(raw.extends, stack);
        stack.delete(id);
        if (!base) {
            return raw;
        }
        return {
            ...base,
            ...raw,
            id: raw.id,
            label: raw.label,
            summary: raw.summary,
            dimensions: mergeDimensions(base.dimensions, raw.dimensions),
            interactionNotes: raw.interactionNotes ?? base.interactionNotes,
            extends: raw.extends,
            metadata: raw.metadata ?? base.metadata
        };
    }
    getActiveProfileId() {
        return this.state.activeProfileId;
    }
    setActiveProfileId(id) {
        this.state.activeProfileId = id;
    }
    putCustomProfile(profile) {
        this.state.customProfiles[profile.id] = profile;
    }
    deleteCustomProfile(id) {
        delete this.state.customProfiles[id];
    }
    resolveEffectiveWithProvenance() {
        const provenance = [
            { source: "default", profileId: DEFAULT_BUILTIN_PROFILE_ID }
        ];
        let chosen = DEFAULT_BUILTIN_PROFILE_ID;
        const active = this.state.activeProfileId;
        if (active) {
            const resolved = this.resolveProfile(active);
            if (resolved) {
                chosen = active;
                provenance.push({ source: "active", profileId: active });
                return { effective: resolved, provenance };
            }
            provenance.push({ source: "fallback", profileId: DEFAULT_BUILTIN_PROFILE_ID });
        }
        const fallback = this.resolveProfile(DEFAULT_BUILTIN_PROFILE_ID);
        return {
            effective: fallback ?? BUILTIN_PROFILES[DEFAULT_BUILTIN_PROFILE_ID],
            provenance
        };
    }
}
export function materializeCustomFromBase(baseId, store, newId, overrides) {
    const baseResolved = store.resolveProfile(baseId);
    if (!baseResolved) {
        return { ok: false, message: `Base profile '${baseId}' not found` };
    }
    const label = overrides.label?.trim() || `${baseResolved.label} (custom)`;
    const summary = overrides.summary?.trim() || baseResolved.summary;
    const dimensions = mergeDimensions(baseResolved.dimensions, overrides.dimensions);
    const draft = {
        schemaVersion: 1,
        id: newId,
        extends: baseId,
        label,
        summary,
        dimensions,
        interactionNotes: overrides.interactionNotes?.trim(),
        metadata: { source: "fork", createdAt: new Date().toISOString(), baseProfileId: baseId }
    };
    return validateBehaviorProfile(draft);
}
