// Copyright 2017 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

import '../../ui/kit/kit.js';
import '../../ui/components/highlighting/highlighting.js';

import * as i18n from '../../core/i18n/i18n.js';
import type * as Workspace from '../../models/workspace/workspace.js';
import * as QuickOpen from '../../ui/legacy/components/quick_open/quick_open.js';
import {html, type TemplateResult} from '../../ui/lit/lit.js';

import {evaluateScriptSnippet, findSnippetsProject} from './ScriptSnippetFileSystem.js';

const UIStrings = {
  /**
   * @description Text in Snippets Quick Open of the Sources panel when opening snippets
   */
  noSnippetsFound: 'No snippets found.',
  /**
   * @description Text for command prefix of run a code snippet
   */
  run: 'Run',
  /**
   * @description Text for suggestion of run a code snippet
   */
  snippet: 'Snippet',
  /**
   * @description Text for help title of run code snippet menu
   */
  runSnippet: 'Run snippet',
} as const;
const str_ = i18n.i18n.registerUIStrings('panels/snippets/SnippetsQuickOpen.ts', UIStrings);
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
const i18nLazyString = i18n.i18n.getLazilyComputedLocalizedString.bind(undefined, str_);

let snippetsQuickOpenInstance: SnippetsQuickOpen;

export class SnippetsQuickOpen extends QuickOpen.FilteredListWidget.Provider {
  private snippets: Workspace.UISourceCode.UISourceCode[] = [];

  static instance(opts: {forceNew: boolean|null} = {forceNew: null}): SnippetsQuickOpen {
    const {forceNew} = opts;
    if (!snippetsQuickOpenInstance || forceNew) {
      snippetsQuickOpenInstance = new SnippetsQuickOpen();
    }

    return snippetsQuickOpenInstance;
  }

  override selectItem(itemIndex: number|null, _promptValue: string): void {
    if (itemIndex === null) {
      return;
    }
    void evaluateScriptSnippet(this.snippets[itemIndex]);
  }

  override notFoundText(_query: string): string {
    return i18nString(UIStrings.noSnippetsFound);
  }

  override attach(): void {
    this.snippets = [...findSnippetsProject().uiSourceCodes()];
  }

  override detach(): void {
    this.snippets = [];
  }

  override itemScoreAt(itemIndex: number, query: string): number {
    // Prefer short matches over long matches
    return query.length / this.snippets[itemIndex].name().length;
  }

  override itemCount(): number {
    return this.snippets.length;
  }

  override itemKeyAt(itemIndex: number): string {
    return this.snippets[itemIndex].name();
  }

  override renderItem(itemIndex: number, query: string): TemplateResult {
    // clang-format off
    const snippet = this.snippets[itemIndex].name();
    const highlightRanges = QuickOpen.FilteredListWidget.FilteredListWidget.getHighlightRanges(snippet, query, true);
    return html`
      <devtools-icon class="snippet" name="snippet"></devtools-icon>
      <div>
        <devtools-highlight type="markup" ranges=${highlightRanges}>
          ${snippet}
        </devtools-highlight>
      </div>`;
    // clang-format on
  }
}

QuickOpen.FilteredListWidget.registerProvider({
  prefix: '!',
  iconName: 'exclamation',
  provider: () => Promise.resolve(SnippetsQuickOpen.instance()),
  helpTitle: i18nLazyString(UIStrings.runSnippet),
  titlePrefix: i18nLazyString(UIStrings.run),
  titleSuggestion: i18nLazyString(UIStrings.snippet),
  jslogContext: 'snippet',
});
