/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import '@polymer/paper-button/paper-button';
import '@polymer/paper-card/paper-card';
import '@polymer/paper-checkbox/paper-checkbox';
import '@polymer/paper-dropdown-menu/paper-dropdown-menu';
import '@polymer/paper-fab/paper-fab';
import '@polymer/paper-icon-button/paper-icon-button';
import '@polymer/paper-item/paper-item';
import '@polymer/paper-listbox/paper-listbox';
import './gr-overview-image';
import './gr-zoomed-image';
import '../../../elements/shared/gr-icons/gr-icons';

import {GrLibLoader} from '../../../elements/shared/gr-lib-loader/gr-lib-loader';
import {RESEMBLEJS_LIBRARY_CONFIG} from '../../../elements/shared/gr-lib-loader/resemblejs_config';

import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {ifDefined} from 'lit/directives/if-defined.js';
import {classMap} from 'lit/directives/class-map.js';
import {StyleInfo, styleMap} from 'lit/directives/style-map.js';

import {Dimensions, fitToFrame, FrameConstrainer, Point, Rect} from './util';
import {ValueChangedEvent} from '../../../types/events';
import {fire} from '../../../utils/event-util';
import {ImageDiffAction} from '../../../api/diff';

const DRAG_DEAD_ZONE_PIXELS = 5;

const DEFAULT_AUTOMATIC_BLINK_TIME_MS = 1000;

const AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS = 350;

/**
 * This components allows the user to rapidly switch between two given images
 * rendered in the same location, to make subtle differences more noticeable.
 * Images can be magnified to compare details.
 */
@customElement('gr-image-viewer')
export class GrImageViewer extends LitElement {
  /** URL for the image to use as base. */
  @property({type: String}) baseUrl = '';

  /** URL for the image to use as revision. */
  @property({type: String}) revisionUrl = '';

  /**
   * When true, cycle automatically between base and revision image, if both
   * are available.
   */
  @property({type: Boolean}) automaticBlink = false;

  @state() protected baseSelected = false;

  @state() protected scaledSelected = true;

  @state() protected followMouse = false;

  @state() protected scale = 1;

  @state() protected checkerboardSelected = true;

  @state() protected backgroundColor = '';

  @state() protected automaticBlinkShown = false;

  @state() protected zoomedImageStyle: StyleInfo = {};

  @query('.imageArea') protected imageArea!: HTMLDivElement;

  @query('gr-zoomed-image') protected zoomedImage!: Element;

  @query('#source-image') protected sourceImage!: HTMLImageElement;

  @query('#automatic-blink-button') protected automaticBlinkButton?: Element;

  private imageSize: Dimensions = {width: 0, height: 0};

  @state()
  protected magnifierSize: Dimensions = {width: 0, height: 0};

  @state()
  protected magnifierFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  @state()
  protected overviewFrame: Rect = {
    origin: {x: 0, y: 0},
    dimensions: {width: 0, height: 0},
  };

  protected readonly zoomLevels: Array<'fit' | number> = [
    'fit',
    1,
    1.25,
    1.5,
    1.75,
    2,
  ];

  @state() protected grabbing = false;

  @state() protected canHighlightDiffs = false;

  @state() protected diffHighlightSrc?: string;

  @state() protected showHighlight = false;

  private ownsMouseDown = false;

  private centerOnDown: Point = {x: 0, y: 0};

  private pointerOnDown: Point = {x: 0, y: 0};

  private readonly frameConstrainer = new FrameConstrainer();

  private readonly resizeObserver = new ResizeObserver(
    (entries: ResizeObserverEntry[]) => {
      for (const entry of entries) {
        if (entry.target === this.imageArea) {
          this.magnifierSize = {
            width: entry.contentRect.width,
            height: entry.contentRect.height,
          };
        }
      }
    }
  );

  // Ensure constant function references, so that render() does not bind a new
  // event listener on every call, as it would with lambdas.
  private createColorPickerCallback(color: string) {
    return {color, callback: () => this.pickColor(color)};
  }

