import { __decorate, __param } from '../../../../../../../../external/tslib/tslib.es6.js';
import { $ as $$1 } from '../../../../../base/browser/dom.js';
import { Button } from '../../../../../base/browser/ui/button/button.js';
import { Codicon } from '../../../../../base/common/codicons.js';
import { Emitter } from '../../../../../base/common/event.js';
import { Disposable, DisposableStore } from '../../../../../base/common/lifecycle.js';
import { matchesSomeScheme, Schemas } from '../../../../../base/common/network.js';
import { basename } from '../../../../../base/common/path.js';
import { basenameOrAuthority } from '../../../../../base/common/resources.js';
import { ThemeIcon } from '../../../../../base/common/themables.js';
import { URI } from '../../../../../base/common/uri.js';
import { localizeWithPath } from '../../../../../nls.js';
import { FileKind } from '../../../../../platform/files/common/files.js';
import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js';
import { WorkbenchList } from '../../../../../platform/list/browser/listService.js';
import { IOpenerService } from '../../../../../platform/opener/common/opener.service.js';
import { IThemeService } from '../../../../../platform/theme/common/themeService.service.js';
import { ResourceLabels } from '../../../../browser/labels.js';
import { ColorScheme } from '../../../../browser/web.api.js';
import { ResourcePool } from './chatCollections.js';
import { IChatVariablesService } from '../../common/chatVariables.service.js';
import { createFileIconThemableTreeContainerScope } from '../../../files/browser/views/explorerView.js';
var ContentReferencesListRenderer_1;
const _moduleId = "vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart";
const $ = $$1;
let ChatReferencesContentPart = class ChatReferencesContentPart extends Disposable {
    constructor(data, labelOverride, element, contentReferencesListPool, openerService) {
        super();
        this.data = data;
        this._onDidChangeHeight = this._register(( (new Emitter())));
        this.onDidChangeHeight = this._onDidChangeHeight.event;
        const referencesLabel = labelOverride ?? (data.length > 1 ?
            ( localizeWithPath(_moduleId, 0, "Used {0} references", data.length)) :
            ( localizeWithPath(_moduleId, 1, "Used {0} reference", 1)));
        const iconElement = $('.chat-used-context-icon');
        const icon = (element) => element.usedReferencesExpanded ? Codicon.chevronDown : Codicon.chevronRight;
        iconElement.classList.add(...ThemeIcon.asClassNameArray(icon(element)));
        const buttonElement = $('.chat-used-context-label', undefined);
        const collapseButton = this._register(( (new Button(buttonElement, {
            buttonBackground: undefined,
            buttonBorder: undefined,
            buttonForeground: undefined,
            buttonHoverBackground: undefined,
            buttonSecondaryBackground: undefined,
            buttonSecondaryForeground: undefined,
            buttonSecondaryHoverBackground: undefined,
            buttonSeparator: undefined
        }))));
        this.domNode = $('.chat-used-context', undefined, buttonElement);
        collapseButton.label = referencesLabel;
        collapseButton.element.prepend(iconElement);
        this.updateAriaLabel(collapseButton.element, referencesLabel, element.usedReferencesExpanded);
        this.domNode.classList.toggle('chat-used-context-collapsed', !element.usedReferencesExpanded);
        this._register(collapseButton.onDidClick(() => {
            iconElement.classList.remove(...ThemeIcon.asClassNameArray(icon(element)));
            element.usedReferencesExpanded = !element.usedReferencesExpanded;
            iconElement.classList.add(...ThemeIcon.asClassNameArray(icon(element)));
            this.domNode.classList.toggle('chat-used-context-collapsed', !element.usedReferencesExpanded);
            this._onDidChangeHeight.fire();
            this.updateAriaLabel(collapseButton.element, referencesLabel, element.usedReferencesExpanded);
        }));
        const ref = this._register(contentReferencesListPool.get());
        const list = ref.object;
        this.domNode.appendChild(list.getHTMLElement().parentElement);
        this._register(list.onDidOpen((e) => {
            if (e.element && 'reference' in e.element) {
                const uriOrLocation = 'variableName' in e.element.reference ? e.element.reference.value : e.element.reference;
                const uri = URI.isUri(uriOrLocation) ? uriOrLocation :
                    uriOrLocation?.uri;
                if (uri) {
                    openerService.open(uri, {
                        fromUserGesture: true,
                        editorOptions: {
                            ...e.editorOptions,
                            ...{
                                selection: uriOrLocation && 'range' in uriOrLocation ? uriOrLocation.range : undefined
                            }
                        }
                    });
                }
            }
        }));
        this._register(list.onContextMenu((e) => {
            e.browserEvent.preventDefault();
            e.browserEvent.stopPropagation();
        }));
        const maxItemsShown = 6;
        const itemsShown = Math.min(data.length, maxItemsShown);
        const height = itemsShown * 22;
        list.layout(height);
        list.getHTMLElement().style.height = `${height}px`;
        list.splice(0, list.length, data);
    }
    hasSameContent(other, followingContent, element) {
        return other.kind === 'references' && other.references.length === this.data.length;
    }
    updateAriaLabel(element, label, expanded) {
        element.ariaLabel = expanded ? ( localizeWithPath(_moduleId, 2, "{0}, expanded", label)) : ( localizeWithPath(_moduleId, 3, "{0}, collapsed", label));
    }
    addDisposable(disposable) {
        this._register(disposable);
    }
};
ChatReferencesContentPart = ( (__decorate([
    ( (__param(4, IOpenerService)))
], ChatReferencesContentPart)));
let ContentReferencesListPool = class ContentReferencesListPool extends Disposable {
    get inUse() {
        return this._pool.inUse;
    }
    constructor(_onDidChangeVisibility, instantiationService, themeService) {
        super();
        this._onDidChangeVisibility = _onDidChangeVisibility;
        this.instantiationService = instantiationService;
        this.themeService = themeService;
        this._pool = this._register(( (new ResourcePool(() => this.listFactory()))));
    }
    listFactory() {
        const resourceLabels = this._register(this.instantiationService.createInstance(ResourceLabels, { onDidChangeVisibility: this._onDidChangeVisibility }));
        const container = $('.chat-used-context-list');
        this._register(createFileIconThemableTreeContainerScope(container, this.themeService));
        const list = this.instantiationService.createInstance((WorkbenchList), 'ChatListRenderer', container, ( (new ContentReferencesListDelegate())), [this.instantiationService.createInstance(ContentReferencesListRenderer, resourceLabels)], {
            alwaysConsumeMouseWheel: false,
            accessibilityProvider: {
                getAriaLabel: (element) => {
                    if (element.kind === 'warning') {
                        return element.content.value;
                    }
                    const reference = element.reference;
                    if ('variableName' in reference) {
                        return reference.variableName;
                    }
                    else if (URI.isUri(reference)) {
                        return basename(reference.path);
                    }
                    else {
                        return basename(reference.uri.path);
                    }
                },
                getWidgetAriaLabel: () => ( localizeWithPath(_moduleId, 4, "Used References"))
            },
            dnd: {
                getDragURI: (element) => {
                    if (element.kind === 'warning') {
                        return null;
                    }
                    const { reference } = element;
                    if ('variableName' in reference) {
                        return null;
                    }
                    else if (URI.isUri(reference)) {
                        return (
                             (reference.toString())
                        );
                    }
                    else {
                        return (
                             (reference.uri.toString())
                        );
                    }
                },
                dispose: () => { },
                onDragOver: () => false,
                drop: () => { },
            },
        });
        return list;
    }
    get() {
        const object = this._pool.get();
        let stale = false;
        return {
            object,
            isStale: () => stale,
            dispose: () => {
                stale = true;
                this._pool.release(object);
            }
        };
    }
};
ContentReferencesListPool = ( (__decorate([
    ( (__param(1, IInstantiationService))),
    ( (__param(2, IThemeService)))
], ContentReferencesListPool)));
class ContentReferencesListDelegate {
    getHeight(element) {
        return 22;
    }
    getTemplateId(element) {
        return ContentReferencesListRenderer.TEMPLATE_ID;
    }
}
let ContentReferencesListRenderer = class ContentReferencesListRenderer {
    static { ContentReferencesListRenderer_1 = this; }
    static { this.TEMPLATE_ID = 'contentReferencesListRenderer'; }
    constructor(labels, themeService, chatVariablesService) {
        this.labels = labels;
        this.themeService = themeService;
        this.chatVariablesService = chatVariablesService;
        this.templateId = ContentReferencesListRenderer_1.TEMPLATE_ID;
    }
    renderTemplate(container) {
        const templateDisposables = ( (new DisposableStore()));
        const label = templateDisposables.add(this.labels.create(container, { supportHighlights: true }));
        return { templateDisposables, label };
    }
    getReferenceIcon(data) {
        if (ThemeIcon.isThemeIcon(data.iconPath)) {
            return data.iconPath;
        }
        else {
            return this.themeService.getColorTheme().type === ColorScheme.DARK && data.iconPath?.dark
                ? data.iconPath?.dark
                : data.iconPath?.light;
        }
    }
    renderElement(data, index, templateData, height) {
        if (data.kind === 'warning') {
            templateData.label.setResource({ name: data.content.value }, { icon: Codicon.warning });
            return;
        }
        const reference = data.reference;
        const icon = this.getReferenceIcon(data);
        templateData.label.element.style.display = 'flex';
        if ('variableName' in reference) {
            if (reference.value) {
                const uri = URI.isUri(reference.value) ? reference.value : reference.value.uri;
                templateData.label.setResource({
                    resource: uri,
                    name: basenameOrAuthority(uri),
                    description: `#${reference.variableName}`,
                    range: 'range' in reference.value ? reference.value.range : undefined,
                }, { icon });
            }
            else {
                const variable = this.chatVariablesService.getVariable(reference.variableName);
                templateData.label.setLabel(`#${reference.variableName}`, undefined, { title: variable?.description });
            }
        }
        else {
            const uri = 'uri' in reference ? reference.uri : reference;
            if (matchesSomeScheme(uri, Schemas.mailto, Schemas.http, Schemas.https)) {
                templateData.label.setResource({ resource: uri, name: ( (uri.toString())) }, { icon: icon ?? Codicon.globe });
            }
            else {
                templateData.label.setFile(uri, {
                    fileKind: FileKind.FILE,
                    fileDecorations: { badges: false, colors: false },
                    range: 'range' in reference ? reference.range : undefined
                });
            }
        }
    }
    disposeTemplate(templateData) {
        templateData.templateDisposables.dispose();
    }
};
ContentReferencesListRenderer = ContentReferencesListRenderer_1 = ( (__decorate([
    ( (__param(1, IThemeService))),
    ( (__param(2, IChatVariablesService)))
], ContentReferencesListRenderer)));
export { ChatReferencesContentPart, ContentReferencesListPool };
