/**
 * @license
 * Copyright 2021 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import {css, html, LitElement, PropertyValues} from 'lit';
import {customElement, property, query, state} from 'lit/decorators.js';
import {StyleInfo, styleMap} from 'lit/directives/style-map.js';
import {ImageDiffAction} from '../../../api/diff';
import {fire} from '../../../utils/event-util';

import {Dimensions, fitToFrame, Point, Rect} from './util';

/**
 * Displays a scaled-down version of an image with a draggable frame for
 * choosing a portion of the image to be magnified by other components.
 *
 * Slotted content can be arbitrary elements, but should be limited to images or
 * stacks of image-like elements (e.g. for overlays) with limited interactivity,
 * to prevent confusion, as the component only captures a limited set of events.
 * Slotted content is scaled to fit the bounds of the component, with
 * letterboxing if aspect ratios differ. For slotted content smaller than the
 * component, it will cap the scale at 1x and also apply letterboxing.
 */
@customElement('gr-overview-image')
export class GrOverviewImage extends LitElement {
  @property({type: Object})
  frameRect: Rect = {origin: {x: 0, y: 0}, dimensions: {width: 0, height: 0}};

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

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

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

  @state() protected dragging = false;

  @query('.content-box') protected contentBox!: HTMLDivElement;

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

  @query('.content-transform') protected contentTransform!: HTMLDivElement;

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

  protected overlay?: HTMLDivElement;

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

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

  private scale = 1;

  // When grabbing the frame to drag it around, this stores the offset of the
  // cursor from the center of the frame at the start of the drag.
  private grabOffset: Point = {x: 0, y: 0};

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

  static override get styles() {
    return [
      css`
        :host {
          --background-color: var(--overview-image-background-color, #000);
          --frame-color: var(--overview-image-frame-color, #f00);
          display: flex;
        }
        * {
          box-sizing: border-box;
        }
        ::slotted(*) {
          display: block;
        }
        .content-box {
          border: 1px solid var(--background-color);
          background-color: var(--background-color);
          width: 100%;
          position: relative;
        }
        .content {
          position: absolute;
          cursor: pointer;
        }
        .content-transform {
          position: absolute;
          transform-origin: top left;
          will-change: transform;
        }
        .frame {
          border: 1px solid var(--frame-color);
          position: absolute;
          will-change: transform;
        }
      `,
    ];
  }

  override render() {
    return html`
      <div class="content-box">
        <div
          class="content"
          style=${styleMap({
            ...this.contentStyle,
          })}
          @mousemove=${this.maybeDragFrame}
          @mousedown=${this.clickOverview}
          @mouseup=${this.releaseFrame}
        >
          <div
            class="content-transform"
            style=${styleMap(this.contentTransformStyle)}
          >
            <slot></slot>
          </div>
          <div
            class="frame"
            style=${styleMap({
              ...this.frameStyle,
              cursor: this.dragging ? 'grabbing' : 'grab',
            })}
            @mousedown=${this.grabFrame}
          ></div>
        </div>
      </div>
    `;
  }

  override connectedCallback() {
    super.connectedCallback();
    if (this.isConnected) {
      this.overlay = document.createElement('div');
      // The overlay is added directly to document body to ensure it fills the
      // entire screen to capture events, without being clipped by any parent
      // overflow properties. This means it has to be styled manually, since
      // component styles will not affect it.
      this.overlay.style.position = 'fixed';
      this.overlay.style.top = '0';
      this.overlay.style.left = '0';
      // We subtract 20 pixels in each dimension to prevent the overlay from
      // extending offscreen under any existing scrollbar and causing the
      // scrollbar for the other dimension to show up unnecessarily.
      this.overlay.style.width = 'calc(100vw - 20px)';
      this.overlay.style.height = 'calc(100vh - 20px)';
      this.overlay.style.zIndex = '10000';
      this.overlay.style.display = 'none';

      this.overlay.addEventListener('mousemove', (event: MouseEvent) =>
        this.maybeDragFrame(event)
      );
      this.overlay.addEventListener('mouseleave', (event: MouseEvent) => {
        // Ignore mouseleave events that are due to closeOverlay() calls.
        if (this.overlay?.style.display !== 'none') {
          this.releaseFrame(event);
        }
      });
      this.overlay.addEventListener('mouseup', (event: MouseEvent) =>
        this.releaseFrame(event)
      );

      document.body.appendChild(this.overlay);
    }
  }

