// Copyright (C) 2024 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 {Trash} from '../base/disposable';
import * as Geometry from '../base/geom';

export interface VirtualScrollHelperOpts {
  overdrawPx: number;

  // How close we can get to undrawn regions before updating
  tolerancePx: number;

  callback: (r: Geometry.Rect) => void;
}

export interface Data {
  opts: VirtualScrollHelperOpts;
  rect?: Geometry.Rect;
}

export class VirtualScrollHelper {
  private readonly _trash = new Trash();
  private readonly _data: Data[] = [];

  constructor(
    sliderElement: HTMLElement,
    containerElement: Element,
    opts: VirtualScrollHelperOpts[] = [],
  ) {
    this._data = opts.map((opts) => {
      return {opts};
    });

    const recalculateRects = () => {
      this._data.forEach((data) =>
        recalculatePuckRect(sliderElement, containerElement, data),
      );
    };

    containerElement.addEventListener('scroll', recalculateRects, {
      passive: true,
    });
    this._trash.addCallback(() =>
      containerElement.removeEventListener('scroll', recalculateRects),
    );

    // Resize observer callbacks are called once immediately
    const resizeObserver = new ResizeObserver(() => {
      recalculateRects();
    });

    resizeObserver.observe(containerElement);
    resizeObserver.observe(sliderElement);
    this._trash.addCallback(() => {
      resizeObserver.disconnect();
    });
  }

  dispose() {
    this._trash.dispose();
  }
}

function recalculatePuckRect(
  sliderElement: HTMLElement,
  containerElement: Element,
  data: Data,
): void {
  const {tolerancePx, overdrawPx, callback} = data.opts;
  if (!data.rect) {
    const targetPuckRect = getTargetPuckRect(
      sliderElement,
      containerElement,
      overdrawPx,
    );
    callback(targetPuckRect);
    data.rect = targetPuckRect;
  } else {
    const viewportRect = containerElement.getBoundingClientRect();

    // Expand the viewportRect by the tolerance
    const viewportExpandedRect = Geometry.expandRect(viewportRect, tolerancePx);

    const sliderClientRect = sliderElement.getBoundingClientRect();
    const viewportClamped = Geometry.intersectRects(
      viewportExpandedRect,
      sliderClientRect,
    );

    // Translate the puck rect into client space (currently in slider space)
    const puckClientRect = Geometry.translateRect(data.rect, {
      x: sliderClientRect.x,
      y: sliderClientRect.y,
    });

    // Check if the tolerance rect entirely contains the expanded viewport rect
    // If not, request an update
    if (!Geometry.containsRect(puckClientRect, viewportClamped)) {
      const targetPuckRect = getTargetPuckRect(
        sliderElement,
        containerElement,
        overdrawPx,
      );
      callback(targetPuckRect);
      data.rect = targetPuckRect;
    }
  }
}

// Returns what the puck rect should look like
function getTargetPuckRect(
  sliderElement: HTMLElement,
  containerElement: Element,
  overdrawPx: number,
) {
  const sliderElementRect = sliderElement.getBoundingClientRect();
  const containerRect = containerElement.getBoundingClientRect();

  // Calculate the intersection of the container's viewport and the target
  const intersection = Geometry.intersectRects(
    containerRect,
    sliderElementRect,
  );

  // Pad the intersection by the overdraw amount
  const intersectionExpanded = Geometry.expandRect(intersection, overdrawPx);

  // Intersect with the original target rect unless we want to avoid resizes
  const targetRect = Geometry.intersectRects(
    intersectionExpanded,
    sliderElementRect,
  );

  return Geometry.rebaseRect(
    targetRect,
    sliderElementRect.x,
    sliderElementRect.y,
  );
}