  private readonly colorPickerCallbacks = [
    this.createColorPickerCallback('#fff'),
    this.createColorPickerCallback('#000'),
    this.createColorPickerCallback('#aaa'),
  ];

  private automaticBlinkTimer?: ReturnType<typeof setInterval>;

  // TODO(hermannloose): Make GrLibLoader a singleton.
  private static readonly libLoader = new GrLibLoader();

  static override get styles() {
    return [
      css`
        :host {
          display: grid;
          grid-template-rows: 1fr auto;
          grid-template-columns: 1fr auto;
          width: 100%;
          height: 100%;
          box-sizing: border-box;
          text-align: initial !important;
          font-size: var(--font-size-normal);
          --image-border-width: 2px;
        }
        .imageArea {
          grid-row-start: 1;
          grid-column-start: 1;
          box-sizing: border-box;
          flex-grow: 1;
          overflow: hidden;
          display: flex;
          flex-direction: column;
          align-items: center;
          margin: var(--spacing-m);
          padding: var(--image-border-width);
          max-height: 100%;
          position: relative;
        }
        #spacer {
          visibility: hidden;
        }
        gr-zoomed-image {
          border: var(--image-border-width) solid;
          margin: calc(-1 * var(--image-border-width));
          box-sizing: content-box;
          position: absolute;
          overflow: hidden;
          cursor: pointer;
        }
        gr-zoomed-image.base {
          border-color: var(--base-image-border-color, rgb(255, 205, 210));
        }
        gr-zoomed-image.revision {
          border-color: var(--revision-image-border-color, rgb(170, 242, 170));
        }
        #automatic-blink-button {
          position: absolute;
          right: var(--spacing-xl);
          bottom: var(--spacing-xl);
          opacity: 0;
          transition: opacity 200ms ease;
          --paper-fab-background: var(--primary-button-background-color);
          --paper-fab-keyboard-focus-background: var(
            --primary-button-background-color
          );
        }
        #automatic-blink-button.show,
        #automatic-blink-button:focus-visible {
          opacity: 1;
        }
        .checkerboard {
          --square-size: var(--checkerboard-square-size, 10px);
          --square-color: var(--checkerboard-square-color, #808080);
          background-color: var(--checkerboard-background-color, #aaaaaa);
          background-image: linear-gradient(
              45deg,
              var(--square-color) 25%,
              transparent 25%
            ),
            linear-gradient(-45deg, var(--square-color) 25%, transparent 25%),
            linear-gradient(45deg, transparent 75%, var(--square-color) 75%),
            linear-gradient(-45deg, transparent 75%, var(--square-color) 75%);
          background-size: calc(var(--square-size) * 2)
            calc(var(--square-size) * 2);
          background-position: 0 0, 0 var(--square-size),
            var(--square-size) calc(-1 * var(--square-size)),
            calc(-1 * var(--square-size)) 0;
        }
        .dimensions {
          grid-row-start: 2;
          justify-self: center;
          align-self: center;
          background: var(--primary-button-background-color);
          color: var(--primary-button-text-color);
          font-family: var(--font-family);
          font-size: var(--font-size-small);
          line-height: var(--line-height-small);
          border-radius: var(--border-radius, 4px);
          margin: var(--spacing-s);
          padding: var(--spacing-xxs) var(--spacing-s);
        }
        .controls {
          grid-column-start: 2;
          flex-grow: 0;
          display: flex;
          flex-direction: column;
          align-self: flex-start;
          margin: var(--spacing-m);
          padding-bottom: var(--spacing-xl);
        }
        paper-button {
          padding: var(--spacing-m);
          font: var(--image-diff-button-font);
          text-transform: var(--image-diff-button-text-transform, uppercase);
          outline: 1px solid transparent;
          border: 1px solid var(--primary-button-background-color);
        }
        paper-button.unelevated {
          color: var(--primary-button-text-color);
          background-color: var(--primary-button-background-color);
        }
        paper-button.outlined {
          color: var(--primary-button-background-color);
        }
        #version-switcher {
          display: flex;
          align-items: center;
          margin: var(--spacing-xl) var(--spacing-xl) var(--spacing-m);
          /* Start a stacking context to contain FAB below. */
          z-index: 0;
        }
        #version-switcher paper-button {
          flex-grow: 1;
          margin: 0;
          /*
        The floating action button below overlaps part of the version buttons.
        This min-width ensures the button text still appears somewhat balanced.
        */
          min-width: 7rem;
        }
        #version-switcher paper-fab {
          /* Round button overlaps Base and Revision buttons. */
          z-index: 1;
          margin: 0 -12px;
          /* Styled as an outlined button. */
          color: var(--primary-button-background-color);
          border: 1px solid var(--primary-button-background-color);
          --paper-fab-background: var(--primary-background-color);
          --paper-fab-keyboard-focus-background: var(
            --primary-background-color
          );
        }
        #version-explanation {
          color: var(--deemphasized-text-color);
          text-align: center;
          margin: var(--spacing-xl) var(--spacing-xl) var(--spacing-m);
        }
        #highlight-changes {
          margin: var(--spacing-m) var(--spacing-xl);
        }
        gr-overview-image {
          min-width: 200px;
          min-height: 150px;
          margin-top: var(--spacing-m);
        }
        #zoom-control {
          margin: 0 var(--spacing-xl);
        }
        paper-item {
          cursor: pointer;
        }
        paper-item:hover {
          background-color: var(--hover-background-color);
        }
        #follow-mouse {
          margin: var(--spacing-m) var(--spacing-xl);
        }
        .color-picker {
          margin: var(--spacing-m) var(--spacing-xl) 0;
        }
        .color-picker .label {
          margin-bottom: var(--spacing-s);
        }
        .color-picker .options {
          display: flex;
          /* Ignore selection border for alignment, for visual balance. */
          margin-left: -3px;
        }
        .color-picker-button {
          border-width: 2px;
          border-style: solid;
          border-color: transparent;
          border-radius: 50%;
          width: 24px;
          height: 24px;
          padding: 1px;
        }
        .color-picker-button.selected {
          border-color: var(--primary-button-background-color);
        }
        .color-picker-button:focus-within:not(.selected) {
          /* Not an actual outline, as those do not follow border-radius. */
          border-color: var(--outline-color-focus);
        }
        .color-picker-button .color {
          border: 1px solid var(--border-color);
          border-radius: 50%;
          width: 100%;
          height: 100%;
          box-sizing: border-box;
        }
        #source-plus-highlight-container {
          position: relative;
        }
        #source-plus-highlight-container img {
          position: absolute;
          top: 0;
          left: 0;
        }
      `,
    ];
  }

