import * as Common from "../../core/common/common.js";
import * as Host from "../../core/host/host.js";
import * as i18n from "../../core/i18n/i18n.js";
import * as Root from "../../core/root/root.js";
import { formatCSSChangesFromDiff } from "../../panels/utils/utils.js";
import * as Diff from "../../third_party/diff/diff.js";
import * as DiffView from "../../ui/components/diff_view/diff_view.js";
import * as UI from "../../ui/legacy/legacy.js";
import changesViewStyles from "./changesView.css.js";
import * as WorkspaceDiff from "../../models/workspace_diff/workspace_diff.js";
import { ChangesSidebar, Events } from "./ChangesSidebar.js";
const UIStrings = {
  revertAllChangesToCurrentFile: "Revert all changes to current file",
  copyAllChangesFromCurrentFile: "Copy all changes from current file",
  noChanges: "No changes",
  binaryData: "Binary data",
  sInsertions: "{n, plural, =1 {# insertion (+)} other {# insertions (+)}}",
  sDeletions: "{n, plural, =1 {# deletion (-)} other {# deletions (-)}}",
  copy: "Copy"
};
const str_ = i18n.i18n.registerUIStrings("panels/changes/ChangesView.ts", UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(void 0, str_);
function diffStats(diff) {
  const insertions = diff.reduce((ins, token) => ins + (token[0] === Diff.Diff.Operation.Insert ? token[1].length : 0), 0);
  const deletions = diff.reduce((ins, token) => ins + (token[0] === Diff.Diff.Operation.Delete ? token[1].length : 0), 0);
  const deletionText = i18nString(UIStrings.sDeletions, { n: deletions });
  const insertionText = i18nString(UIStrings.sInsertions, { n: insertions });
  return `${insertionText}, ${deletionText}`;
}
let changesViewInstance;
export class ChangesView extends UI.Widget.VBox {
  emptyWidget;
  workspaceDiff;
  changesSidebar;
  selectedUISourceCode;
  diffContainer;
  toolbar;
  diffStats;
  diffView;
  copyButton;
  copyButtonSeparator;
  constructor() {
    super(true);
    const splitWidget = new UI.SplitWidget.SplitWidget(true, false);
    const mainWidget = new UI.Widget.Widget();
    splitWidget.setMainWidget(mainWidget);
    splitWidget.show(this.contentElement);
    this.emptyWidget = new UI.EmptyWidget.EmptyWidget("");
    this.emptyWidget.show(mainWidget.element);
    this.workspaceDiff = WorkspaceDiff.WorkspaceDiff.workspaceDiff();
    this.changesSidebar = new ChangesSidebar(this.workspaceDiff);
    this.changesSidebar.addEventListener(Events.SelectedUISourceCodeChanged, this.selectedUISourceCodeChanged, this);
    splitWidget.setSidebarWidget(this.changesSidebar);
    this.selectedUISourceCode = null;
    this.diffContainer = mainWidget.element.createChild("div", "diff-container");
    UI.ARIAUtils.markAsTabpanel(this.diffContainer);
    this.diffContainer.addEventListener("click", (event) => this.click(event));
    this.diffView = this.diffContainer.appendChild(new DiffView.DiffView.DiffView());
    this.toolbar = new UI.Toolbar.Toolbar("changes-toolbar", mainWidget.element);
    const revertButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.revertAllChangesToCurrentFile), "largeicon-undo");
    revertButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this.revert.bind(this));
    this.toolbar.appendToolbarItem(revertButton);
    this.diffStats = new UI.Toolbar.ToolbarText("");
    this.toolbar.appendToolbarItem(this.diffStats);
    this.copyButton = new UI.Toolbar.ToolbarButton(i18nString(UIStrings.copyAllChangesFromCurrentFile), "largeicon-copy", UIStrings.copy);
    this.copyButton.addEventListener(UI.Toolbar.ToolbarButton.Events.Click, this.copyChanges.bind(this));
    this.copyButtonSeparator = new UI.Toolbar.ToolbarSeparator();
    this.toolbar.setEnabled(false);
    this.hideDiff(i18nString(UIStrings.noChanges));
    this.selectedUISourceCodeChanged();
  }
  static instance(opts = { forceNew: null }) {
    const { forceNew } = opts;
    if (!changesViewInstance || forceNew) {
      changesViewInstance = new ChangesView();
    }
    return changesViewInstance;
  }
  selectedUISourceCodeChanged() {
    this.revealUISourceCode(this.changesSidebar.selectedUISourceCode());
    if (this.selectedUISourceCode?.contentType() === Common.ResourceType.resourceTypes.Stylesheet) {
      this.toolbar.appendToolbarItem(this.copyButtonSeparator);
      this.toolbar.appendToolbarItem(this.copyButton);
    } else {
      this.toolbar.removeToolbarItem(this.copyButtonSeparator);
      this.toolbar.removeToolbarItem(this.copyButton);
    }
  }
  revert() {
    const uiSourceCode = this.selectedUISourceCode;
    if (!uiSourceCode) {
      return;
    }
    void this.workspaceDiff.revertToOriginal(uiSourceCode);
  }
  async copyChanges() {
    const uiSourceCode = this.selectedUISourceCode;
    if (!uiSourceCode) {
      return;
    }
    const diffResponse = await this.workspaceDiff.requestDiff(uiSourceCode, { shouldFormatDiff: true });
    if (!diffResponse || diffResponse?.diff.length < 2) {
      return;
    }
    const changes = await formatCSSChangesFromDiff(diffResponse.diff);
    Host.InspectorFrontendHost.InspectorFrontendHostInstance.copyText(changes);
  }
  click(event) {
    if (!this.selectedUISourceCode) {
      return;
    }
    for (let target = event.target; target; target = target.parentElement) {
      if (target.classList.contains("diff-line-content")) {
        const number = target.getAttribute("data-line-number");
        if (number) {
          void Common.Revealer.reveal(this.selectedUISourceCode.uiLocation(Number(number) - 1, 0), false);
          event.consume(true);
        }
        break;
      } else if (target.classList.contains("diff-listing")) {
        break;
      }
    }
  }
  revealUISourceCode(uiSourceCode) {
    if (this.selectedUISourceCode === uiSourceCode) {
      return;
    }
    if (this.selectedUISourceCode) {
      this.workspaceDiff.unsubscribeFromDiffChange(this.selectedUISourceCode, this.refreshDiff, this);
    }
    if (uiSourceCode && this.isShowing()) {
      this.workspaceDiff.subscribeToDiffChange(uiSourceCode, this.refreshDiff, this);
    }
    this.selectedUISourceCode = uiSourceCode;
    void this.refreshDiff();
  }
  wasShown() {
    void this.refreshDiff();
    this.registerCSSFiles([changesViewStyles]);
  }
  async refreshDiff() {
    if (!this.isShowing()) {
      return;
    }
    if (!this.selectedUISourceCode) {
      this.renderDiffRows();
      return;
    }
    const uiSourceCode = this.selectedUISourceCode;
    if (!uiSourceCode.contentType().isTextType()) {
      this.hideDiff(i18nString(UIStrings.binaryData));
      return;
    }
    const diffResponse = await this.workspaceDiff.requestDiff(uiSourceCode, { shouldFormatDiff: Root.Runtime.experiments.isEnabled("preciseChanges") });
    if (this.selectedUISourceCode !== uiSourceCode) {
      return;
    }
    this.renderDiffRows(diffResponse?.diff);
  }
  hideDiff(message) {
    this.diffStats.setText("");
    this.toolbar.setEnabled(false);
    this.diffContainer.style.display = "none";
    this.emptyWidget.text = message;
    this.emptyWidget.showWidget();
  }
  renderDiffRows(diff) {
    if (!diff || diff.length === 1 && diff[0][0] === Diff.Diff.Operation.Equal) {
      this.hideDiff(i18nString(UIStrings.noChanges));
    } else {
      this.diffStats.setText(diffStats(diff));
      this.toolbar.setEnabled(true);
      this.emptyWidget.hideWidget();
      const mimeType = this.selectedUISourceCode.mimeType();
      this.diffContainer.style.display = "block";
      this.diffView.data = { diff, mimeType };
    }
  }
}
let diffUILocationRevealerInstance;
export class DiffUILocationRevealer {
  static instance(opts = { forceNew: false }) {
    const { forceNew } = opts;
    if (!diffUILocationRevealerInstance || forceNew) {
      diffUILocationRevealerInstance = new DiffUILocationRevealer();
    }
    return diffUILocationRevealerInstance;
  }
  async reveal(diffUILocation, omitFocus) {
    if (!(diffUILocation instanceof WorkspaceDiff.WorkspaceDiff.DiffUILocation)) {
      throw new Error("Internal error: not a diff ui location");
    }
    await UI.ViewManager.ViewManager.instance().showView("changes.changes");
    ChangesView.instance().changesSidebar.selectUISourceCode(diffUILocation.uiSourceCode, omitFocus);
  }
}
//# sourceMappingURL=ChangesView.js.map
