/**
 * @license
 * Copyright (C) 2016 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 '../../elements/shared/gr-tooltip/gr-tooltip';
import {flush} from '@polymer/polymer/lib/legacy/polymer.dom';
import {getRootElement} from '../../scripts/rootElement';
import {property, observe} from '@polymer/decorators';
import {dedupingMixin} from '@polymer/polymer/lib/utils/mixin';
import {GrTooltip} from '../../elements/shared/gr-tooltip/gr-tooltip';
import {PolymerElement} from '@polymer/polymer';
import {Constructor} from '../../utils/common-util';

const BOTTOM_OFFSET = 7.2; // Height of the arrow in tooltip.

/** The interface corresponding to TooltipMixin */
export interface TooltipMixinInterface {
  hasTooltip: boolean;
  positionBelow: boolean;
  _isTouchDevice: boolean;
  _tooltip: GrTooltip | null;
  _titleText: string;
  _hasSetupTooltipListeners: boolean;
}

/**
 * @polymer
 * @mixinFunction
 */
export const TooltipMixin = dedupingMixin(
  <T extends Constructor<PolymerElement>>(
    superClass: T
  ): T & Constructor<TooltipMixinInterface> => {
    /**
     * @polymer
     * @mixinClass
     */
    class Mixin extends superClass {
      @property({type: Boolean})
      hasTooltip = false;

      @property({type: Boolean, reflectToAttribute: true})
      positionBelow = false;

      @property({type: Boolean})
      _isTouchDevice = 'ontouchstart' in document.documentElement;

      @property({type: Object})
      _tooltip: GrTooltip | null = null;

      @property({type: String})
      _titleText = '';

      @property({type: Boolean})
      _hasSetupTooltipListeners = false;

      // Handler for mouseenter event
      private mouseenterHandler?: (e: MouseEvent) => void;

      // Handler for scrolling on window
      private readonly windowScrollHandler: () => void;

      // Handler for showing the tooltip, will be attached to certain events
      private readonly showHandler: () => void;

      // Handler for hiding the tooltip, will be attached to certain events
      private readonly hideHandler: () => void;

      // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-explicit-any
      constructor(..._: any[]) {
        super();
        this.windowScrollHandler = () => this._handleWindowScroll();
        this.showHandler = () => this._handleShowTooltip();
        this.hideHandler = () => this._handleHideTooltip();
      }

      /** @override */
      disconnectedCallback() {
        // NOTE: if you define your own `detached` in your component
        // then this won't take affect (as its not a class yet)
        this._handleHideTooltip();
        if (this.mouseenterHandler) {
          this.removeEventListener('mouseenter', this.mouseenterHandler);
        }
        window.removeEventListener('scroll', this.windowScrollHandler);
        super.disconnectedCallback();
      }

      @observe('hasTooltip')
      _setupTooltipListeners() {
        if (!this.mouseenterHandler) {
          this.mouseenterHandler = this.showHandler;
        }

        if (!this.hasTooltip) {
          // if attribute set to false, remove the listener
          this.removeEventListener('mouseenter', this.mouseenterHandler);
          this._hasSetupTooltipListeners = false;
          return;
        }

        if (this._hasSetupTooltipListeners) {
          return;
        }
        this._hasSetupTooltipListeners = true;

        this.addEventListener('mouseenter', this.mouseenterHandler);
      }

      _handleShowTooltip() {
        if (this._isTouchDevice) {
          return;
        }

        if (
          !this.hasAttribute('title') ||
          this.getAttribute('title') === '' ||
          this._tooltip
        ) {
          return;
        }

        // Store the title attribute text then set it to an empty string to
        // prevent it from showing natively.
        this._titleText = this.getAttribute('title') || '';
        this.setAttribute('title', '');

        const tooltip = document.createElement('gr-tooltip');
        tooltip.text = this._titleText;
        tooltip.maxWidth = this.getAttribute('max-width') || '';
        tooltip.positionBelow = this.hasAttribute('position-below');

        // Set visibility to hidden before appending to the DOM so that
        // calculations can be made based on the element’s size.
        tooltip.style.visibility = 'hidden';
        getRootElement().appendChild(tooltip);
        this._positionTooltip(tooltip);
        tooltip.style.visibility = 'initial';

        this._tooltip = tooltip;
        window.addEventListener('scroll', this.windowScrollHandler);
        this.addEventListener('mouseleave', this.hideHandler);
        this.addEventListener('click', this.hideHandler);
      }

      _handleHideTooltip() {
        if (this._isTouchDevice) {
          return;
        }
        if (!this.hasAttribute('title') || !this._titleText) {
          return;
        }

        window.removeEventListener('scroll', this.windowScrollHandler);
        this.removeEventListener('mouseleave', this.hideHandler);
        this.removeEventListener('click', this.hideHandler);
        this.setAttribute('title', this._titleText);

        if (this._tooltip?.parentNode) {
          this._tooltip.parentNode.removeChild(this._tooltip);
        }
        this._tooltip = null;
      }

      _handleWindowScroll() {
        if (!this._tooltip) {
          return;
        }

        this._positionTooltip(this._tooltip);
      }

      _positionTooltip(tooltip: GrTooltip) {
        // This flush is needed for tooltips to be positioned correctly in Firefox
        // and Safari.
        flush();
        const rect = this.getBoundingClientRect();
        const boxRect = tooltip.getBoundingClientRect();
        if (!tooltip.parentElement) {
          return;
        }
        const parentRect = tooltip.parentElement.getBoundingClientRect();
        const top = rect.top - parentRect.top;
        const left =
          rect.left - parentRect.left + (rect.width - boxRect.width) / 2;
        const right = parentRect.width - left - boxRect.width;
        if (left < 0) {
          tooltip.updateStyles({
            '--gr-tooltip-arrow-center-offset': `${left}px`,
          });
        } else if (right < 0) {
          tooltip.updateStyles({
            '--gr-tooltip-arrow-center-offset': `${-0.5 * right}px`,
          });
        }
        tooltip.style.left = `${Math.max(0, left)}px`;

        if (!this.positionBelow) {
          tooltip.style.top = `${Math.max(0, top)}px`;
          tooltip.style.transform = `translateY(calc(-100% - ${BOTTOM_OFFSET}px))`;
        } else {
          tooltip.style.top = `${top + rect.height + BOTTOM_OFFSET}px`;
        }
      }
    }

    return Mixin;
  }
);