  private renderColorPickerButton(color: string, colorPicked: () => void) {
    const selected =
      color === this.backgroundColor && !this.checkerboardSelected;
    return html`
      <div
        class=${classMap({
          'color-picker-button': true,
          selected,
        })}
      >
        <paper-icon-button
          class="color"
          style=${styleMap({backgroundColor: color})}
          @click=${colorPicked}
        ></paper-icon-button>
      </div>
    `;
  }

  private renderCheckerboardButton() {
    return html`
      <div
        class=${classMap({
          'color-picker-button': true,
          selected: this.checkerboardSelected,
        })}
      >
        <paper-icon-button
          class="color checkerboard"
          @click=${this.pickCheckerboard}
        >
        </paper-icon-button>
      </div>
    `;
  }

  override render() {
    const src = this.baseSelected ? this.baseUrl : this.revisionUrl;

    const sourceImage = html`
      <img
        id="source-image"
        src=${src}
        class=${classMap({checkerboard: this.checkerboardSelected})}
        style=${styleMap({
          backgroundColor: this.checkerboardSelected
            ? ''
            : this.backgroundColor,
        })}
        @load=${this.updateSizes}
      />
    `;

    const sourceImageWithHighlight = html`
      <div id="source-plus-highlight-container">
        ${sourceImage}
        <img
          id="highlight-image"
          style=${styleMap({
            opacity: this.showHighlight ? '1' : '0',
            // When the highlight layer is not being shown, saving the image or
            // opening it in a new tab from the context menu, e.g. for external
            // comparison, should give back the source image, not the highlight
            // layer.
            'pointer-events': this.showHighlight ? 'auto' : 'none',
          })}
          src=${ifDefined(this.diffHighlightSrc)}
        />
      </div>
    `;

    const versionExplanation = html`
      <div id="version-explanation">
        This file is being ${this.revisionUrl ? 'added' : 'deleted'}.
      </div>
    `;

    // This uses the unelevated and outlined attributes from mwc-button with
    // manual styling, for a more seamless transition later.
    const leftClasses = {
      left: true,
      unelevated: this.baseSelected,
      outlined: !this.baseSelected,
    };
    const rightClasses = {
      right: true,
      unelevated: !this.baseSelected,
      outlined: this.baseSelected,
    };
    const versionToggle = html`
      <div id="version-switcher">
        <paper-button class=${classMap(leftClasses)} @click=${this.selectBase}>
          Base
        </paper-button>
        <paper-fab
          mini
          icon="gr-icons:swapHoriz"
          title=${this.baseSelected
            ? 'switch to Revision version'
            : 'switch to Base version'}
          @click=${this.manualBlink}
        >
        </paper-fab>
        <paper-button
          class=${classMap(rightClasses)}
          @click=${this.selectRevision}
        >
          Revision
        </paper-button>
      </div>
    `;

    const versionSwitcher = html`
      ${this.baseUrl && this.revisionUrl ? versionToggle : versionExplanation}
    `;

    const highlightSwitcher = this.diffHighlightSrc
      ? html`
          <paper-checkbox
            id="highlight-changes"
            ?checked=${this.showHighlight}
            @change=${this.showHighlightChanged}
          >
            Highlight differences
          </paper-checkbox>
        `
      : '';

    const overviewImage = html`
      <gr-overview-image
        .frameRect=${this.overviewFrame}
        @center-updated=${this.onOverviewCenterUpdated}
      >
        <img
          src=${src}
          class=${classMap({checkerboard: this.checkerboardSelected})}
          style=${styleMap({
            backgroundColor: this.checkerboardSelected
              ? ''
              : this.backgroundColor,
          })}
        />
      </gr-overview-image>
    `;

    const zoomControl = html`
      <paper-dropdown-menu id="zoom-control" label="Zoom">
        <paper-listbox
          slot="dropdown-content"
          selected="fit"
          .attrForSelected=${'value'}
          @selected-changed=${this.zoomControlChanged}
        >
          ${this.zoomLevels.map(
            zoomLevel => html`
              <paper-item value=${zoomLevel}>
                ${zoomLevel === 'fit' ? 'Fit' : `${zoomLevel * 100}%`}
              </paper-item>
            `
          )}
        </paper-listbox>
      </paper-dropdown-menu>
    `;

    const followMouse = html`
      <paper-checkbox
        id="follow-mouse"
        ?checked=${this.followMouse}
        @change=${this.followMouseChanged}
      >
        Magnifier follows mouse
      </paper-checkbox>
    `;

    const backgroundPicker = html`
      <div class="color-picker">
        <div class="label">Background</div>
        <div class="options">
          ${this.renderCheckerboardButton()}
          ${this.colorPickerCallbacks.map(({color, callback}) =>
            this.renderColorPickerButton(color, callback)
          )}
        </div>
      </div>
    `;

    /*
     * We want the content to fill the available space until it can display
     * without being cropped, the maximum of which will be determined by
     * (max-)width and (max-)height constraints on the host element; but we
     * are also limiting the displayed content to the measured dimensions of
     * the host element without overflow, so we need something else to take up
     * the requested space unconditionally.
     */
    const spacerScale = Math.max(this.scale, 1);
    const spacerWidth = this.imageSize.width * spacerScale;
    const spacerHeight = this.imageSize.height * spacerScale;
    const spacer = html`
      <div
        id="spacer"
        style=${styleMap({
          width: `${spacerWidth}px`,
          height: `${spacerHeight}px`,
        })}
      ></div>
    `;

    const automaticBlink = html`
      <paper-fab
        id="automatic-blink-button"
        class=${classMap({show: this.automaticBlinkShown})}
        title="Automatic blink"
        icon="gr-icons:${this.automaticBlink ? 'pause' : 'playArrow'}"
        @click=${this.toggleAutomaticBlink}
      >
      </paper-fab>
    `;

    // To pass CSS mixins for @apply to Polymer components, they need to appear
    // in <style> inside the template.
    /* eslint-disable lit/prefer-static-styles */
    const customStyle = html`
      <style>
        /* prettier formatter removes semi-colons after css mixins. */
        /* prettier-ignore */
        paper-item {
          --paper-item-min-height: 48;
          --paper-item: {
            min-height: 48px;
            padding: 0 var(--spacing-xl);
          };
          --paper-item-focused-before: {
            background-color: var(--selection-background-color);
          };
          --paper-item-focused: {
            background-color: var(--selection-background-color);
          };
        }
      </style>
    `;

    return html`
      ${customStyle}
      <div
        class="imageArea"
        @mousemove=${this.mousemoveImageArea}
        @mouseleave=${this.mouseleaveImageArea}
      >
        <gr-zoomed-image
          class=${classMap({
            base: this.baseSelected,
            revision: !this.baseSelected,
          })}
          style=${styleMap({
            ...this.zoomedImageStyle,
            cursor: this.grabbing ? 'grabbing' : 'pointer',
          })}
          .scale=${this.scale}
          .frameRect=${this.magnifierFrame}
          @mousedown=${this.mousedownMagnifier}
          @mouseup=${this.mouseupMagnifier}
          @mousemove=${this.mousemoveMagnifier}
          @mouseleave=${this.mouseleaveMagnifier}
          @dragstart=${this.dragstartMagnifier}
        >
          ${sourceImageWithHighlight}
        </gr-zoomed-image>
        ${this.baseUrl && this.revisionUrl ? automaticBlink : ''} ${spacer}
      </div>

      <div class="dimensions">
        ${this.imageSize.width} x ${this.imageSize.height}
      </div>

      <paper-card class="controls">
        ${versionSwitcher} ${highlightSwitcher} ${overviewImage} ${zoomControl}
        ${!this.scaledSelected ? followMouse : ''} ${backgroundPicker}
      </paper-card>
    `;
  }

