/**
 * @fileoverview A custom element that loads a patch based on provided CL or
 * manually entered git diff.
 *
 * @attr {string} patchType - Specifies the project for the patch. Must be
 * set. Supported values include "chromium" and "skia".
 *
 * @event cl-description-changed - Any time a different (or invalid) CL is
 * loaded
 *
 * @event patch-changed - Any time the patch changed, either due to loading a
 * new CL patchset, or manual editing of the patch field.
 */

import '../../../elements-sk/modules/icons/delete-icon-sk';
import '../../../elements-sk/modules/icons/cancel-icon-sk';
import '../../../elements-sk/modules/icons/check-circle-icon-sk';
import '../../../elements-sk/modules/icons/help-icon-sk';
import '../../../elements-sk/modules/spinner-sk';
import '../../../elements-sk/modules/toast-sk';
import '../../../infra-sk/modules/expandable-textarea-sk';

import { html } from 'lit/html.js';
import { SpinnerSk } from '../../../elements-sk/modules/spinner-sk/spinner-sk';
import { $$ } from '../../../infra-sk/modules/dom';
import { fromObject } from '../../../infra-sk/modules/query';
import { jsonOrThrow } from '../../../infra-sk/modules/jsonOrThrow';
import { define } from '../../../elements-sk/modules/define';
import { errorMessage } from '../../../elements-sk/modules/errorMessage';
import * as ctfe_utils from '../ctfe_utils';

import { ElementSk } from '../../../infra-sk/modules/ElementSk';
import '../input-sk';
import { CLDataResponse } from '../json';
import { ExpandableTextArea } from '../pageset-selector-sk/pageset-selector-sk';

export class PatchSk extends ElementSk {
  private _spinner: SpinnerSk | null = null;

  private _cl: string = '';

  private _clData: CLDataResponse | null = null;

  private _clDescription: string = '';

  private _clError: Error | null = null;

  constructor() {
    super(PatchSk.template);
    this._upgradeProperty('patchType');
  }

  private static template = (ele: PatchSk) => html`
    <table>
      <tr>
        <td>CL:</td>
        <td>
          <input-sk @input=${ele._clChanged} label="Please paste a complete Gerrit URL"></input-sk>
        </td>
        <td>
          <div class="cl-detail-container">
            <div class="cl-detail">
              <spinner-sk alt="Loading CL details"></spinner-sk>
            </div>
            <div class="cl-detail">
              <a href=${ele._clUrl()} target="_blank">${ele._formattedClData()}</a>
              <span class="cl-error">${ele._formattedClError()}</span>
            </div>
          </div>
        </td>
      </tr>
      <tr>
        <td colspan="3" class="patch-manual">
          <expandable-textarea-sk displaytext="Specify Patch Manually" @input=${ele._patchChanged}>
          </expandable-textarea-sk>
        </td>
      </tr>
    </table>
  `;

  connectedCallback(): void {
    super.connectedCallback();
    this._render();
    this._spinner = $$('spinner-sk', this);
  }

  _clChanged(e: Event): void {
    const newValue = (e.target as HTMLInputElement).value;
    this.cl = newValue;
    if (!newValue || newValue.length < 3) {
      this._clData = null;
      this._clError = null;
      this._clDescription = this._formattedClDescription();
      this._spinner!.active = false;
      this._render();
      return;
    }
    this._spinner!.active = true;
    const queryParams = { cl: newValue };
    const url = `/_/cl_data?${fromObject(queryParams)}`;

    fetch(url, { method: 'POST' })
      .then(jsonOrThrow)
      .then((json: CLDataResponse) => {
        // If the response is for the value still present in the input we
        // apply it.
        if (this.cl === newValue) {
          if (json.cl) {
            this._clData = json;
            const patch = this._clData![`${this.patchType}_patch` as keyof CLDataResponse];
            if (!patch) {
              this._clError = new Error(`This is not a ${this.patchType} CL.`);
              this._patchFetchError();
            } else {
              this.patch = patch;
            }
          } else {
            this._clData = null;
          }
        }
      })
      .catch((err) => {
        if (this.cl === newValue) {
          this._clError = err;
          this._clLoadError();
        }
      })
      .finally(() => {
        if (this.cl === newValue) {
          this.clDescription = this._formattedClDescription();
          this._spinner!.active = false;
        }
        this._render();
      });
  }

  /**
   * @returns {boolean} True if a patch is successfully loaded.
   * Trigger errorMessage event otherwise.
   */
  validate(): boolean {
    if (this.cl && !this._clData) {
      this._clLoadError();
      return false;
    }
    if (this.cl && !this.patch) {
      this._patchFetchError();
      return false;
    }
    return true;
  }

  /**
   * Expands the text area if it is collapsed.
   */
  expandTextArea(): void {
    const exTextarea = $$('expandable-textarea-sk', this) as ExpandableTextArea;
    if (!exTextarea.open) {
      ($$('button', exTextarea) as HTMLElement).click();
    }
  }

  /**
   * @prop {string} cl - Raw value of the CL input.
   */
  get cl(): string {
    return this._cl || '';
  }

  set cl(val: string) {
    this._cl = val;
  }

  /**
   * @prop {string} clDescription - Human readable description of CL.  Fires
   * 'cl-description-changed' with detail { clDescription: <new desc> } event on
   * change.
   */
  get clDescription(): string {
    return this._clDescription || '';
  }

  set clDescription(val: string) {
    this._clDescription = val;
    // shadow dom, do we need composed: true?
    this.dispatchEvent(
      new CustomEvent('cl-description-changed', {
        bubbles: true,
        detail: { clDescription: val },
      })
    );
  }

  /**
   * @prop {string} patch - The patch, either retrieved from the CL or
   * manually entered/modified.
   */
  get patch(): string {
    return ($$('expandable-textarea-sk', this) as HTMLInputElement).value || '';
  }

  set patch(val: string) {
    ($$('expandable-textarea-sk', this) as HTMLInputElement).value = val;
    this._patchChanged();
  }

  /**
   * @prop {string} patchType - Specifies the project for the patch. Must be
   * set. Possible values include "chromium" and "skia". Mirrors the attribute.
   */
  get patchType(): string {
    return this.getAttribute('patchType')!;
  }

  set patchType(val: string) {
    this.setAttribute('patchType', val!);
  }

  _clUrl(): string {
    if (this._clData && !this._clError) {
      return this._clData.url;
    }
    // eslint-disable-next-line no-script-url
    return 'javascript:void(0);';
  }

  _formattedClData(): string {
    if (this._clData && !this._clError) {
      return (
        `${this._clData.subject} (modified ` +
        `${ctfe_utils.getFormattedTimestamp(+this._clData.modified)})`
      );
    }
    return '';
  }

  _formattedClError(): string {
    if (this._clData && this._clError) {
      return this._clError.message || JSON.stringify(this._clError);
    }
    return '';
  }

  _formattedClDescription(): string {
    if (this._clData && !this._clError) {
      return `${this._clUrl()} (${this._clData.subject})`;
    }
    return '';
  }

  _clLoadError(): void {
    errorMessage(
      `Unable to load ${this.patchType} CL ${this.cl}` + '. Please specify patches manually.'
    );
  }

  _patchFetchError(): void {
    errorMessage(
      `Unable to fetch ${this.patchType} patch from CL ${this.cl}` +
        '. Please specify patches manually.'
    );
  }

  _patchChanged(): void {
    this.dispatchEvent(
      new CustomEvent('patch-changed', {
        bubbles: true,
        detail: { patch: this.patch },
      })
    );
  }
}

define('patch-sk', PatchSk);
