import { __decorate } from "tslib";
import { attr, customElement, GenesisElement, html, observable, volatile, } from '@genesislcap/web-core';
import { AGENT_PICKER_AUTO_VALUE } from './agent-picker.constants';
import { styles } from './agent-picker.styles';
import { AgentPickerTemplate } from './agent-picker.template';
export { AGENT_PICKER_AUTO_VALUE };
/** Tolerance for `scrollWidth > clientWidth` overflow detection (sub-pixel rounding). */
const OVERFLOW_TOLERANCE_PX = 1;
/**
 * User-facing agent picker rendered above the chat input.
 *
 * Renders `Auto` plus each top-level agent that has `manualSelection.enabled`.
 * Sub-agents and non-selectable specialists are excluded. Hidden when fewer
 * than two agents are configured or none are manually selectable.
 *
 * @fires agent-pinned - Fired when the user changes selection with the
 *   agent name or `null` for Auto. detail: `string | null`
 *
 * @beta
 */
let AgentPicker = class AgentPicker extends GenesisElement {
    constructor() {
        super(...arguments);
        /** Design-system tag prefix, e.g. `'rapid'` for `rapid-segmented-control`. */
        this.designSystemPrefix = 'rapid';
        /** Picker variant, sourced from the assistant's `chatConfig.agentPicker`. */
        this.mode = 'disabled';
        /** Top-level agents passed to the assistant. */
        this.agents = [];
        /** Currently pinned agent name, or `null` for Auto. */
        this.pinnedAgentName = null;
        /**
         * @internal — true when the segmented row's content overflows its container.
         * Drives the fallback to `select` rendering. Only meaningful when
         * `mode === 'segmented-control'`.
         */
        this.overflowing = false;
    }
    /** Top-level agents that opted in to manual selection. */
    get selectableAgents() {
        var _a;
        return ((_a = this.agents) !== null && _a !== void 0 ? _a : []).filter((a) => { var _a; return (_a = a.manualSelection) === null || _a === void 0 ? void 0 : _a.enabled; });
    }
    /** Whether the picker should render at all. */
    get visible() {
        var _a, _b;
        if (this.mode === 'disabled')
            return false;
        if (((_b = (_a = this.agents) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) <= 1)
            return false;
        if (this.selectableAgents.length === 0)
            return false;
        return true;
    }
    /**
     * The variant actually rendered: `'select'` if user-configured or if the
     * segmented row currently overflows; `'segmented-control'` otherwise.
     */
    get effectiveMode() {
        if (this.mode === 'segmented-control') {
            return this.overflowing ? 'select' : 'segmented-control';
        }
        return 'select';
    }
    connectedCallback() {
        super.connectedCallback();
        if (typeof ResizeObserver === 'undefined')
            return;
        this.resizeObserver = new ResizeObserver(() => this.measureOverflow());
        this.resizeObserver.observe(this);
    }
    disconnectedCallback() {
        var _a;
        super.disconnectedCallback();
        (_a = this.resizeObserver) === null || _a === void 0 ? void 0 : _a.disconnect();
        this.resizeObserver = undefined;
    }
    /**
     * Re-measure when agents change — newly added selectable agents may push the
     * segmented row past the container's width.
     */
    agentsChanged() {
        queueMicrotask(() => this.measureOverflow());
    }
    modeChanged() {
        queueMicrotask(() => this.measureOverflow());
    }
    /**
     * Measures whether the segmented row's natural content width exceeds the
     * container's visible width. Bails when the row isn't currently rendered
     * (e.g. when `mode !== 'segmented-control'`).
     */
    measureOverflow() {
        const row = this.segmentedRowEl;
        if (!row) {
            this.overflowing = false;
            return;
        }
        this.overflowing = row.scrollWidth > row.clientWidth + OVERFLOW_TOLERANCE_PX;
    }
    selectAgent(name) {
        this.pinnedAgentName = name;
        // Always emit — the host may close a slide-out panel on click even when
        // the selection didn't change.
        this.$emit('agent-pinned', name);
    }
    /**
     * Maps a value from the segmented-control or select (which uses
     * {@link AGENT_PICKER_AUTO_VALUE} for Auto) back to the `string | null` form
     * expected by `selectAgent`.
     */
    selectByValue(value) {
        this.selectAgent(value === AGENT_PICKER_AUTO_VALUE ? null : value);
    }
    /** Current pinned agent name as a value the segmented-control / select can bind to. */
    get currentValue() {
        var _a;
        return (_a = this.pinnedAgentName) !== null && _a !== void 0 ? _a : AGENT_PICKER_AUTO_VALUE;
    }
};
__decorate([
    attr({ attribute: 'design-system-prefix' })
], AgentPicker.prototype, "designSystemPrefix", void 0);
__decorate([
    observable
], AgentPicker.prototype, "mode", void 0);
__decorate([
    observable
], AgentPicker.prototype, "agents", void 0);
__decorate([
    observable
], AgentPicker.prototype, "pinnedAgentName", void 0);
__decorate([
    observable
], AgentPicker.prototype, "overflowing", void 0);
__decorate([
    volatile
], AgentPicker.prototype, "selectableAgents", null);
__decorate([
    volatile
], AgentPicker.prototype, "visible", null);
__decorate([
    volatile
], AgentPicker.prototype, "effectiveMode", null);
__decorate([
    volatile
], AgentPicker.prototype, "currentValue", null);
AgentPicker = __decorate([
    customElement({
        name: 'foundation-ai-agent-picker',
        template: html `
    ${(x) => AgentPickerTemplate(x.designSystemPrefix)}
  `,
        styles,
    })
], AgentPicker);
export { AgentPicker };
