import { Container, Input, Spacer, Text, getEditorKeybindings, matchesKey, truncateToWidth } from '../../../tui/index.js';
import { theme } from '../../theme/runtime.js';
import { DynamicBorder } from '../primitives/dynamic-border.js';
import { cancelKeyHint, rawKeyHint } from '../primitives/keybinding-hints.js';
function getSourceRank(source) {
    switch (source) {
        case 'agents':
            return 0;
        case 'claude':
            return 1;
        case 'codex':
            return 2;
        case 'built-in':
            return 3;
        case 'path':
            return 4;
        case 'project':
            return 5;
        case 'user':
            return 6;
        default:
            return 7;
    }
}
function getSourceLabel(source) {
    switch (source) {
        case 'agents':
            return 'Agents';
        case 'claude':
            return 'Claude';
        case 'codex':
            return 'Codex';
        case 'built-in':
            return 'built-in';
        case 'path':
            return 'path';
        case 'project':
            return 'project';
        case 'user':
            return 'user';
        default:
            return source;
    }
}
class SkillsSelectorHeader {
    invalidate() { }
    render(width) {
        return [
            truncateToWidth(theme.bold('Skill Visibility'), width, ''),
            truncateToWidth(theme.fg('muted', 'Unchecked skills are not revealed to the agent but are still available via explicit prompting /skill:name'), width, '...')
        ];
    }
}
class SkillList {
    searchInput;
    items;
    filteredItems;
    selectedIndex = 0;
    maxVisible = 12;
    _focused = false;
    onCancel;
    onExit;
    onToggle;
    onApply;
    get focused() {
        return this._focused;
    }
    set focused(value) {
        this._focused = value;
        this.searchInput.focused = value;
    }
    constructor(items) {
        this.items = [...items].sort((a, b) => {
            const rank = getSourceRank(a.source) - getSourceRank(b.source);
            if (rank !== 0) {
                return rank;
            }
            return a.name.localeCompare(b.name);
        });
        this.filteredItems = [...this.items];
        this.searchInput = new Input();
        this.selectFirstItem();
    }
    invalidate() { }
    render(width) {
        const lines = [...this.searchInput.render(width), ''];
        if (this.filteredItems.length === 0) {
            lines.push(theme.fg('muted', '  No loaded skills match your search.'));
            return lines;
        }
        const startIndex = Math.max(0, Math.min(this.selectedIndex - Math.floor(this.maxVisible / 2), Math.max(0, this.filteredItems.length - this.maxVisible)));
        const endIndex = Math.min(startIndex + this.maxVisible, this.filteredItems.length);
        for (let i = startIndex; i < endIndex; i++) {
            const item = this.filteredItems[i];
            const isSelected = i === this.selectedIndex;
            const cursor = isSelected ? '> ' : '  ';
            const marker = item.locked
                ? theme.fg('warning', '[m]')
                : item.enabled
                    ? theme.fg('success', '[x]')
                    : theme.fg('dim', '[ ]');
            const name = isSelected ? theme.bold(item.name) : item.name;
            const source = theme.fg('muted', `[${getSourceLabel(item.source)}]`);
            const desc = item.description ? theme.fg('dim', ` - ${item.description}`) : '';
            lines.push(truncateToWidth(`${cursor}${marker} ${source} ${name}${desc}`, width, '...'));
        }
        if (startIndex > 0 || endIndex < this.filteredItems.length) {
            lines.push(theme.fg('dim', `  (${this.selectedIndex + 1}/${this.filteredItems.length})`));
        }
        return lines;
    }
    handleInput(data) {
        const kb = getEditorKeybindings();
        if (kb.matches(data, 'selectUp')) {
            this.selectedIndex = Math.max(0, this.selectedIndex - 1);
            return;
        }
        if (kb.matches(data, 'selectDown')) {
            this.selectedIndex = Math.min(this.filteredItems.length - 1, this.selectedIndex + 1);
            return;
        }
        if (kb.matches(data, 'selectPageUp')) {
            this.selectedIndex = Math.max(0, this.selectedIndex - this.maxVisible);
            return;
        }
        if (kb.matches(data, 'selectPageDown')) {
            this.selectedIndex = Math.min(this.filteredItems.length - 1, this.selectedIndex + this.maxVisible);
            return;
        }
        if (kb.matches(data, 'selectCancel')) {
            this.onCancel?.();
            return;
        }
        if (matchesKey(data, 'ctrl+c')) {
            this.onCancel?.();
            return;
        }
        if (matchesKey(data, 'space')) {
            const item = this.filteredItems[this.selectedIndex];
            if (!item || item.locked)
                return;
            item.enabled = !item.enabled;
            const canonical = this.items.find((candidate) => candidate.name === item.name);
            if (canonical) {
                canonical.enabled = item.enabled;
            }
            this.onToggle?.();
            return;
        }
        if (kb.matches(data, 'selectConfirm')) {
            this.onApply?.(this.items.map((item) => ({ ...item })));
            return;
        }
        this.searchInput.handleInput(data);
        this.filterItems(this.searchInput.getValue());
    }
    filterItems(query) {
        const lowered = query.trim().toLowerCase();
        this.filteredItems = lowered
            ? this.items.filter((item) => item.name.toLowerCase().includes(lowered) ||
                item.description.toLowerCase().includes(lowered) ||
                item.source.toLowerCase().includes(lowered) ||
                item.filePath.toLowerCase().includes(lowered))
            : [...this.items];
        this.selectFirstItem();
    }
    selectFirstItem() {
        this.selectedIndex = this.filteredItems.length > 0 ? 0 : -1;
    }
}
export class SkillsSelectorComponent extends Container {
    skillList;
    hintText;
    _focused = false;
    get focused() {
        return this._focused;
    }
    set focused(value) {
        this._focused = value;
        this.skillList.focused = value;
    }
    constructor(items, onClose, onExit, onToggle, requestRender) {
        super();
        this.addChild(new Spacer(1));
        this.addChild(new DynamicBorder());
        this.addChild(new Spacer(1));
        this.addChild(new SkillsSelectorHeader());
        this.addChild(new Spacer(1));
        this.skillList = new SkillList(items);
        this.skillList.onCancel = onClose;
        this.skillList.onExit = onExit;
        this.skillList.onToggle = () => {
            requestRender();
        };
        this.skillList.onApply = (draftItems) => {
            onToggle(draftItems);
            requestRender();
        };
        this.addChild(this.skillList);
        this.addChild(new Spacer(1));
        this.hintText = new Text(rawKeyHint('↑↓', 'navigate') + '  ' + rawKeyHint('enter', 'select') + '  ' + cancelKeyHint(), 1, 0);
        this.addChild(this.hintText);
        this.addChild(new Spacer(1));
        this.addChild(new DynamicBorder());
    }
    getSkillList() {
        return this.skillList;
    }
}
//# sourceMappingURL=skills-selector.js.map