/**
 * @license
 * Copyright 2017 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
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 {GrEditAction, GrEditConstants} from '../gr-edit-constants';
import {GerritNav} from '../../core/gr-navigation/gr-navigation';
import {ChangeInfo, PatchSetNum} from '../../../types/common';
import {GrDialog} from '../../shared/gr-dialog/gr-dialog';
import {
  AutocompleteQuery,
  AutocompleteSuggestion,
  GrAutocomplete,
} from '../../shared/gr-autocomplete/gr-autocomplete';
import {getAppContext} from '../../../services/app-context';
import {fireAlert, fireReload} from '../../../utils/event-util';
import {
  assertIsDefined,
  query as queryUtil,
  queryAll,
} from '../../../utils/common-util';
import {sharedStyles} from '../../../styles/shared-styles';
import {LitElement, html, css} from 'lit';
import {customElement, property, query, state} from 'lit/decorators';
import {BindValueChangeEvent} from '../../../types/events';
import {GrOverlay} from '../../shared/gr-overlay/gr-overlay';
import {IronInputElement} from '@polymer/iron-input/iron-input';

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

  @query('#overlay') protected overlay?: GrOverlay;

  // 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;

  @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 = '';

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

  private readonly restApiService = getAppContext().restApiService;

  static override get styles() {
    return [
      sharedStyles,
      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: 50em;
        }
        gr-dialog .main {
          width: 100%;
        }
        gr-dialog .main > iron-input {
          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: content-box;
        }
        #fileUploadBrowse {
          margin-left: 0;
        }
        #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;
        }
        #dragDropArea > p {
          font-weight: var(--font-weight-bold);
          padding: var(--spacing-s);
        }
        @media screen and (max-width: 50em) {
          gr-dialog {
            width: 100vw;
          }
        }
      `,
    ];
  }

  override render() {
    return html`
      ${this.actions.map(action => this.renderAction(action))}
      <gr-overlay id="overlay" with-backdrop="">
        ${this.renderOpenDialog()} ${this.renderDeleteDialog()}
        ${this.renderRenameDialog()} ${this.renderRestoreDialog()}
      </gr-overlay>
    `;
  }

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

  private renderOpenDialog() {
    return html`
      <gr-dialog
        id="openDialog"
        class="invisible dialog"
        ?disabled=${!this.isValidPath(this.path)}
        confirm-label="Confirm"
        confirm-on-enter=""
        @confirm=${this.handleOpenConfirm}
        @cancel=${this.handleDialogCancel}
      >
        <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}
            @text-changed=${this.handleTextChanged}
          ></gr-autocomplete>
          <div
            id="dragDropArea"
            contenteditable="true"
            @drop=${this.handleDragAndDropUpload}
            @keypress=${this.handleKeyPress}
          >
            <p>Drag and drop a file here</p>
            <p>or</p>
            <p>
              <iron-input>
                <input
                  id="fileUploadInput"
                  type="file"
                  @change=${this.handleFileUploadChanged}
                  multiple
                  hidden
                />
              </iron-input>
              <label for="fileUploadInput">
                <gr-button id="fileUploadBrowse">Browse</gr-button>
              </label>
            </p>
          </div>
        </div>
      </gr-dialog>
    `;
  }

  private renderDeleteDialog() {
    return html`
      <gr-dialog
        id="deleteDialog"
        class="invisible dialog"
        ?disabled=${!this.isValidPath(this.path)}
        confirm-label="Delete"
        confirm-on-enter=""
        @confirm=${this.handleDeleteConfirm}
        @cancel=${this.handleDialogCancel}
      >
        <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}
            @text-changed=${this.handleTextChanged}
          ></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=${this.handleRenameConfirm}
        @cancel=${this.handleDialogCancel}
      >
        <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}
            @text-changed=${this.handleTextChanged}
          ></gr-autocomplete>
          <iron-input
            id="newPathIronInput"
            .bindValue=${this.newPath}
            @bind-value-changed=${this.handleBindValueChangedNewPath}
          >
            <input id="newPathInput" placeholder="Enter the new path." />
          </iron-input>
        </div>
      </gr-dialog>
    `;
  }

  private renderRestoreDialog() {
    return html`
      <gr-dialog
        id="restoreDialog"
        class="invisible dialog"
        confirm-label="Restore"
        confirm-on-enter=""
        @confirm=${this.handleRestoreConfirm}
        @cancel=${this.handleDialogCancel}
      >
        <div class="header" slot="header">Restore this file?</div>
        <div class="main" slot="main">
          <iron-input
            .bindValue=${this.path}
            @bind-value-changed=${this.handleBindValueChangedPath}
          >
            <input ?disabled=${''} />
          </iron-input>
        </div>
      </gr-dialog>
    `;
  }

  private readonly handleTap = (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;
    }
    assertIsDefined(this.openDialog, 'openDialog');
    return this.showDialog(this.openDialog);
  }

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

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

  openRestoreDialog(path?: string) {
    assertIsDefined(this.restoreDialog, 'restoreDialog');
    if (path) {
      this.path = path;
    }
    return 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.overlay, 'overlay');

    // 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 = queryUtil<GrAutocomplete>(dialog, 'gr-autocomplete');
      if (autocomplete) {
        autocomplete.focus();
      }
      setTimeout(() => {
        assertIsDefined(this.overlay, 'overlay');
        this.overlay.center();
      }, 1);
    });
  }

  // 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('iron-input').forEach(input => {
        input.bindValue = '';
      });
    }

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

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

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

  private readonly handleOpenConfirm = (e: Event) => {
    if (!this.change || !this.path) {
      fireAlert(this, 'You must enter a path.');
      this.closeDialog(this.openDialog);
      return;
    }
    const url = GerritNav.getEditUrlForDiff(
      this.change,
      this.path,
      this.patchNum
    );
    GerritNav.navigateToRelativeUrl(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.closeDialog(this.openDialog);
      return Promise.resolve();
    }
    return this.restApiService
      .saveFileUploadChangeEdit(this.change._number, path, fileData)
      .then(res => {
        if (!res || !res.ok) {
          return;
        }
        this.closeDialog(this.openDialog);
        fireReload(this, true);
      });
  }

  private readonly 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);
        fireReload(this);
      });
  };

  private readonly 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);
        fireReload(this);
      });
  };

  private readonly 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);
        fireReload(this, true);
      });
  };

  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)
      .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 readonly handleDragAndDropUpload = (e: DragEvent) => {
    e.preventDefault();
    e.stopPropagation();

    if (!e.dataTransfer) return;
    this.fileUpload(e.dataTransfer.files);
  };

  private readonly handleFileUploadChanged = (e: InputEvent) => {
    if (!e.target) return;
    if (!(e.target instanceof HTMLInputElement)) return;
    const input = e.target;
    if (!input.files) return;
    this.fileUpload(input.files);
  };

  private 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);
    }
  }

  private readonly handleKeyPress = (e: KeyboardEvent) => {
    e.preventDefault();
    e.stopImmediatePropagation();
  };

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

  private readonly handleBindValueChangedNewPath = (
    e: BindValueChangeEvent
  ) => {
    this.newPath = e.detail.value;
  };

  private readonly handleBindValueChangedPath = (e: BindValueChangeEvent) => {
    this.path = e.detail.value;
  };
}

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