/**
 * @license
 * Copyright (C) 2016 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 {
  ActionInfo,
  ChangeInfo,
} from '@gerritcodereview/typescript-api/rest-api';
import {PopupPluginApi} from '@gerritcodereview/typescript-api/popup';
import {PluginApi} from '@gerritcodereview/typescript-api/plugin';
import {RequestPayload} from '@gerritcodereview/typescript-api/rest';

// export for testing only
export type ConfigMap = {[branch: string]: boolean};

export declare interface UIActionInfo extends ActionInfo {
  __key: string;
  __url?: string;
}

export interface PopupPluginApiExtended extends PopupPluginApi {
  // TODO: Remove this reference to a private method. This can break any time.
  _getElement: () => HTMLElement;
}

export class Automerger {
  private change?: ChangeInfo;

  private action?: UIActionInfo;

  private downstreamConfigMap: ConfigMap = {};

  readonly plugin: PluginApi;

  constructor(readonly p: PluginApi) {
    this.plugin = p;
  }

  private callAction(payload: RequestPayload, onSuccess: () => void) {
    if (!this.action?.method) return;
    if (!this.action?.__url) return;
    this.plugin
      .restApi()
      .send(this.action.method, this.action.__url, payload)
      .then(onSuccess)
      .catch((error: unknown) => {
        document.dispatchEvent(
          new CustomEvent('show-alert', {
            detail: {message: `Plugin network error: ${error}`},
          })
        );
      });
  }

  private onAutomergeChange() {
    // Create checkboxes for each downstream branch.
    const branchToCheckbox: {[branch: string]: HTMLElement} = {};
    const downstreamConfigBranches = Object.keys(this.downstreamConfigMap);
    downstreamConfigBranches.forEach(branch => {
      const checkbox = document.createElement('input');
      checkbox.type = 'checkbox';
      if (this.downstreamConfigMap[branch]) checkbox.checked = true;
      const label = document.createElement('gr-label');
      label.appendChild(document.createTextNode(branch));
      const div = document.createElement('div');
      div.appendChild(checkbox);
      div.appendChild(label);
      branchToCheckbox[branch] = div;
    });

    // Create popup content.
    const popupContent = document.createElement('div');
    for (const branch of Object.keys(branchToCheckbox)) {
      popupContent.appendChild(branchToCheckbox[branch]);
      popupContent.appendChild(document.createElement('br'));
    }
    popupContent.appendChild(this.createMergeButton(branchToCheckbox));

    this.plugin.popup().then((popApi: PopupPluginApi) => {
      const popupEl = (popApi as PopupPluginApiExtended)._getElement();
      if (!popupEl) throw new Error('Popup element not found');
      popupEl.appendChild(popupContent);
    });
  }

  private createMergeButton(branchToCheckbox: {[branch: string]: HTMLElement}) {
    const onClick = (e: Event) => {
      const branchMap: {[branch: string]: boolean} = {};
      for (const branch of Object.keys(branchToCheckbox)) {
        branchMap[branch] =
          (branchToCheckbox[branch].firstChild as HTMLInputElement | undefined)
            ?.checked ?? false;
      }
      this.callAction({branch_map: branchMap}, () => {
        this.windowReload();
      });
      const target = e.currentTarget;
      if (target && target instanceof Element) {
        target.setAttribute('disabled', 'true');
      }
    };
    const button = document.createElement('gr-button');
    button.appendChild(document.createTextNode('Merge'));
    button.addEventListener('click', onClick);
    return button;
  }

  // public for testing only
  windowReload() {
    window.location.reload();
  }

  private styleRelatedChanges() {
    document.querySelectorAll('[data-branch]').forEach(relChange => {
      if (!(relChange instanceof HTMLElement)) return;
      if (!this.change) return;
      const relatedBranch = relChange.dataset['branch'];
      if (relatedBranch === this.change.branch) {
        relChange.style.fontWeight = 'bold';
      } else {
        relChange.style.fontWeight = '';
      }
      if (relChange.innerText.includes('[skipped')) {
        const parent = relChange.parentNode;
        if (parent && parent instanceof HTMLElement) {
          parent.style.backgroundColor = 'lightGray';
        }
      }
    });
  }

  private getDownstreamConfigMap() {
    const change = this.change;
    if (!change) return;

    const changeId = change._number;
    if(changeId === undefined) return;

    const revisionId = change.current_revision;
    if(revisionId === undefined) return;

    const url =
      `/changes/${changeId}/revisions/${revisionId}` +
      '/automerger~config-downstream';
    this.plugin.restApi().post<ConfigMap>(url, {subject: change.subject}).then(resp => {
      this.downstreamConfigMap = resp;
      this.styleRelatedChanges();
    });
  }

  onShowChange(change: ChangeInfo) {
    this.change = change;
    this.downstreamConfigMap = {};
    this.getDownstreamConfigMap();
  }

  onShowRevision() {
    let actionsApi = this.plugin.changeActions();

    this.action = actionsApi.getActionDetails(
      'automerge-change'
    ) as UIActionInfo;

    if (this.action) {
      actionsApi.addTapListener(this.action.__key, () => {
        this.onAutomergeChange();
      });
    }
  }
}
