/**
 * @license
 * Copyright 2022 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {LitElement, css, html} from 'lit';
import {customElement, property, query} from 'lit/decorators.js';
import {EditorView} from '@codemirror/view';
import {EditorState} from '@codemirror/state';
import {updateRulerWidth} from './ruler';
import {extensions} from './extensions';

type ValueChangedEvent<T = string> = CustomEvent<{value: T}>;

declare global {
  interface HTMLElementEventMap {
    'content-change': ValueChangedEvent;
  }
  interface HTMLElementTagNameMap {
    // @ts-ignore TS2717: Subsequent property declarations must have the same
    // type.
    'codemirror-element': CodeMirrorElement;
  }
}

/**
 * This is a standard REST API object:
 * https://gerrit-review.googlesource.com/Documentation/rest-api-accounts.html#edit-preferences-info
 *
 * TODO: Add this object to the plugin API.
 */
export interface EditPreferencesInfo {
  tab_size?: number;
  line_length?: number;
  indent_unit?: number;
  show_tabs?: boolean;
  show_whitespace_errors?: boolean;
  syntax_highlighting?: boolean;
  match_brackets?: boolean;
  line_wrapping?: boolean;
  indent_with_tabs?: boolean;
  auto_close_brackets?: boolean;
}

@customElement('codemirror-element')
export class CodeMirrorElement extends LitElement {
  @property({type: Number}) lineNum?: number;

  @property({type: String}) fileContent?: string;

  @property({type: String}) fileType?: string;

  @property({type: Object}) prefs?: EditPreferencesInfo;

  @property({type: Boolean}) darkMode = false;

  @query('#wrapper')
  wrapper!: HTMLElement;

  private initialized = false;

  static override get styles() {
    return [
      css`
        .cm-editor {
          font-family: 'Roboto Mono', 'SF Mono', 'Lucida Console', Monaco,
            monospace;
          /* CodeMirror has a default z-index of 4. Set to 0 to avoid collisions with fixed header. */
          z-index: 0;
        }
        .CodeMirror-ruler {
          border-left: 1px solid #ddd;
        }
        .cm-editor .cm-content {
          font-family: 'Roboto Mono', 'SF Mono', 'Lucida Console', Monaco,
            monospace;
        }
      `,
    ];
  }

  override render() {
    return html`<div id="wrapper"></div>`;
  }

  override updated() {
    this.initialize();
  }

  private initialize() {
    if (!this.isConnected || !this.wrapper) return;

    if (this.initialized) return;
    this.initialized = true;

    const offsetTop = this.getBoundingClientRect().top;
    const clientHeight = window.innerHeight ?? document.body.clientHeight;
    // We are setting a fixed height, because for large files we want to
    // benefit from CodeMirror's virtual scrolling.
    // 80px is roughly the size of the bottom margins plus the footer height.
    // This ensures the height of the textarea doesn't push out of screen.
    const height = clientHeight - offsetTop - 80;

    const editor = new EditorView({
      state: EditorState.create({
        doc: this.fileContent ?? '',
        extensions: [
          ...extensions(
            height,
            this.prefs,
            this.fileType,
            this.fileContent ?? '',
            this.darkMode
          ),
          EditorView.updateListener.of(update => {
            // Set ruler width to 72 for commit messages,
            // as this is the recommended line length for git commit messages.
            if (this.fileType?.includes('x-gerrit-commit-message')) {
              updateRulerWidth(72, update.view.defaultCharacterWidth, true);
            } else if (this.prefs?.line_length) {
              // This is required to be in the setTimeout() to ensure the
              // line is set as correctly as possible.
              updateRulerWidth(
                this.prefs.line_length,
                update.view.defaultCharacterWidth,
                true
              );
            }

            if (update.docChanged) {
              this.dispatchEvent(
                new CustomEvent('content-change', {
                  detail: {value: update.state.doc.toString()},
                  bubbles: true,
                  composed: true,
                })
              );
            }
          }),
          EditorView.domEventHandlers({
            keydown(e: KeyboardEvent) {
              // Exempt the ctrl/command+s key from preventing events from propagating
              // through the app. This is because we use it to save changes.
              if (!e.metaKey && !e.ctrlKey) {
                e.stopPropagation();
              }

              // There is an issue where you paste and immediately
              // press ctrl+s/cmd+s after, it would trigger the
              // web browsers file browser rather then gr-editor-view
              // intercepting ctrl+s/cmd+s.
              if ((e.metaKey || e.ctrlKey) && e.key === 'v') {
                e.stopPropagation();
              }
            },
          }),
        ],
      }),
      parent: this.wrapper as Element,
    });

    editor.focus();

    if (this.lineNum) {
      // We have to take away one from the line number,
      // ... because CodeMirror's line count is zero-based.
      editor.dispatch({selection: {anchor: this.lineNum - 1}});
    }
  }
}