  override firstUpdated() {
    this.resizeObserver.observe(this.imageArea, {box: 'content-box'});
    GrImageViewer.libLoader.getLibrary(RESEMBLEJS_LIBRARY_CONFIG).then(() => {
      this.canHighlightDiffs = true;
      this.computeDiffImage();
    });
  }

  // We don't want property changes in updateSizes() to trigger infinite update
  // loops, so we perform this in update() instead of updated().
  override update(changedProperties: PropertyValues) {
    // eslint-disable-next-line lit/no-property-change-update
    if (!this.baseUrl) this.baseSelected = false;
    // eslint-disable-next-line lit/no-property-change-update
    if (!this.revisionUrl) this.baseSelected = true;
    this.updateSizes();
    super.update(changedProperties);
  }

  override updated(changedProperties: PropertyValues) {
    if (
      (changedProperties.has('baseUrl') && this.baseSelected) ||
      (changedProperties.has('revisionUrl') && !this.baseSelected)
    ) {
      this.frameConstrainer.requestCenter({x: 0, y: 0});
    }
    if (changedProperties.has('automaticBlink')) {
      this.updateAutomaticBlink();
    }
    if (
      this.canHighlightDiffs &&
      (changedProperties.has('baseUrl') || changedProperties.has('revisionUrl'))
    ) {
      this.computeDiffImage();
    }
  }

