/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import '../../../styles/shared-styles';
import '../gr-button/gr-button';
import '../gr-icon/gr-icon';
import '../../plugins/gr-endpoint-decorator/gr-endpoint-decorator';
import '../../plugins/gr-endpoint-param/gr-endpoint-param';
import '../../plugins/gr-endpoint-slot/gr-endpoint-slot';
import {subscribe} from '../../lit/subscription-controller';
import {changeModelToken} from '../../../models/change/change-model';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {fire, fireAlert} from '../../../utils/event-util';
import {getAppContext} from '../../../services/app-context';
import {debounce, DelayedTask} from '../../../utils/async-util';
import {assertIsDefined, queryAndAssert} from '../../../utils/common-util';
import {IronAutogrowTextareaElement} from '@polymer/iron-autogrow-textarea/iron-autogrow-textarea';
import {Interaction} from '../../../constants/reporting';
import {LitElement, html} from 'lit';
import {customElement, property, state} from 'lit/decorators.js';
import {sharedStyles} from '../../../styles/shared-styles';
import {css} from 'lit';
import {PropertyValues} from 'lit';
import {
  BindValueChangeEvent,
  EditableContentSaveEvent,
  ValueChangedEvent,
} from '../../../types/events';
import {
  EmailInfo,
  GitPersonInfo,
  NumericChangeId,
  RepoName,
  RevisionPatchSetNum,
} from '../../../types/common';
import {nothing} from 'lit';
import {classMap} from 'lit/directives/class-map.js';
import {when} from 'lit/directives/when.js';
import {fontStyles} from '../../../styles/gr-font-styles';
import {storageServiceToken} from '../../../services/storage/gr-storage_impl';
import {resolve} from '../../../models/dependency';
import {formStyles} from '../../../styles/form-styles';
import {changeViewModelToken} from '../../../models/views/change';
import {SpecialFilePath} from '../../../constants/constants';
import {
  detectFormattingErrorsInString,
  formatCommitMessageString,
  FormattingError,
} from '../../../utils/commit-message-formatter-util';

const RESTORED_MESSAGE = 'Content restored from a previous edit.';
const STORAGE_DEBOUNCE_INTERVAL_MS = 400;

declare global {
  interface HTMLElementTagNameMap {
    'gr-editable-content': GrEditableContent;
  }
  interface HTMLElementEventMap {
    'content-changed': ValueChangedEvent<string>;
    'editing-changed': ValueChangedEvent<boolean>;
    /** Fired when the 'cancel' button is pressed. */
    'editable-content-cancel': CustomEvent<{}>;
    /** Fired when the 'save' button is pressed. */
    'editable-content-save': EditableContentSaveEvent;
  }
}

@customElement('gr-editable-content')
export class GrEditableContent extends LitElement {
  /**
   * Fired when content is restored from storage.
   *
   * @event show-alert
   */

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

  @property({type: Boolean, reflect: true})
  disabled = false;

  @property({
    type: Boolean,
    reflect: true,
  })
  editing = false;

  @property({type: Boolean, attribute: 'remove-zero-width-space'})
  removeZeroWidthSpace?: boolean;

  // If no storage key is provided, content is not stored.
  @property({type: String, attribute: 'storage-key'})
  storageKey?: string;

  @property({type: Boolean, attribute: 'commit-collapsible'})
  commitCollapsible = true;

  @property({type: Boolean, attribute: 'hide-edit-commit-message'})
  hideEditCommitMessage?: boolean;

  /** If false, then the "Show more" button was used to expand. */
  @state() commitCollapsed = true;

  @state() newContent = '';

  @state()
  emails: EmailInfo[] = [];

  @state()
  committerEmail?: string;

  @state()
  latestCommitter?: GitPersonInfo;

  @state() editMode = false;

  @state() repoName?: RepoName;

  @state() changeNum?: NumericChangeId;

  @state() patchNum?: RevisionPatchSetNum;

