/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-dialog/gr-dialog';
import {GrEditAction, GrEditConstants} from '../gr-edit-constants';
import {navigationToken} from '../../core/gr-navigation/gr-navigation';
import {
  ChangeInfo,
  PARENT,
  PatchSetNum,
  RevisionPatchSetNum,
} from '../../../types/common';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {
  AutocompleteQuery,
  GrAutocomplete,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {AutocompleteSuggestion} from '../../../utils/autocomplete-util';
import {getAppContext} from '../../../services/app-context';
import {fireAlert} from '../../../utils/event-util';
import {
  assertIsDefined,
  queryAll,
  query as queryUtil,
} from '../../../utils/common-util';
import {sharedStyles} from '../../../styles/shared-styles';
import {css, html, LitElement} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {BindValueChangeEvent} from '../../../types/events';
import {changeViewModelToken} from '../../../models/views/change';
import {resolve} from '../../../models/dependency';
import {modalStyles} from '../../../styles/gr-modal-styles';
import {whenVisible} from '../../../utils/dom-util';
import {throwingErrorCallback} from '../../shared/gr-rest-api-interface/gr-rest-apis/gr-rest-api-helper';
import {changeModelToken} from '../../../models/change/change-model';
import {formStyles} from '../../../styles/form-styles';
import {spinnerStyles} from '../../../styles/gr-spinner-styles';
import {formatBytes} from '../../../utils/file-util';
import {MdOutlinedTextField} from '@material/web/textfield/outlined-text-field';
import {materialStyles} from '../../../styles/gr-material-styles';

const FILE_UPLOAD_FAILURE = 'File failed to upload.';

@customElement('gr-edit-controls')
export class GrEditControls extends LitElement {
  // private but used in test
  @query('#newPathInput') newPathInput?: MdOutlinedTextField;

  @query('#modal') modal?: HTMLDialogElement;

  // private but used in test
  @query('#openDialog') openDialog?: GrDialog;

  // private but used in test
  @query('#deleteDialog') deleteDialog?: GrDialog;

  // private but used in test
  @query('#renameDialog') renameDialog?: GrDialog;

  // private but used in test
  @query('#restoreDialog') restoreDialog?: GrDialog;

  // private but used in test
  @query('#dragDropArea') dragDropArea?: HTMLDivElement;

  @query('#fileUploadInput') private fileUploadInput?: HTMLInputElement;

  @property({type: Object})
  change?: ChangeInfo;

  @property({type: String})
  patchNum?: PatchSetNum;

  @property({type: Array})
  hiddenActions: string[] = [GrEditConstants.Actions.RESTORE.id];

  // private but used in test
  @state() actions: GrEditAction[] = Object.values(GrEditConstants.Actions);

  // private but used in test
  @state() path = '';

  // private but used in test
  @state() newPath = '';

  @state() private fileName?: string;

  @state() private fileSize?: string;

  @state() fileUploaded?: boolean;

  private readonly query: AutocompleteQuery = (input: string) =>
    this.queryFiles(input);

  private readonly restApiService = getAppContext().restApiService;

  private readonly getChangeModel = resolve(this, changeModelToken);

  private readonly getViewModel = resolve(this, changeViewModelToken);

  private readonly getNavigation = resolve(this, navigationToken);

  static override get styles() {
    return [
      materialStyles,
      formStyles,
      sharedStyles,
      modalStyles,
      spinnerStyles,
      css`
        :host {
          align-items: center;
          display: flex;
          justify-content: flex-end;
        }
        .invisible {
          display: none;
        }
        gr-button {
          margin-left: var(--spacing-l);
          text-decoration: none;
        }
        gr-dialog {
          width: calc(min(50em, 90vw));
        }
        gr-dialog .main {
          width: 100%;
        }
        gr-dialog .main > md-outlined-text-field {
          width: 100%;
        }
        input {
          border: 1px solid var(--border-color);
          border-radius: var(--border-radius);
          margin: var(--spacing-m) 0;
          padding: var(--spacing-s);
          width: 100%;
          box-sizing: border-box;
        }
        #dragDropArea {
          border: 2px dashed var(--border-color);
          border-radius: var(--border-radius);
          margin-top: var(--spacing-l);
          padding: var(--spacing-xxl) var(--spacing-xxl);
          text-align: center;
          cursor: pointer;
        }
        #dragDropArea:hover,
        .hover {
          background-color: var(--hover-background-color);
        }
        #dragDropArea > p {
          font-weight: var(--font-weight-medium);
          padding: var(--spacing-s);
        }
        .loadingSpin {
          width: calc(var(--line-height-normal) - 2px);
          height: calc(var(--line-height-normal) - 2px);
          display: inline-block;
          vertical-align: middle;
        }
        .fileUploadInfo {
          margin-top: var(--spacing-l);
        }
        .disabled {
          pointer-events: none;
          opacity: 0.6;
        }
        md-outlined-text-field {
          margin: var(--spacing-m) 0;
        }
        @media screen and (max-width: 50em) {
          gr-dialog {
            height: 90vh;
          }
        }
      `,
    ];
  }

  override render() {
    return html`
      ${this.actions.map(action => this.renderAction(action))}
      <dialog id="modal" tabindex="-1">
        ${this.renderOpenDialog()} ${this.renderDeleteDialog()}
        ${this.renderRenameDialog()} ${this.renderRestoreDialog()}
      </dialog>
    `;
  }

  private renderAction(action: GrEditAction) {
    return html`
      <gr-button
        id=${action.id}
        class=${this.computeIsInvisible(action.id)}
        link=""
        @click=${this.handleClick}
        >${action.label}</gr-button
      >
    `;
  }

  private renderOpenDialog() {
    return html`
      <gr-dialog
        id="openDialog"
        class="invisible dialog"
        ?disabled=${!this.isValidPath(this.path) || !!this.fileUploaded}
        ?disableCancel=${!!this.fileUploaded}
        confirm-label="Confirm"
        confirm-on-enter=""
        @confirm=${(e: Event) => this.handleOpenConfirm(e)}
        @cancel=${(e: Event) => this.handleDialogCancel(e)}
      >
        <div class="header" slot="header">
          Add a new file or open an existing file
        </div>
        <div class="main" slot="main">
          <gr-autocomplete
            placeholder="Enter an existing or new full file path."
            .query=${this.query}
            .text=${this.path}
            .showBlueFocusBorder=${true}
            @text-changed=${(e: BindValueChangeEvent) =>
              this.handleTextChanged(e)}
          ></gr-autocomplete>
          <!-- We have to call preventDefault for dragenter and dragover
                in order for the drop event to work. -->
          <div
            id="dragDropArea"
            @drop=${(e: DragEvent) => this.handleDragAndDropUpload(e)}
            @click=${() => {
              if (!this.fileUploaded) {
                this.fileUploadInput?.click();
              }
            }}
            @dragenter=${(e: DragEvent) => e.preventDefault()}
            @dragover=${(e: DragEvent) => {
              e.preventDefault();
              if (!this.fileUploaded && this.dragDropArea) {
                this.dragDropArea.classList.add('hover');
              }
            }}
            @dragleave=${() => {
              if (!this.fileUploaded && this.dragDropArea) {
                this.dragDropArea.classList.remove('hover');
              }
            }}
          >
            <p>Drag and drop your file here, or click to select</p>
            <input
              id="fileUploadInput"
              type="file"
              @change=${(e: InputEvent) => this.handleFileUploadChange(e)}
              ?hidden=${true}
            />
          </div>
          ${this.renderLoading()}
        </div>
      </gr-dialog>
    `;
  }

  private renderLoading() {
    if (!this.fileUploaded) return;
    return html`
      <div id="fileUploadInfo" class="fileUploadInfo">
        <span class="loadingSpin"></span>
        <span>Uploading...</span>
        <span>${this.fileName} (${this.fileSize})</span>
      </div>
    `;
  }

  private renderDeleteDialog() {
    return html`
      <gr-dialog
        id="deleteDialog"
        class="invisible dialog"
        ?disabled=${!this.isValidPath(this.path)}
        confirm-label="Delete"
        confirm-on-enter=""
        @confirm=${(e: Event) => this.handleDeleteConfirm(e)}
        @cancel=${(e: Event) => this.handleDialogCancel(e)}
      >
        <div class="header" slot="header">Delete a file from the repo</div>
        <div class="main" slot="main">
          <gr-autocomplete
            placeholder="Enter an existing full file path."
            .query=${this.query}
            .text=${this.path}
            .showBlueFocusBorder=${true}
            @text-changed=${(e: BindValueChangeEvent) =>
              this.handleTextChanged(e)}
          ></gr-autocomplete>
        </div>
      </gr-dialog>
    `;
  }

  private renderRenameDialog() {
    return html`
      <gr-dialog
        id="renameDialog"
        class="invisible dialog"
        ?disabled=${!this.isValidPath(this.path) ||
        !this.isValidPath(this.newPath)}
        confirm-label="Rename"
        confirm-on-enter=""
        @confirm=${(e: Event) => this.handleRenameConfirm(e)}
        @cancel=${(e: Event) => this.handleDialogCancel(e)}
      >
        <div class="header" slot="header">Rename a file in the repo</div>
        <div class="main" slot="main">
          <gr-autocomplete
            placeholder="Enter an existing full file path."
            .query=${this.query}
            .text=${this.path}
            .showBlueFocusBorder=${true}
            @text-changed=${(e: BindValueChangeEvent) =>
              this.handleTextChanged(e)}
          ></gr-autocomplete>
          <md-outlined-text-field
            id="newPathInput"
            class="showBlueFocusBorder"
            placeholder="Enter the new path."
            .value=${this.newPath ?? ''}
            @input=${(e: InputEvent) => {
              const target = e.target as HTMLInputElement;
              this.newPath = target.value;
            }}
          >
          </md-outlined-text-field>
        </div>
      </gr-dialog>
    `;
  }

  private renderRestoreDialog() {
    return html`
      <gr-dialog
        id="restoreDialog"
        class="invisible dialog"
        confirm-label="Restore"
        confirm-on-enter=""
        @confirm=${(e: Event) => this.handleRestoreConfirm(e)}
        @cancel=${(e: Event) => this.handleDialogCancel(e)}
      >
        <div class="header" slot="header">Restore this file?</div>
        <div class="main" slot="main">
          <md-outlined-text-field
            class="showBlueFocusBorder"
            ?readOnly=${true}
            .value=${this.path ?? ''}
            @input=${(e: InputEvent) => {
              const target = e.target as HTMLInputElement;
              this.path = target.value;
            }}
          >
          </md-outlined-text-field>
        </div>
      </gr-dialog>
    `;
  }

  private readonly handleClick = (e: Event) => {
    e.preventDefault();
    const target = e.target as Element;
    const action = target.id;
    switch (action) {
      case GrEditConstants.Actions.OPEN.id:
        this.openOpenDialog();
        return;
      case GrEditConstants.Actions.DELETE.id:
        this.openDeleteDialog();
        return;
      case GrEditConstants.Actions.RENAME.id:
        this.openRenameDialog();
        return;
      case GrEditConstants.Actions.RESTORE.id:
        this.openRestoreDialog();
        return;
    }
  };

  openOpenDialog(path?: string) {
    if (path) {
      this.path = path;
    }
    this.resetUploadStatus();
    assertIsDefined(this.openDialog, 'openDialog');
    this.showDialog(this.openDialog);
  }

  openDeleteDialog(path?: string) {
    if (path) {
      this.path = path;
    }
    assertIsDefined(this.deleteDialog, 'deleteDialog');
    this.showDialog(this.deleteDialog);
  }

  openRenameDialog(path?: string) {
    if (path) {
      this.path = path;
    }
    assertIsDefined(this.renameDialog, 'renameDialog');
    this.showDialog(this.renameDialog);
  }

  openRestoreDialog(path?: string) {
    assertIsDefined(this.restoreDialog, 'restoreDialog');
    if (path) {
      this.path = path;
    }
    this.showDialog(this.restoreDialog);
  }

  /**
   * Given a path string, checks that it is a valid file path.
   *
   * Private but used in test
   */
  isValidPath(path: string) {
    // Double negation needed for strict boolean return type.
    return !!path.length && !path.endsWith('/');
  }

  /**
   * Given a dom event, gets the dialog that lies along this event path.
   *
   * Private but used in test
   */
  getDialogFromEvent(e: Event): GrDialog | undefined {
    return e.composedPath().find(element => {
      if (!(element instanceof Element)) return false;
      if (!element.classList) return false;
      return element.classList.contains('dialog');
    }) as GrDialog | undefined;
  }

  // Private but used in test
  showDialog(dialog: GrDialog) {
    assertIsDefined(this.modal, 'modal');

    // Some dialogs may not fire their on-close event when closed in certain
    // ways (e.g. by clicking outside the dialog body). This call prevents
    // multiple dialogs from being shown in the same modal.
    this.hideAllDialogs();

    this.modal.showModal();
    whenVisible(this.modal, () => {
      dialog.classList.toggle('invisible', false);
      const autocomplete = queryUtil<GrAutocomplete>(dialog, 'gr-autocomplete');
      if (autocomplete) {
        autocomplete.focus();
      }
    });
  }

  // Private but used in test
  hideAllDialogs() {
    const dialogs = queryAll<GrDialog>(this, '.dialog');
    for (const dialog of dialogs) {
      // We set the second param to false, because this function
      // is called by showDialog which when you open either restore,
      // delete or rename dialogs, it reseted the automatically
      // set input.
      this.closeDialog(dialog, false);
    }
  }

  // Private but used in test
  closeDialog(dialog?: GrDialog, clearInputs = true) {
    if (!dialog) return;

    if (clearInputs) {
      // Dialog may have autocompletes and plain inputs -- as these have
      // different properties representing their bound text, it is easier to
      // just make two separate queries.
      dialog.querySelectorAll('gr-autocomplete').forEach(input => {
        input.text = '';
      });

      dialog.querySelectorAll('md-outlined-text-field').forEach(input => {
        input.value = '';
        input.dispatchEvent(new Event('input', {bubbles: true}));
      });
    }

    dialog.classList.toggle('invisible', true);

    assertIsDefined(this.modal, 'modal');
    this.modal.close();
  }

  private handleDialogCancel(e: Event) {
    this.closeDialog(this.getDialogFromEvent(e));
  }

  private handleOpenConfirm(e: Event) {
    if (!this.change || !this.path) {
      fireAlert(this, 'You must enter a path.');
      this.closeDialog(this.openDialog);
      return;
    }
    const patchNum = this.patchNum;
    assertIsDefined(this.patchNum, 'patchset number');
    if (patchNum === PARENT) {
      fireAlert(this, "This doesn't work on Parent");
    }
    const url = this.getViewModel().editUrl({
      editView: {path: this.path},
      // since parent is checked above, it's revision patchset.
      patchNum: patchNum as RevisionPatchSetNum,
    });
    this.getNavigation().setUrl(url);
    this.closeDialog(this.getDialogFromEvent(e));
  }

  // Private but used in test
  handleUploadConfirm(path: string, fileData: string) {
    if (!this.change || !path || !fileData) {
      fireAlert(this, 'You must enter a path and data.');
      this.resetUploadStatus();
      this.closeDialog(this.openDialog);
      return Promise.resolve();
    }
    return this.restApiService
      .saveFileUploadChangeEdit(this.change._number, path, fileData)
      .then(res => {
        if (!res || !res.ok) {
          fireAlert(this, FILE_UPLOAD_FAILURE);
        }
        this.resetUploadStatus();
        this.closeDialog(this.openDialog);
        this.getChangeModel().navigateToChangeResetReload();
      })
      .catch(() => {
        fireAlert(this, FILE_UPLOAD_FAILURE);
        this.resetUploadStatus();
        this.closeDialog(this.openDialog);
      });
  }

  private handleDeleteConfirm(e: Event) {
    // Get the dialog before the api call as the event will change during bubbling
    // which will make Polymer.dom(e).path an empty array in polymer 2
    const dialog = this.getDialogFromEvent(e);
    if (!this.change || !this.path) {
      fireAlert(this, 'You must enter a path.');
      this.closeDialog(dialog);
      return;
    }
    this.restApiService
      .deleteFileInChangeEdit(this.change._number, this.path)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this.closeDialog(dialog);
        this.getChangeModel().navigateToChangeResetReload();
      });
  }

  private handleRestoreConfirm(e: Event) {
    const dialog = this.getDialogFromEvent(e);
    if (!this.change || !this.path) {
      fireAlert(this, 'You must enter a path.');
      this.closeDialog(dialog);
      return;
    }
    this.restApiService
      .restoreFileInChangeEdit(this.change._number, this.path)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this.closeDialog(dialog);
        this.getChangeModel().navigateToChangeResetReload();
      });
  }

  private handleRenameConfirm(e: Event) {
    const dialog = this.getDialogFromEvent(e);
    if (!this.change || !this.path || !this.newPath) {
      fireAlert(this, 'You must enter a old path and a new path.');
      this.closeDialog(dialog);
      return;
    }
    this.restApiService
      .renameFileInChangeEdit(this.change._number, this.path, this.newPath)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this.closeDialog(dialog);
        this.getChangeModel().navigateToChangeResetReload();
      });
  }

  private queryFiles(input: string): Promise<AutocompleteSuggestion[]> {
    assertIsDefined(this.change, 'this.change');
    assertIsDefined(this.patchNum, 'this.patchNum');
    return this.restApiService
      .queryChangeFiles(
        this.change._number,
        this.patchNum,
        input,
        throwingErrorCallback
      )
      .then(res => {
        if (!res)
          throw new Error('Failed to retrieve files. Response not set.');
        return res.map(file => {
          return {name: file};
        });
      });
  }

  private computeIsInvisible(id: string) {
    return this.hiddenActions.includes(id) ? 'invisible' : '';
  }

  private handleDragAndDropUpload(e: DragEvent) {
    if (this.fileUploaded) return;

    e.preventDefault();
    e.stopPropagation();

    // Reset background on drop
    this.dragDropArea!.classList.remove('hover');

    if (!e.dataTransfer || !e.dataTransfer.files) return;
    this.fileUpload(e.dataTransfer.files[0]);
  }

  private handleFileUploadChange(e: InputEvent) {
    const input = e.target;
    if (
      this.fileUploaded ||
      !input ||
      !(input instanceof HTMLInputElement) ||
      !input.files
    )
      return;
    this.fileUpload(input.files[0]);
  }

  private async fileUpload(file: File) {
    if (!file) return;

    let path = this.path;
    if (!path) {
      path = file.name;
    }

    this.fileUploaded = true;
    this.fileName = path;
    this.fileSize = formatBytes(file.size, false);
    await this.updateComplete;

    // Disable drag/drop and input during the upload process
    this.dragDropArea?.classList.add('disabled');

    const fileReader = new FileReader();
    fileReader.onload = (fileLoadEvent: ProgressEvent<FileReader>) => {
      if (!fileLoadEvent) return;
      const fileData = fileLoadEvent.target!.result;
      if (typeof fileData !== 'string') return;
      this.handleUploadConfirm(path, fileData);
    };
    fileReader.readAsDataURL(file);
  }

  private handleTextChanged(e: BindValueChangeEvent) {
    this.path = e.detail.value ?? '';
  }

  // Reset the upload status when dialog is opened or closed
  private async resetUploadStatus() {
    this.fileName = '';
    this.fileSize = '';
    const dropZone = this.dragDropArea;
    dropZone!.classList.remove('disabled');
    dropZone!.classList.remove('hover');
    this.fileUploaded = false;
    await this.updateComplete;
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-edit-controls': GrEditControls;
  }
}