  private computeDiffImage() {
    if (!(this.baseUrl && this.revisionUrl)) return;
    window
      .resemble(this.baseUrl)
      .compareTo(this.revisionUrl)
      // By default Resemble.js applies some color / alpha tolerance as well as
      // min / max brightness beyond which to ignore changes. Until we have
      // controls to let the user affect these options, always highlight all
      // changed pixels.
      .ignoreNothing()
      .onComplete(result => {
        this.diffHighlightSrc = result.getImageDataUrl();
      });
  }

  fireAction(detail: ImageDiffAction) {
    fire(this, 'image-diff-action', detail);
  }

  selectBase() {
    if (!this.baseUrl) return;
    this.baseSelected = true;
    this.fireAction({type: 'version-switcher-clicked', button: 'base'});
  }

  selectRevision() {
    if (!this.revisionUrl) return;
    this.baseSelected = false;
    this.fireAction({type: 'version-switcher-clicked', button: 'revision'});
  }

  manualBlink() {
    this.toggleImage();
    this.fireAction({type: 'version-switcher-clicked', button: 'switch'});
  }

  private toggleImage() {
    if (this.baseUrl && this.revisionUrl) {
      this.baseSelected = !this.baseSelected;
    }
  }

  toggleAutomaticBlink() {
    this.automaticBlink = !this.automaticBlink;
    this.fireAction({
      type: 'automatic-blink-changed',
      value: this.automaticBlink,
    });
  }