  private readonly restApiService = getAppContext().restApiService;

  private readonly getChangeModel = resolve(this, changeModelToken);

  private readonly getStorage = resolve(this, storageServiceToken);

  private readonly reporting = getAppContext().reportingService;

  private readonly getNavigation = resolve(this, navigationToken);

  private readonly getViewModel = resolve(this, changeViewModelToken);

  // Tests use this so needs to be non private
  storeTask?: DelayedTask;

  private formatCheckTask?: DelayedTask;

  @state() private formatDisabled = true;

  @state() private formattedErrors: FormattingError[] = [];

  // Used to undo formatting
  @state() private lastFormattedContent?: string;

  constructor() {
    super();
    subscribe(
      this,
      () => this.getChangeModel().latestCommitter$,
      x => (this.latestCommitter = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().editMode$,
      editMode => (this.editMode = editMode)
    );
    subscribe(
      this,
      () => this.getChangeModel().repo$,
      x => (this.repoName = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().changeNum$,
      x => (this.changeNum = x)
    );
    subscribe(
      this,
      () => this.getChangeModel().patchNum$,
      x => (this.patchNum = x)
    );
  }

  override disconnectedCallback() {
    this.storeTask?.flush();
    super.disconnectedCallback();
  }

  override willUpdate(changedProperties: PropertyValues) {
    if (changedProperties.has('editing')) this.editingChanged();
    if (changedProperties.has('newContent')) {
      this.updateFormatState();
      this.updateStorageWithNewContent();
      if (
        this.lastFormattedContent &&
        this.newContent !== formatCommitMessageString(this.lastFormattedContent)
      ) {
        this.lastFormattedContent = undefined;
      }
    }
    if (changedProperties.has('content')) this.contentChanged();
  }

  static override get styles() {
    return [
      sharedStyles,
      formStyles,
      fontStyles,
      css`
        :host {
          display: block;
        }
        :host([disabled]) iron-autogrow-textarea {
          opacity: 0.5;
        }
        .viewer {
          background-color: var(--view-background-color);
          border: 1px solid var(--view-background-color);
          border-radius: var(--border-radius);
          box-shadow: var(--elevation-level-1);
          padding: var(--spacing-m);
        }
        :host(.collapsed) .viewer,
        .viewer.collapsed {
          max-height: var(--collapsed-max-height, 300px);
          overflow: hidden;
        }
        .editor iron-autogrow-textarea,
        .viewer {
          min-height: 100px;
        }
        .editor iron-autogrow-textarea {
          background-color: var(--view-background-color);
          width: 100%;
          display: block;
          --iron-autogrow-textarea_-_padding: var(--spacing-m);
        }
        .editButtons {
          display: flex;
          justify-content: space-between;
          align-items: center;
        }
        .show-all-container {
          background-color: var(--view-background-color);
          display: flex;
          border: 1px solid transparent;
          border-top-color: var(--border-color);
          border-radius: 0 0 4px 4px;
          box-shadow: var(--elevation-level-1);
          /* slightly up to cover rounded corner of the commit msg */
          margin-top: calc(-1 * var(--spacing-xs));
          /* To make this bar pop over editor, since editor has relative position.
          */
          position: relative;
        }
        :host([editing]) .show-all-container {
          box-shadow: none;
          border: 1px solid var(--border-color);
          justify-content: space-between;
        }
        :host(:not([editing])) .show-all-container {
          justify-content: flex-end;
        }
        div:only-child {
          align-self: flex-end;
          margin-left: auto;
        }
        .flex-space {
          flex-grow: 1;
        }
        .show-all-container gr-icon {
          color: inherit;
        }
        .email-dropdown {
          margin-left: var(--spacing-s);
          align-self: center;
        }
        .cancel-button {
          margin-right: var(--spacing-l);
        }
        .save-button {
          margin-right: var(--spacing-xs);
        }
        gr-button {
          padding: var(--spacing-xs);
        }
        .format-button {
          margin-right: var(--spacing-l);
        }
        gr-icon.warning {
          color: var(--warning-foreground);
        }
      `,
    ];
  }

  override render() {
    return html`
      <gr-endpoint-decorator name="commit-message">
        <gr-endpoint-param
          name="editing"
          .value=${this.editing}
        ></gr-endpoint-param>
        ${this.renderViewer()} ${this.renderEditor()} ${this.renderButtons()}
        <gr-endpoint-slot name="above-actions"></gr-endpoint-slot>
      </gr-endpoint-decorator>
    `;
  }

  private renderViewer() {
    if (this.editing) return;
    return html`
      <div
        class=${classMap({
          viewer: true,
          collapsed: this.commitCollapsed && this.commitCollapsible,
        })}
      >
        <slot></slot>
      </div>
    `;
  }

  private renderEditor() {
    if (!this.editing) return;
    return html`
      <div class="editor">
        <div>
          <iron-autogrow-textarea
            autocomplete="on"
            .bindValue=${this.newContent}
            ?disabled=${this.disabled}
            @bind-value-changed=${(e: BindValueChangeEvent) => {
              this.newContent = e.detail.value ?? '';
            }}
          ></iron-autogrow-textarea>
        </div>
      </div>
    `;
  }

  private renderButtons() {
    if (!this.editing && !this.commitCollapsible && this.hideEditCommitMessage)
      return nothing;

    return html`
      <div class="show-all-container font-normal">
        ${when(
          this.commitCollapsible && !this.editing,
          () => html`
            <gr-button
              link
              class="show-all-button"
              @click=${this.toggleCommitCollapsed}
            >
              <div>
                ${when(
                  !this.commitCollapsed,
                  () => html`<gr-icon icon="expand_less" small></gr-icon>`
                )}
                ${when(
                  this.commitCollapsed,
                  () => html`<gr-icon icon="expand_more" small></gr-icon>`
                )}
                <span>${this.commitCollapsed ? 'Show all' : 'Show less'}</span>
              </div>
            </gr-button>
            <div class="flex-space"></div>
          `
        )}
        ${when(
          !this.hideEditCommitMessage,
          () => html`
            <gr-button
              link
              class="edit-commit-message"
              title="Edit commit message"
              @click=${this.handleEditCommitMessage}
              ><div>
                <gr-icon icon="edit" filled small></gr-icon>
                <span>Edit</span>
              </div></gr-button
            >
          `
        )}
        ${when(
          this.editing,
          () => html` ${when(
              this.canShowEmailDropdown(),
              () => html` <div class="email-dropdown" id="editMessageEmailDropdown">Committer Email
            <gr-dropdown-list
                .items=${this.getEmailDropdownItems()}
                .value=${this.committerEmail}
                @value-change=${this.setCommitterEmail}
            >
            </gr-dropdown-list>
            <span></div>`
            )}
            <div class="editButtons">
              ${when(
                this.formattedErrors.length > 0,
                () => html`<gr-tooltip-content
                  .title=${this.formattedErrors
                    .map(e => `${e.line ? `Line ${e.line}: ` : ''}${e.message}`)
                    .join('\n')}
                  ><gr-icon class="warning" icon="warning" filled></gr-icon
                ></gr-tooltip-content>`
              )}
              <gr-button
                link
                class="format-button"
                @click=${this.handleFormat}
                ?disabled=${this.formatDisabled}
                .title=${this.computeFormatButtonTooltip(
                  this.formatDisabled,
                  this.formattedErrors,
                  !!this.lastFormattedContent
                )}
                >${this.lastFormattedContent ? 'Undo' : 'Format'}</gr-button
              >
              <gr-button
                link
                class="cancel-button"
                @click=${this.handleCancel}
                ?disabled=${this.disabled}
                >Cancel</gr-button
              >
              <gr-button
                class="save-button"
                primary=""
                @click=${this.handleSave}
                ?disabled=${this.computeSaveDisabled()}
                >Save</gr-button
              >
            </div>`
        )}
        </div>
      </div>
    `;
  }

  contentChanged() {
    /* A changed content means that either a different change has been loaded
     * or new content was saved. Either way, let's reset the component.
     */
    this.editing = false;
    this.newContent = '';
    fire(this, 'content-changed', {
      value: this.content ?? '',
    });
  }

  focusTextarea() {
    queryAndAssert<IronAutogrowTextareaElement>(
      this,
      'iron-autogrow-textarea'
    ).textarea.focus();
  }

  private updateFormatState() {
    if (!this.newContent) return;

    // Run immediately first time
    if (!this.formatCheckTask) {
      this.formatDisabled =
        formatCommitMessageString(this.newContent) === this.newContent;
      this.formattedErrors = detectFormattingErrorsInString(this.newContent);
    }

    // Then debounce subsequent calls
    this.formatCheckTask = debounce(
      this.formatCheckTask,
      () => {
        this.formatDisabled =
          formatCommitMessageString(this.newContent) === this.newContent;
        this.formattedErrors = detectFormattingErrorsInString(this.newContent);
      },
      3000
    );
  }

  updateStorageWithNewContent() {
    if (!this.storageKey) return;
    const storageKey = this.storageKey;

    this.storeTask = debounce(
      this.storeTask,
      () => {
        if (this.newContent.length) {
          this.getStorage().setEditableContentItem(storageKey, this.newContent);
        } else {
          // This does not really happen, because we don't clear newContent
          // after saving (see below). So this only occurs when the user clears
          // all the content in the editable textarea. But GrStorage cleans
          // up itself after one day, so we are not so concerned about leaving
          // some garbage behind.
          this.getStorage().eraseEditableContentItem(storageKey);
        }
      },
      STORAGE_DEBOUNCE_INTERVAL_MS
    );
  }

  editingChanged() {
    // This method is for initializing newContent when you start editing.
    // Restoring content from local storage is not perfect and has
    // some issues:
    //
    // 1. When you start editing in multiple tabs, then we are vulnerable to
    // race conditions between the tabs.
    // 2. The stored content is keyed by revision, so when you upload a new
    // patchset and click "reload" and then click "cancel" on the content-
    // editable, then you won't be able to recover the content anymore.
    //
    // Because of these issues we believe that it is better to only recover
    // content from local storage when you enter editing mode for the first
    // time. Otherwise it is better to just keep the last editing state from
    // the same session.
    fire(this, 'editing-changed', {
      value: this.editing,
    });

    if (!this.editing || this.newContent) return;

    let content;
    if (this.storageKey) {
      const storedContent = this.getStorage().getEditableContentItem(
        this.storageKey
      );
      if (storedContent?.message) {
        content = storedContent.message;
        fireAlert(this, RESTORED_MESSAGE);
      }
    }
    if (!content) {
      content = this.content || '';
    }

    // TODO(wyatta) switch linkify sequence, see issue 5526.
    this.newContent = this.removeZeroWidthSpace
      ? content.replace(/^R=\u200B/gm, 'R=')
      : content;
  }

  computeSaveDisabled(): boolean {
    return (
      this.disabled || !this.newContent || this.content === this.newContent
    );
  }

  handleSave(e: Event) {
    e.preventDefault();
    fire(this, 'editable-content-save', {
      content: this.newContent,
      committerEmail: this.committerEmail ? this.committerEmail : null,
    });
    // It would be nice, if we would set this.newContent = undefined here,
    // but we can only do that when we are sure that the save operation has
    // succeeded.
  }

  handleCancel(e: Event) {
    e.preventDefault();
    this.editing = false;
    fire(this, 'editable-content-cancel', {});
  }

  toggleCommitCollapsed() {
    this.commitCollapsed = !this.commitCollapsed;
    this.reporting.reportInteraction(Interaction.TOGGLE_SHOW_ALL_BUTTON, {
      sectionName: 'Commit message',
      toState: !this.commitCollapsed ? 'Show all' : 'Show less',
    });
    if (this.commitCollapsed) {
      window.scrollTo(0, 0);
    }
  }

  async handleEditCommitMessage() {
    if (this.editMode) {
      assertIsDefined(this.changeNum, 'changeNum');
      assertIsDefined(this.repoName, 'repoName');
      assertIsDefined(this.patchNum, 'patchNum');
      this.getNavigation().setUrl(
        this.getViewModel().editUrl({
          editView: {path: SpecialFilePath.COMMIT_MESSAGE},
          patchNum: this.patchNum,
        })
      );

      return;
    }
    await this.loadEmails();
    this.editing = true;
    await this.updateComplete;
    this.focusTextarea();
  }

  async loadEmails() {
    const accountEmails: EmailInfo[] =
      (await this.restApiService.getAccountEmails()) ?? [];
    let selectedEmail: string | undefined;
    accountEmails.forEach(e => {
      if (e.preferred) {
        selectedEmail = e.email;
      }
    });

    if (accountEmails.some(e => e.email === this.latestCommitter?.email)) {
      selectedEmail = this.latestCommitter?.email;
    }
    this.emails = accountEmails;
    this.committerEmail = selectedEmail;
  }

  private canShowEmailDropdown() {
    return this.emails.length > 1;
  }

  private getEmailDropdownItems() {
    return this.emails.map(e => {
      return {
        text: e.email,
        value: e.email,
      };
    });
  }

  /**
   * Called when the user clicks the "Format" button. Instead of setting
   * `this.newContent` directly, we use `document.execCommand('insertText')`
   * on the native <textarea> to push the change onto the native undo stack.
   */
  handleFormat(e: Event) {
    e.preventDefault();

    const textarea = queryAndAssert<IronAutogrowTextareaElement>(
      this,
      'iron-autogrow-textarea'
    ).textarea;

    // If we have lastFormattedContent, we're undoing
    if (this.lastFormattedContent) {
      textarea.focus();
      textarea.setSelectionRange(0, textarea.value.length);
      document.execCommand('insertText', false, this.lastFormattedContent);
      this.newContent = this.lastFormattedContent;
      this.lastFormattedContent = undefined;
      return;
    }

    // Otherwise we're formatting
    const oldValue = textarea.value;
    const newValue = formatCommitMessageString(oldValue);
    if (oldValue === newValue) return;

    const {selectionStart, selectionEnd} = textarea;

    textarea.focus();
    textarea.setSelectionRange(0, oldValue.length);

    this.lastFormattedContent = oldValue;
    document.execCommand('insertText', false, newValue);
    this.newContent = textarea.value;

    // Restore the cursor position
    const newSelectionStart = Math.min(selectionStart, newValue.length);
    const newSelectionEnd = Math.min(selectionEnd, newValue.length);
    textarea.setSelectionRange(newSelectionStart, newSelectionEnd);
  }

  private setCommitterEmail(e: CustomEvent<{value: string}>) {
    this.committerEmail = e.detail.value;
  }

  private computeFormatButtonTooltip(
    formatDisabled: boolean,
    formattedErrors: FormattingError[],
    isUndo: boolean
  ): string {
    if (isUndo) {
      return 'Undo formatting changes';
    }
    if (!formatDisabled) {
      return (
        'Automatically fixes formatting by trimming trailing spaces, ' +
        'wrapping paragraphs at 72 characters, and condensing blank lines. '
      );
    }
    // If disabled but there are formatting errors, the button can't fix them all
    if (formattedErrors.length > 0) {
      return (
        'Format button cannot fix all issues (like subject or footer length). ' +
        'Some must be fixed manually.'
      );
    }
    return 'No format changes needed.';
  }
}
