import { append, $ } from "../../../../base/browser/dom.mjs";
import { MarkdownString } from "../../../../base/common/htmlContent.mjs";
import { DisposableStore } from "../../../../base/common/lifecycle.mjs";
import { MarkdownRenderer } from "../../markdownRenderer/browser/markdownRenderer.mjs";
import { Range } from "../../../common/core/range.mjs";
import { ILanguageService } from "../../../common/languages/language.mjs";
import { HoverForeignElementAnchor } from "../../hover/browser/hoverTypes.mjs";
import { GhostTextController, ShowNextInlineSuggestionAction, ShowPreviousInlineSuggestionAction, commitInlineSuggestionAction } from "./ghostTextController.mjs";
import { localize } from "../../../../nls.mjs";
import { IAccessibilityService } from "../../../../platform/accessibility/common/accessibility.mjs";
import { IMenuService, MenuId, MenuItemAction } from "../../../../platform/actions/common/actions.mjs";
import { ICommandService } from "../../../../platform/commands/common/commands.mjs";
import { IContextKeyService } from "../../../../platform/contextkey/common/contextkey.mjs";
import { IOpenerService } from "../../../../platform/opener/common/opener.mjs";
var __decorate = globalThis && globalThis.__decorate || function(decorators, target, key, desc) {
  var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
    r = Reflect.decorate(decorators, target, key, desc);
  else
    for (var i = decorators.length - 1; i >= 0; i--)
      if (d = decorators[i])
        r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
  return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __param = globalThis && globalThis.__param || function(paramIndex, decorator) {
  return function(target, key) {
    decorator(target, key, paramIndex);
  };
};
class InlineCompletionsHover {
  constructor(owner, range, controller) {
    this.owner = owner;
    this.range = range;
    this.controller = controller;
  }
  isValidForHoverAnchor(anchor) {
    return anchor.type === 1 && this.range.startColumn <= anchor.range.startColumn && this.range.endColumn >= anchor.range.endColumn;
  }
  hasMultipleSuggestions() {
    return this.controller.hasMultipleInlineCompletions();
  }
}
let InlineCompletionsHoverParticipant = class InlineCompletionsHoverParticipant2 {
  constructor(_editor, _commandService, _menuService, _contextKeyService, _languageService, _openerService, accessibilityService) {
    this._editor = _editor;
    this._commandService = _commandService;
    this._menuService = _menuService;
    this._contextKeyService = _contextKeyService;
    this._languageService = _languageService;
    this._openerService = _openerService;
    this.accessibilityService = accessibilityService;
    this.hoverOrdinal = 3;
  }
  suggestHoverAnchor(mouseEvent) {
    const controller = GhostTextController.get(this._editor);
    if (!controller) {
      return null;
    }
    const target = mouseEvent.target;
    if (target.type === 8) {
      const viewZoneData = target.detail;
      if (controller.shouldShowHoverAtViewZone(viewZoneData.viewZoneId)) {
        return new HoverForeignElementAnchor(1e3, this, Range.fromPositions(viewZoneData.positionBefore || viewZoneData.position, viewZoneData.positionBefore || viewZoneData.position));
      }
    }
    if (target.type === 7) {
      if (controller.shouldShowHoverAt(target.range)) {
        return new HoverForeignElementAnchor(1e3, this, target.range);
      }
    }
    if (target.type === 6) {
      const mightBeForeignElement = target.detail.mightBeForeignElement;
      if (mightBeForeignElement && controller.shouldShowHoverAt(target.range)) {
        return new HoverForeignElementAnchor(1e3, this, target.range);
      }
    }
    return null;
  }
  computeSync(anchor, lineDecorations) {
    const controller = GhostTextController.get(this._editor);
    if (controller && controller.shouldShowHoverAt(anchor.range)) {
      return [new InlineCompletionsHover(this, anchor.range, controller)];
    }
    return [];
  }
  renderHoverParts(context, hoverParts) {
    const disposableStore = new DisposableStore();
    const part = hoverParts[0];
    if (this.accessibilityService.isScreenReaderOptimized()) {
      this.renderScreenReaderText(context, part, disposableStore);
    }
    const menu = disposableStore.add(this._menuService.createMenu(MenuId.InlineCompletionsActions, this._contextKeyService));
    const previousAction = context.statusBar.addAction({
      label: localize("showNextInlineSuggestion", "Next"),
      commandId: ShowNextInlineSuggestionAction.ID,
      run: () => this._commandService.executeCommand(ShowNextInlineSuggestionAction.ID)
    });
    const nextAction = context.statusBar.addAction({
      label: localize("showPreviousInlineSuggestion", "Previous"),
      commandId: ShowPreviousInlineSuggestionAction.ID,
      run: () => this._commandService.executeCommand(ShowPreviousInlineSuggestionAction.ID)
    });
    context.statusBar.addAction({
      label: localize("acceptInlineSuggestion", "Accept"),
      commandId: commitInlineSuggestionAction.id,
      run: () => this._commandService.executeCommand(commitInlineSuggestionAction.id)
    });
    const actions = [previousAction, nextAction];
    for (const action of actions) {
      action.setEnabled(false);
    }
    part.hasMultipleSuggestions().then((hasMore) => {
      for (const action of actions) {
        action.setEnabled(hasMore);
      }
    });
    for (const [_, group] of menu.getActions()) {
      for (const action of group) {
        if (action instanceof MenuItemAction) {
          context.statusBar.addAction({
            label: action.label,
            commandId: action.item.id,
            run: () => this._commandService.executeCommand(action.item.id)
          });
        }
      }
    }
    return disposableStore;
  }
  renderScreenReaderText(context, part, disposableStore) {
    var _a, _b;
    const $$1 = $;
    const markdownHoverElement = $$1("div.hover-row.markdown-hover");
    const hoverContentsElement = append(markdownHoverElement, $$1("div.hover-contents"));
    const renderer = disposableStore.add(new MarkdownRenderer({ editor: this._editor }, this._languageService, this._openerService));
    const render = (code) => {
      disposableStore.add(renderer.onDidRenderAsync(() => {
        hoverContentsElement.className = "hover-contents code-hover-contents";
        context.onContentsChanged();
      }));
      const inlineSuggestionAvailable = localize("inlineSuggestionFollows", "Suggestion:");
      const renderedContents = disposableStore.add(renderer.render(new MarkdownString().appendText(inlineSuggestionAvailable).appendCodeblock("text", code)));
      hoverContentsElement.replaceChildren(renderedContents.element);
    };
    const ghostText = (_b = (_a = part.controller.activeModel) === null || _a === void 0 ? void 0 : _a.inlineCompletionsModel) === null || _b === void 0 ? void 0 : _b.ghostText;
    if (ghostText) {
      const lineText = this._editor.getModel().getLineContent(ghostText.lineNumber);
      render(ghostText.renderForScreenReader(lineText));
    }
    context.fragment.appendChild(markdownHoverElement);
  }
};
InlineCompletionsHoverParticipant = __decorate([
  __param(1, ICommandService),
  __param(2, IMenuService),
  __param(3, IContextKeyService),
  __param(4, ILanguageService),
  __param(5, IOpenerService),
  __param(6, IAccessibilityService)
], InlineCompletionsHoverParticipant);
export {
  InlineCompletionsHover,
  InlineCompletionsHoverParticipant
};
