import { __decorate, __param } from '../../../../../../../external/tslib/tslib.es6.js';
import { addDisposableListener, Dimension } from '../../../../base/browser/dom.js';
import { status } from '../../../../base/browser/ui/aria/aria.js';
import { toDisposable } from '../../../../base/common/lifecycle.js';
import { assertType } from '../../../../base/common/types.js';
import { ZoneWidget } from '../../../../editor/contrib/zoneWidget/browser/zoneWidget.js';
import { localizeWithPath } from '../../../../nls.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.service.js';
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
import { CTX_INLINE_CHAT_OUTER_CURSOR_POSITION, MENU_INLINE_CHAT_WIDGET, MENU_INLINE_CHAT_WIDGET_FEEDBACK, MENU_INLINE_CHAT_WIDGET_STATUS, ACTION_REGENERATE_RESPONSE, ACTION_TOGGLE_DIFF, ACTION_VIEW_IN_CHAT, ACTION_ACCEPT_CHANGES } from '../common/inlineChat.js';
import { EditorBasedInlineChatWidget } from './inlineChatWidget.js';
import { MenuId } from '../../../../platform/actions/common/actions.js';
const _moduleId = "vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget";
let InlineChatZoneWidget = class InlineChatZoneWidget extends ZoneWidget {
    constructor(editor, _instaService, contextKeyService) {
        super(editor, { showFrame: false, showArrow: false, isAccessible: true, className: 'inline-chat-widget', keepEditorSelection: true, showInHiddenAreas: true, ordinal: 10000 });
        this._instaService = _instaService;
        this._ctxCursorPosition = CTX_INLINE_CHAT_OUTER_CURSOR_POSITION.bindTo(contextKeyService);
        this._disposables.add(toDisposable(() => {
            this._ctxCursorPosition.reset();
        }));
        this.widget = this._instaService.createInstance(EditorBasedInlineChatWidget, this.editor, {
            telemetrySource: 'interactiveEditorWidget-toolbar',
            inputMenuId: MenuId.ChatExecute,
            widgetMenuId: MENU_INLINE_CHAT_WIDGET,
            feedbackMenuId: MENU_INLINE_CHAT_WIDGET_FEEDBACK,
            statusMenuId: {
                menu: MENU_INLINE_CHAT_WIDGET_STATUS,
                options: {
                    buttonConfigProvider: action => {
                        if (action.id === ACTION_REGENERATE_RESPONSE || action.id === ACTION_TOGGLE_DIFF) {
                            return { showIcon: true, showLabel: false, isSecondary: true };
                        }
                        else if (action.id === ACTION_VIEW_IN_CHAT || action.id === ACTION_ACCEPT_CHANGES) {
                            return { isSecondary: false };
                        }
                        else {
                            return { isSecondary: true };
                        }
                    }
                }
            }
        });
        this._disposables.add(this.widget.onDidChangeHeight(() => {
            if (this.position) {
                this._relayout(this._computeHeightInLines());
            }
        }));
        this._disposables.add(this.widget);
        this.create();
        this._disposables.add(addDisposableListener(this.domNode, 'click', e => {
            if (!this.widget.hasFocus()) {
                this.widget.focus();
            }
        }, true));
        const updateCursorIsAboveContextKey = () => {
            if (!this.position || !this.editor.hasModel()) {
                this._ctxCursorPosition.reset();
            }
            else if (this.position.lineNumber === this.editor.getPosition().lineNumber) {
                this._ctxCursorPosition.set('above');
            }
            else if (this.position.lineNumber + 1 === this.editor.getPosition().lineNumber) {
                this._ctxCursorPosition.set('below');
            }
            else {
                this._ctxCursorPosition.reset();
            }
        };
        this._disposables.add(this.editor.onDidChangeCursorPosition(e => updateCursorIsAboveContextKey()));
        this._disposables.add(this.editor.onDidFocusEditorText(e => updateCursorIsAboveContextKey()));
        updateCursorIsAboveContextKey();
    }
    _fillContainer(container) {
        container.appendChild(this.widget.domNode);
    }
    _doLayout(heightInPixel) {
        const maxWidth = !this.widget.showsAnyPreview() ? 640 : Number.MAX_SAFE_INTEGER;
        const width = Math.min(maxWidth, this._availableSpaceGivenIndentation(this._indentationWidth));
        this._dimension = ( (new Dimension(width, heightInPixel)));
        this.widget.layout(this._dimension);
    }
    _availableSpaceGivenIndentation(indentationWidth) {
        const info = this.editor.getLayoutInfo();
        return info.contentWidth - (info.glyphMarginWidth + info.decorationsWidth + (indentationWidth ?? 0));
    }
    _computeHeightInLines() {
        const chatContentHeight = this.widget.contentHeight;
        const editorHeight = this.editor.getLayoutInfo().height;
        const contentHeight = Math.min(chatContentHeight, Math.max(this.widget.minHeight, editorHeight * 0.42));
        const heightInLines = contentHeight / this.editor.getOption(67 );
        return heightInLines;
    }
    _onWidth(_widthInPixel) {
        if (this._dimension) {
            this._doLayout(this._dimension.height);
        }
    }
    show(position) {
        assertType(this.container);
        const info = this.editor.getLayoutInfo();
        const marginWithoutIndentation = info.glyphMarginWidth + info.decorationsWidth + info.lineNumbersWidth;
        this.container.style.marginLeft = `${marginWithoutIndentation}px`;
        super.show(position, this._computeHeightInLines());
        this._setWidgetMargins(position);
        this.widget.focus();
    }
    updatePositionAndHeight(position) {
        super.updatePositionAndHeight(position, this._computeHeightInLines());
        this._setWidgetMargins(position);
    }
    _getWidth(info) {
        return info.width - info.minimap.minimapWidth;
    }
    updateBackgroundColor(newPosition, wholeRange) {
        assertType(this.container);
        const widgetLineNumber = newPosition.lineNumber;
        this.container.classList.toggle('inside-selection', widgetLineNumber > wholeRange.startLineNumber && widgetLineNumber < wholeRange.endLineNumber);
    }
    _calculateIndentationWidth(position) {
        const viewModel = this.editor._getViewModel();
        if (!viewModel) {
            return 0;
        }
        const visibleRange = viewModel.getCompletelyVisibleViewRange();
        if (!visibleRange.containsPosition(position)) {
            return 0;
        }
        let indentationLevel = viewModel.getLineFirstNonWhitespaceColumn(position.lineNumber);
        let indentationLineNumber = position.lineNumber;
        for (let lineNumber = position.lineNumber; lineNumber >= visibleRange.startLineNumber; lineNumber--) {
            const currentIndentationLevel = viewModel.getLineFirstNonWhitespaceColumn(lineNumber);
            if (currentIndentationLevel !== 0) {
                indentationLineNumber = lineNumber;
                indentationLevel = currentIndentationLevel;
                break;
            }
        }
        return Math.max(0, this.editor.getOffsetForColumn(indentationLineNumber, indentationLevel));
    }
    _setWidgetMargins(position) {
        const indentationWidth = this._calculateIndentationWidth(position);
        if (this._indentationWidth === indentationWidth) {
            return;
        }
        this._indentationWidth = this._availableSpaceGivenIndentation(indentationWidth) > 400 ? indentationWidth : 0;
        this.widget.domNode.style.marginLeft = `${this._indentationWidth}px`;
        this.widget.domNode.style.marginRight = `${this.editor.getLayoutInfo().minimap.minimapWidth}px`;
    }
    hide() {
        this.container.classList.remove('inside-selection');
        this._ctxCursorPosition.reset();
        this.widget.reset();
        super.hide();
        status(( localizeWithPath(_moduleId, 0, 'Closed inline chat widget')));
    }
};
InlineChatZoneWidget = ( (__decorate([
    ( (__param(1, IInstantiationService))),
    ( (__param(2, IContextKeyService)))
], InlineChatZoneWidget)));
export { InlineChatZoneWidget };