  override disconnectedCallback() {
    if (this.overlay) {
      document.body.removeChild(this.overlay);
      this.overlay = undefined;
    }
    super.disconnectedCallback();
  }

  override firstUpdated() {
    this.resizeObserver.observe(this.contentBox);
    this.resizeObserver.observe(this.contentTransform);
  }

  override updated(changedProperties: PropertyValues) {
    if (changedProperties.has('frameRect')) {
      this.updateFrameStyle();
    }
  }

  clickOverview(event: MouseEvent) {
    if (event.buttons !== 1) return;
    event.preventDefault();

    this.dragging = true;
    this.openOverlay();

    const rect = this.content.getBoundingClientRect();
    this.notifyNewCenter({
      x: (event.clientX - rect.left) / this.scale,
      y: (event.clientY - rect.top) / this.scale,
    });
  }

  grabFrame(event: MouseEvent) {
    if (event.buttons !== 1) return;
    event.preventDefault();
    // Do not bubble up into clickOverview().
    event.stopPropagation();

    this.dragging = true;
    this.openOverlay();

    const rect = this.frame.getBoundingClientRect();
    const frameCenterX = rect.x + rect.width / 2;
    const frameCenterY = rect.y + rect.height / 2;
    this.grabOffset = {
      x: event.clientX - frameCenterX,
      y: event.clientY - frameCenterY,
    };
  }

  maybeDragFrame(event: MouseEvent) {
    event.preventDefault();
    if (!this.dragging) return;
    const rect = this.content.getBoundingClientRect();
    const center = {
      x: (event.clientX - rect.left - this.grabOffset.x) / this.scale,
      y: (event.clientY - rect.top - this.grabOffset.y) / this.scale,
    };
    this.notifyNewCenter(center);
  }

  releaseFrame(event: MouseEvent) {
    event.preventDefault();

    const detail: ImageDiffAction = {
      type: this.dragging ? 'overview-frame-dragged' : 'overview-image-clicked',
    };
    fire(this, 'image-diff-action', detail);

    this.dragging = false;
    this.closeOverlay();
    this.grabOffset = {x: 0, y: 0};
  }

  private openOverlay() {
    if (this.overlay) {
      this.overlay.style.display = 'block';
      this.overlay.style.cursor = 'grabbing';
    }
  }

  private closeOverlay() {
    if (this.overlay) {
      this.overlay.style.display = 'none';
      this.overlay.style.cursor = '';
    }
  }

  private updateScale() {
    const fitted = fitToFrame(this.imageBounds, this.contentBounds);
    this.scale = fitted.scale;

    this.contentStyle = {
      ...this.contentStyle,
      top: `${fitted.top}px`,
      left: `${fitted.left}px`,
      width: `${fitted.width}px`,
      height: `${fitted.height}px`,
    };

    this.contentTransformStyle = {
      transform: `scale(${this.scale})`,
    };

    this.updateFrameStyle();
  }

  private updateFrameStyle() {
    const x = this.frameRect.origin.x * this.scale;
    const y = this.frameRect.origin.y * this.scale;
    const width = this.frameRect.dimensions.width * this.scale;
    const height = this.frameRect.dimensions.height * this.scale;
    this.frameStyle = {
      ...this.frameStyle,
      transform: `translate(${x}px, ${y}px)`,
      width: `${width}px`,
      height: `${height}px`,
    };
  }

  private notifyNewCenter(center: Point) {
    fire(this, 'center-updated', {...center});
  }
}

declare global {
  interface HTMLElementTagNameMap {
    'gr-overview-image': GrOverviewImage;
  }
  interface HTMLElementEventMap {
    'center-updated': CustomEvent<Point>;
  }
}
