/**
 * @license
 * Copyright (C) 2017 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
import '@polymer/iron-input/iron-input';
import '../../shared/gr-autocomplete/gr-autocomplete';
import '../../shared/gr-button/gr-button';
import '../../shared/gr-dialog/gr-dialog';
import '../../shared/gr-dropdown/gr-dropdown';
import '../../shared/gr-overlay/gr-overlay';
import '../../../styles/shared-styles';
import {dom, EventApi} from '@polymer/polymer/lib/legacy/polymer.dom';
import {PolymerElement} from '@polymer/polymer/polymer-element';
import {htmlTemplate} from './gr-edit-controls_html';
import {GrEditAction, GrEditConstants} from '../gr-edit-constants';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {customElement, property} from '@polymer/decorators';
import {ChangeInfo, PatchSetNum} from '../../../types/common';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {
  AutocompleteQuery,
  AutocompleteSuggestion,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {appContext} from '../../../services/app-context';

export interface GrEditControls {
  $: {
    overlay: GrOverlay;
    openDialog: GrDialog;
    deleteDialog: GrDialog;
    renameDialog: GrDialog;
    restoreDialog: GrDialog;
  };
}

@customElement('gr-edit-controls')
export class GrEditControls extends PolymerElement {
  static get template() {
    return htmlTemplate;
  }

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

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

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

  @property({type: Array})
  _actions: GrEditAction[] = Object.values(GrEditConstants.Actions);

  @property({type: String})
  _path = '';

  @property({type: String})
  _newPath = '';

  @property({type: Object})
  _query: AutocompleteQuery;

  private readonly restApiService = appContext.restApiService;

  constructor() {
    super();
    this._query = (input: string) => this._queryFiles(input);
  }

  _handleTap(e: Event) {
    e.preventDefault();
    const target = (dom(e) as EventApi).localTarget 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;
    }
    return this._showDialog(this.$.openDialog);
  }

  openDeleteDialog(path?: string) {
    if (path) {
      this._path = path;
    }
    return this._showDialog(this.$.deleteDialog);
  }

  openRenameDialog(path?: string) {
    if (path) {
      this._path = path;
    }
    return this._showDialog(this.$.renameDialog);
  }

  openRestoreDialog(path?: string) {
    if (path) {
      this._path = path;
    }
    return this._showDialog(this.$.restoreDialog);
  }

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

  _computeRenameDisabled(path: string, newPath: string) {
    return this._isValidPath(path) && this._isValidPath(newPath);
  }

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

  _showDialog(dialog: GrDialog) {
    // 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 overlay.
    this._hideAllDialogs();

    return this.$.overlay.open().then(() => {
      dialog.classList.toggle('invisible', false);
      const autocomplete = dialog.querySelector('gr-autocomplete');
      if (autocomplete) {
        autocomplete.focus();
      }
      setTimeout(() => {
        this.$.overlay.center();
      }, 1);
    });
  }

  _hideAllDialogs() {
    const dialogs = this.root!.querySelectorAll('.dialog') as NodeListOf<
      GrDialog
    >;
    for (const dialog of dialogs) {
      this._closeDialog(dialog);
    }
  }

  _closeDialog(dialog?: GrDialog, clearInputs = false) {
    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('iron-input').forEach(input => {
        input.bindValue = '';
      });
    }

    dialog.classList.toggle('invisible', true);
    return this.$.overlay.close();
  }

  _handleDialogCancel(e: Event) {
    this._closeDialog(this._getDialogFromEvent(e));
  }

  _handleOpenConfirm(e: Event) {
    const url = GerritNav.getEditUrlForDiff(
      this.change,
      this._path,
      this.patchNum
    );
    GerritNav.navigateToRelativeUrl(url);
    this._closeDialog(this._getDialogFromEvent(e), true);
  }

  _handleUploadConfirm(path: string, fileData: string) {
    if (!this.change || !path || !fileData) {
      this._closeDialog(this.$.openDialog, true);
      return;
    }
    return this.restApiService
      .saveFileUploadChangeEdit(this.change._number, path, fileData)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this._closeDialog(this.$.openDialog, true);
        GerritNav.navigateToChange(this.change);
      });
  }

  _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);
    this.restApiService
      .deleteFileInChangeEdit(this.change._number, this._path)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this._closeDialog(dialog, true);
        GerritNav.navigateToChange(this.change);
      });
  }

  _handleRestoreConfirm(e: Event) {
    const dialog = this._getDialogFromEvent(e);
    this.restApiService
      .restoreFileInChangeEdit(this.change._number, this._path)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this._closeDialog(dialog, true);
        GerritNav.navigateToChange(this.change);
      });
  }

  _handleRenameConfirm(e: Event) {
    const dialog = this._getDialogFromEvent(e);
    return this.restApiService
      .renameFileInChangeEdit(this.change._number, this._path, this._newPath)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this._closeDialog(dialog, true);
        GerritNav.navigateToChange(this.change);
      });
  }

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

  _computeIsInvisible(id: string, hiddenActions: string[]) {
    return hiddenActions.includes(id) ? 'invisible' : '';
  }

  _handleDragAndDropUpload(event: DragEvent) {
    event.preventDefault();
    event.stopPropagation();

    if (!event.dataTransfer) return;
    this._fileUpload(event.dataTransfer.files);
  }

  _handleFileUploadChanged(event: InputEvent) {
    if (!event.target) return;
    if (!(event.target instanceof HTMLInputElement)) return;
    const input = event.target as HTMLInputElement;
    if (!input.files) return;
    this._fileUpload(input.files);
  }

  _fileUpload(files: FileList) {
    for (const file of files) {
      if (!file) continue;

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

      const fr = new FileReader();
      // TODO(TS): Do we need this line?
      // fr.file = file;
      fr.onload = (fileLoadEvent: ProgressEvent<FileReader>) => {
        if (!fileLoadEvent) return;
        const fileData = fileLoadEvent.target!.result;
        if (typeof fileData !== 'string') return;
        this._handleUploadConfirm(path, fileData);
      };
      fr.readAsDataURL(file);
    }
  }
}

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