  private updateAutomaticBlink() {
    if (this.automaticBlink) {
      this.toggleImage();
      this.setBlinkInterval();
    } else {
      this.clearBlinkInterval();
    }
  }

  private setBlinkInterval() {
    this.clearBlinkInterval();
    this.automaticBlinkTimer = setInterval(() => {
      this.toggleImage();
    }, DEFAULT_AUTOMATIC_BLINK_TIME_MS);
  }

  private clearBlinkInterval() {
    if (this.automaticBlinkTimer) {
      clearInterval(this.automaticBlinkTimer);
      this.automaticBlinkTimer = undefined;
    }
  }

  showHighlightChanged() {
    this.toggleHighlight('controls');
  }

  private toggleHighlight(source: 'controls' | 'magnifier') {
    this.showHighlight = !this.showHighlight;
    this.fireAction({
      type: 'highlight-changes-changed',
      value: this.showHighlight,
      source,
    });
  }

  zoomControlChanged(event: ValueChangedEvent<string>) {
    const scaleString = event.detail.value;
    if (!scaleString) return;
    if (scaleString === 'fit') {
      this.scaledSelected = true;
      this.fireAction({type: 'zoom-level-changed', scale: 'fit'});
    }
    const scale = Number(scaleString);
    if (Number.isFinite(scale) && scale > 0) {
      this.scaledSelected = false;
      this.scale = scale;
      this.fireAction({type: 'zoom-level-changed', scale});
    }
    this.updateSizes();
  }

  followMouseChanged() {
    this.followMouse = !this.followMouse;
    this.fireAction({type: 'follow-mouse-changed', value: this.followMouse});
  }

  pickColor(value: string) {
    this.checkerboardSelected = false;
    this.backgroundColor = value;
    this.fireAction({type: 'background-color-changed', value});
  }

  pickCheckerboard() {
    this.checkerboardSelected = true;
    this.fireAction({type: 'background-color-changed', value: 'checkerboard'});
  }

  mousemoveImageArea(event: MouseEvent) {
    if (this.automaticBlinkButton) {
      this.updateAutomaticBlinkVisibility(event);
    }
    this.mousemoveMagnifier(event);
  }

  private updateAutomaticBlinkVisibility(event: MouseEvent) {
    const rect = this.automaticBlinkButton!.getBoundingClientRect();
    const centerX = rect.left + (rect.right - rect.left) / 2;
    const centerY = rect.top + (rect.bottom - rect.top) / 2;
    const distX = Math.abs(centerX - event.clientX);
    const distY = Math.abs(centerY - event.clientY);
    this.automaticBlinkShown =
      distX < AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS &&
      distY < AUTOMATIC_BLINK_BUTTON_ACTIVE_AREA_PIXELS;
  }

  mouseleaveImageArea() {
    this.automaticBlinkShown = false;
  }

  mousedownMagnifier(event: MouseEvent) {
    if (event.buttons === 1) {
      this.ownsMouseDown = true;
      this.centerOnDown = this.frameConstrainer.getCenter();
      this.pointerOnDown = {
        x: event.clientX,
        y: event.clientY,
      };
    }
  }

