/**
 * @license
 * Copyright 2016 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {ImageInfo} from '../../../types/common';
import {Side} from '../../../api/diff';
import '../gr-diff-image-viewer/gr-image-viewer';
import {html, LitElement, nothing} from 'lit';
import {property, query, state} from 'lit/decorators.js';
import {isNewDiff} from '../gr-diff/gr-diff-utils';

// MIME types for images we allow showing. Do not include SVG, it can contain
// arbitrary JavaScript.
const IMAGE_MIME_PATTERN = /^image\/(bmp|gif|x-icon|jpeg|jpg|png|tiff|webp)$/;

class GrDiffImageNew extends LitElement {
  @property() baseImage?: ImageInfo;

  @property() revisionImage?: ImageInfo;

  @property() automaticBlink = false;

  /**
   * The browser API for handling selection does not (yet) work for selection
   * across multiple shadow DOM elements. So we are rendering gr-diff components
   * into the light DOM instead of the shadow DOM by overriding this method,
   * which was the recommended workaround by the lit team.
   * See also https://github.com/WICG/webcomponents/issues/79.
   */
  override createRenderRoot() {
    return this;
  }

  override render() {
    return html`
      <tbody class="gr-diff image-diff">
        <tr class="gr-diff">
          <td class="gr-diff" colspan="4">
            <gr-image-viewer
              class="gr-diff"
              .baseUrl=${imageSrc(this.baseImage)}
              .revisionUrl=${imageSrc(this.revisionImage)}
              .automaticBlink=${this.automaticBlink}
            >
            </gr-image-viewer>
          </td>
        </tr>
      </tbody>
    `;
  }
}

class GrDiffImageOld extends LitElement {
  @property() baseImage?: ImageInfo;

  @property() revisionImage?: ImageInfo;

  @query('img.left') baseImageEl?: HTMLImageElement;

  @query('img.right') revisionImageEl?: HTMLImageElement;

  @state() baseError?: string;

  @state() revisionError?: string;

  /**
   * The browser API for handling selection does not (yet) work for selection
   * across multiple shadow DOM elements. So we are rendering gr-diff components
   * into the light DOM instead of the shadow DOM by overriding this method,
   * which was the recommended workaround by the lit team.
   * See also https://github.com/WICG/webcomponents/issues/79.
   */
  override createRenderRoot() {
    return this;
  }

  override render() {
    return html`
      <tbody class="gr-diff image-diff">
        ${this.renderImagePairRow()} ${this.renderImageLabelRow()}
      </tbody>
      ${this.renderEndpoint()}
    `;
  }

  private renderEndpoint() {
    return html`
      <tbody class="gr-diff endpoint">
        <tr class="gr-diff">
          <td class="gr-diff" colspan="4">
            <gr-endpoint-decorator class="gr-diff" name="image-diff">
              ${this.renderEndpointParam('baseImage', this.baseImage)}
              ${this.renderEndpointParam('revisionImage', this.revisionImage)}
            </gr-endpoint-decorator>
          </td>
        </tr>
      </tbody>
    `;
  }

  private renderEndpointParam(name: string, value: unknown) {
    if (!value) return nothing;
    return html`
      <gr-endpoint-param class="gr-diff" name=${name} .value=${value}>
      </gr-endpoint-param>
    `;
  }

  private renderImagePairRow() {
    return html`
      <tr class="gr-diff">
        <td class="gr-diff left lineNum blank"></td>
        <td class="gr-diff left">${this.renderImage(Side.LEFT)}</td>
        <td class="gr-diff right lineNum blank"></td>
        <td class="gr-diff right">${this.renderImage(Side.RIGHT)}</td>
      </tr>
    `;
  }

  private renderImage(side: Side) {
    const image = side === Side.LEFT ? this.baseImage : this.revisionImage;
    if (!image) return nothing;
    const error = side === Side.LEFT ? this.baseError : this.revisionError;
    if (error) return error;
    const src = imageSrc(image);
    if (!src) return nothing;

    return html`
      <img
        class="gr-diff ${side}"
        src=${src}
        @load=${this.handleLoad}
        @error=${(e: Event) => this.handleError(e, side)}
      >
      </img>
    `;
  }

  private handleLoad() {
    this.requestUpdate();
  }

  private handleError(e: Event, side: Side) {
    const msg = `[Image failed to load] ${e.type}`;
    if (side === Side.LEFT) this.baseError = msg;
    if (side === Side.RIGHT) this.revisionError = msg;
  }

  private renderImageLabelRow() {
    return html`
      <tr class="gr-diff">
        <td class="gr-diff left lineNum blank"></td>
        <td class="gr-diff left">
          <label class="gr-diff">
            ${this.renderName(this.baseImage?._name ?? '')}
            <span class="gr-diff label">${this.imageLabel(Side.LEFT)}</span>
          </label>
        </td>
        <td class="gr-diff right lineNum blank"></td>
        <td class="gr-diff right">
          <label class="gr-diff">
            ${this.renderName(this.revisionImage?._name ?? '')}
            <span class="gr-diff label"> ${this.imageLabel(Side.RIGHT)} </span>
          </label>
        </td>
      </tr>
    `;
  }

  private renderName(name?: string) {
    const addNamesInLabel =
      this.baseImage &&
      this.revisionImage &&
      this.baseImage._name !== this.revisionImage._name;
    if (!addNamesInLabel) return nothing;
    return html`
      <span class="gr-diff name">${name}</span><br class="gr-diff" />
    `;
  }

  private imageLabel(side: Side) {
    const image = side === Side.LEFT ? this.baseImage : this.revisionImage;
    const imageEl =
      side === Side.LEFT ? this.baseImageEl : this.revisionImageEl;
    if (image) {
      const type = image.type ?? image._expectedType;
      if (imageEl?.naturalWidth && imageEl.naturalHeight) {
        return `${imageEl?.naturalWidth}×${imageEl.naturalHeight} ${type}`;
      } else {
        return type;
      }
    }
    return 'No image';
  }
}

function imageSrc(image?: ImageInfo): string {
  return image && IMAGE_MIME_PATTERN.test(image.type)
    ? `data:${image.type};base64,${image.body}`
    : '';
}

// TODO(newdiff-cleanup): Remove once newdiff migration is completed.
if (isNewDiff()) {
  customElements.define('gr-diff-image-new', GrDiffImageNew);
  customElements.define('gr-diff-image-old', GrDiffImageOld);
}

declare global {
  interface HTMLElementTagNameMap {
    // TODO(newdiff-cleanup): Replace once newdiff migration is completed.
    'gr-diff-image-new': LitElement;
    'gr-diff-image-old': LitElement;
  }
}