  mouseupMagnifier(event: MouseEvent) {
    if (!this.ownsMouseDown) return;
    this.grabbing = false;
    this.ownsMouseDown = false;

    if (event.shiftKey && this.diffHighlightSrc) {
      this.toggleHighlight('magnifier');
      return;
    }

    const offsetX = event.clientX - this.pointerOnDown.x;
    const offsetY = event.clientY - this.pointerOnDown.y;
    const distance = Math.max(Math.abs(offsetX), Math.abs(offsetY));
    // Consider very short drags as clicks. These tend to happen more often on
    // external mice.
    if (distance < DRAG_DEAD_ZONE_PIXELS) {
      this.toggleImage();
      this.fireAction({type: 'magnifier-clicked'});
    } else {
      this.fireAction({type: 'magnifier-dragged'});
    }
  }

  mousemoveMagnifier(event: MouseEvent) {
    if (event.buttons === 1 && this.ownsMouseDown) {
      this.handleMagnifierDrag(event);
      return;
    }
    if (this.followMouse) {
      this.handleFollowMouse(event);
      return;
    }
  }

  private handleMagnifierDrag(event: MouseEvent) {
    this.grabbing = true;
    const offsetX = event.clientX - this.pointerOnDown.x;
    const offsetY = event.clientY - this.pointerOnDown.y;
    this.frameConstrainer.requestCenter({
      x: this.centerOnDown.x - offsetX / this.scale,
      y: this.centerOnDown.y - offsetY / this.scale,
    });
    this.updateFrames();
  }

  private handleFollowMouse(event: MouseEvent) {
    const rect = this.imageArea.getBoundingClientRect();
    const offsetX = event.clientX - rect.left;
    const offsetY = event.clientY - rect.top;
    const fractionX = offsetX / rect.width;
    const fractionY = offsetY / rect.height;
    this.frameConstrainer.requestCenter({
      x: this.imageSize.width * fractionX,
      y: this.imageSize.height * fractionY,
    });
    this.updateFrames();
  }

  mouseleaveMagnifier() {
    if (!this.ownsMouseDown) return;
    this.grabbing = false;
    this.ownsMouseDown = false;
    this.fireAction({type: 'magnifier-dragged'});
  }

  dragstartMagnifier(event: DragEvent) {
    event.preventDefault();
  }

  onOverviewCenterUpdated(event: CustomEvent<Point>) {
    this.frameConstrainer.requestCenter({
      x: event.detail.x,
      y: event.detail.y,
    });
    this.updateFrames();
  }

  updateFrames() {
    this.magnifierFrame = this.frameConstrainer.getUnscaledFrame();
    this.overviewFrame = this.frameConstrainer.getScaledFrame();
  }

  updateSizes() {
    if (!this.sourceImage || !this.sourceImage.complete) return;

    this.imageSize = {
      width: this.sourceImage.naturalWidth || 0,
      height: this.sourceImage.naturalHeight || 0,
    };

    this.frameConstrainer.setBounds(this.imageSize);

    if (this.scaledSelected) {
      const fittedImage = fitToFrame(this.imageSize, this.magnifierSize);
      this.scale = Math.min(fittedImage.scale, 1);
    }

    this.frameConstrainer.setScale(this.scale);

    const scaledImageSize = {
      width: this.imageSize.width * this.scale,
      height: this.imageSize.height * this.scale,
    };

    const width = Math.min(this.magnifierSize.width, scaledImageSize.width);
    const height = Math.min(this.magnifierSize.height, scaledImageSize.height);

    this.frameConstrainer.setFrameSize({width, height});

    this.updateFrames();

    this.zoomedImageStyle = {
      ...this.zoomedImageStyle,
      width: `${width}px`,
      height: `${height}px`,
    };
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-image-viewer': GrImageViewer;
  }
  interface HTMLElementEventMap {
    'image-diff-action': CustomEvent<ImageDiffAction>;
  }
}
