/**
 * @license
 * Copyright 2020 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
interface ElementWithShadowRoot extends Element {
  shadowRoot: ShadowRoot;
}

/**
 * Type guard for element with a shadowRoot.
 */
function isElementWithShadowRoot(
  el: Element | ShadowRoot
): el is ElementWithShadowRoot {
  return 'shadowRoot' in el;
}

export function isElement(node: Node): node is Element {
  return node.nodeType === 1;
}

export function isElementTarget(
  target: EventTarget | null | undefined
): target is Element {
  if (!target) return false;
  return 'nodeType' in target && isElement(target as Node);
}

// TODO: maybe should have a better name for this
function getPathFromNode(el: EventTarget) {
  let tagName = '';
  let id = '';
  let className = '';
  if (el instanceof Element) {
    tagName = el.tagName;
    id = el.id;
    className = el.className;
  }
  if (
    !tagName ||
    'GR-APP' === tagName ||
    el instanceof DocumentFragment ||
    el instanceof HTMLSlotElement
  ) {
    return '';
  }
  let path = '';
  if (tagName) {
    path += tagName.toLowerCase();
  }
  if (id) {
    path += `#${id}`;
  }
  if (className) {
    path += `.${className.replace(/ /g, '.')}`;
  }
  return path;
}

/**
 * Get computed style value.
 */
export function getComputedStyleValue(name: string, el: Element) {
  return getComputedStyle(el).getPropertyValue(name).trim();
}

/**
 * Query selector on a dom element.
 *
 * This is shadow DOM compatible, but only works when selector is within
 * one shadow host, won't work if your selector is crossing
 * multiple shadow hosts.
 *
 */
export function querySelector(
  el: Element | ShadowRoot,
  selector: string
): Element | null {
  let nodes = [el];
  let result = null;
  while (nodes.length) {
    const node = nodes.pop();

    // Skip if it's an invalid node.
    if (!node || !node.querySelector) continue;

    // Try find it with native querySelector directly
    result = node.querySelector(selector);

    if (result) {
      break;
    }

    // Add all nodes with shadowRoot and loop through
    const allShadowNodes = [...node.querySelectorAll('*')]
      .filter(isElementWithShadowRoot)
      .map(child => child.shadowRoot);
    nodes = nodes.concat(allShadowNodes);

    // Add shadowRoot of current node if has one
    // as its not included in node.querySelectorAll('*')
    if (isElementWithShadowRoot(node)) {
      nodes.push(node.shadowRoot);
    }
  }
  return result;
}

/**
 * Query selector all dom elements matching with certain selector.
 *
 * This is shadow DOM compatible, but only works when selector is within
 * one shadow host, won't work if your selector is crossing
 * multiple shadow hosts.
 *
 * Note: this can be very expensive, only use when have to.
 */
export function querySelectorAll(
  el: Element | ShadowRoot,
  selector: string
): Element[] {
  let nodes = [el];
  const results = new Set<Element>();
  while (nodes.length) {
    const node = nodes.pop();

    if (!node || !node.querySelectorAll) continue;

    // Try find all from regular children
    [...node.querySelectorAll(selector)].forEach(el => results.add(el));

    // Add all nodes with shadowRoot and loop through
    const allShadowNodes = [...node.querySelectorAll('*')]
      .filter(isElementWithShadowRoot)
      .map(child => child.shadowRoot);
    nodes = nodes.concat(allShadowNodes);

    // Add shadowRoot of current node if has one
    // as its not included in node.querySelectorAll('*')
    if (isElementWithShadowRoot(node)) {
      nodes.push(node.shadowRoot);
    }
  }
  return [...results];
}

export function windowLocationReload() {
  const e = new Error();
  console.info(`Calling window.location.reload(): ${e.stack}`);
  window.location.reload();
}

/**
 * Retrieves the dom path of the current event.
 *
 * If the event object contains a `path` property, then use it,
 * otherwise, construct the dom path based on the event target.
 *
 * domNode.onclick = e => {
 *  getEventPath(e); // eg: div.class1>p#pid.class2
 * }
 */
export function getEventPath<T extends MouseEvent>(e?: T) {
  if (!e) return '';

  let path = e.composedPath();
  if (!path || !path.length) {
    path = [];
    let el = e.target;
    while (el) {
      path.push(el);
      el = (el as Node).parentNode || (el as ShadowRoot).host;
    }
  }

  return path.reduce<string>((domPath: string, curEl: EventTarget) => {
    const pathForEl = getPathFromNode(curEl);
    if (!pathForEl) return domPath;
    return domPath ? `${pathForEl}>${domPath}` : pathForEl;
  }, '');
}

/**
 * Are any ancestors of the element (or the element itself) tagged with the
 * given css class?
 *
 * We are walking up the DOM using `element.parentElement`, but are not crossing
 * Shadow DOM boundaries, if there are any.
 */
export function descendedFromClass(
  element: Element | undefined,
  className: string,
  stopElement?: Element
) {
  return parentWithClass(element, className, stopElement) !== undefined;
}

/**
 * Returns an ancestor of the element (or the element itself) tagged with the
 * given css class - or undefined.
 *
 * We are walking up the DOM using `element.parentElement`, but are not crossing
 * Shadow DOM boundaries, if there are any.
 */
export function parentWithClass(
  element: Element | undefined,
  className: string,
  stopElement?: Element
) {
  while (element && (!stopElement || element !== stopElement)) {
    if (element.classList.contains(className)) return element;
    element = element.parentElement ?? undefined;
  }
  return undefined;
}

/**
 * Convert any string into a valid class name.
 *
 * For class names, naming rules:
 * Must begin with a letter A-Z or a-z
 * Can be followed by: letters (A-Za-z), digits (0-9), hyphens ("-"), and underscores ("_")
 */
export function strToClassName(str = '', prefix = 'generated_') {
  return `${prefix}${str.replace(/[^a-zA-Z0-9-_]/g, '_')}`;
}

// document.activeElement is not enough, because it's not getting activeElement
// without looking inside of shadow roots. This will find best activeElement.
export function findActiveElement(
  root: Document | ShadowRoot | null,
  ignoreDialogs?: boolean
): HTMLElement | null {
  if (root === null) {
    return null;
  }
  if (
    ignoreDialogs &&
    root.activeElement &&
    root.activeElement.nodeName.toUpperCase().includes('DIALOG')
  ) {
    return null;
  }
  if (root.activeElement?.shadowRoot?.activeElement) {
    return findActiveElement(root.activeElement.shadowRoot);
  }
  if (!root.activeElement) {
    return null;
  }
  // We block some elements
  if ('BODY' === root.activeElement.nodeName.toUpperCase()) {
    return null;
  }
  return root.activeElement as HTMLElement;
}

// Whether the browser is Safari. Used for polyfilling unique browser behavior.
export function isSafari() {
  return (
    /^((?!chrome|android).)*safari/i.test(navigator.userAgent) ||
    /iPad|iPhone|iPod/.test(navigator.userAgent)
  );
}

export function whenVisible(
  element: Element,
  callback: () => void,
  marginPx = 0
) {
  const observer = new IntersectionObserver(
    (entries: IntersectionObserverEntry[]) => {
      for (const entry of entries) {
        if (entry.isIntersecting) {
          observer.unobserve(entry.target);
          callback();
          return;
        }
      }
    },
    {rootMargin: `${marginPx}px`}
  );
  observer.observe(element);
}

/**
 * Toggles a CSS class on or off for an element.
 */
export function toggleClass(el: Element, className: string, bool?: boolean) {
  if (bool === undefined) {
    bool = !el.classList.contains(className);
  }
  if (bool) {
    el.classList.add(className);
  } else {
    el.classList.remove(className);
  }
}

/**
 * For matching the `key` property of KeyboardEvents. These are known to work
 * with Firefox, Safari and Chrome.
 */
export enum Key {
  ENTER = 'Enter',
  ESC = 'Escape',
  TAB = 'Tab',
  SPACE = ' ',
  LEFT = 'ArrowLeft',
  RIGHT = 'ArrowRight',
  UP = 'ArrowUp',
  DOWN = 'ArrowDown',
}

export enum Modifier {
  ALT_KEY,
  CTRL_KEY,
  META_KEY,
  SHIFT_KEY,
}

export enum ComboKey {
  G = 'g',
  V = 'v',
}

export interface Binding {
  key: string | Key;
  /** Defaults to false. */
  docOnly?: boolean;
  /** Defaults to not being a combo shortcut. */
  combo?: ComboKey;
  /** Defaults to no modifiers. */
  modifiers?: Modifier[];
  /** Defaults to false. If true, then `event.repeat === true` is allowed. */
  allowRepeat?: boolean;
}

const ALPHA_NUM = new RegExp(/^[A-Za-z0-9]$/);

/**
 * For "normal" keys we do not check that the SHIFT modifier is pressed or not,
 * because that depends on the keyboard layout. Just checking the key string is
 * sufficient.
 *
 * But for some special keys it is important whether SHIFT is pressed at the
 * same time, for example we want to distinguish Enter from Shift+Enter.
 */
function shiftMustMatch(key: string | Key) {
  return Object.values(Key).includes(key as Key);
}

/**
 * For a-zA-Z0-9 and for Enter, Tab, etc. we want to check the ALT modifier.
 *
 * But for special chars like []/? we don't care whether the user is pressing
 * the ALT modifier to produce the special char. For example on a German
 * keyboard layout you have to press ALT to produce a [.
 */
function altMustMatch(key: string | Key) {
  return ALPHA_NUM.test(key) || Object.values(Key).includes(key as Key);
}

export function eventMatchesShortcut(
  e: KeyboardEvent,
  shortcut: Binding
): boolean {
  if (e.key !== shortcut.key) return false;
  const modifiers = shortcut.modifiers ?? [];
  if (e.ctrlKey !== modifiers.includes(Modifier.CTRL_KEY)) return false;
  if (e.metaKey !== modifiers.includes(Modifier.META_KEY)) return false;
  if (
    altMustMatch(e.key) &&
    e.altKey !== modifiers.includes(Modifier.ALT_KEY)
  ) {
    return false;
  }
  if (
    shiftMustMatch(e.key) &&
    e.shiftKey !== modifiers.includes(Modifier.SHIFT_KEY)
  ) {
    return false;
  }
  return true;
}

export interface ShortcutOptions {
  /**
   * Do you want to suppress events from <input> elements and such?
   */
  shouldSuppress?: boolean;
  /**
   * Do you want to take care of calling preventDefault() and
   * stopPropagation() yourself? Then set this option to `false`.
   */
  preventDefault?: boolean;
}

/**
 * @deprecated
 *
 * For LitElement use the shortcut-controller.
 */
export function addShortcut(
  element: HTMLElement,
  shortcut: Binding,
  listener: (e: KeyboardEvent) => void,
  options?: ShortcutOptions
) {
  const optShouldSuppress = options?.shouldSuppress ?? false;
  const optPreventDefault = options?.preventDefault ?? true;
  const wrappedListener = (e: KeyboardEvent) => {
    if (e.repeat && !shortcut.allowRepeat) return;
    if (optShouldSuppress && shouldSuppress(e)) return;
    if (!eventMatchesShortcut(e, shortcut)) return;
    if (optPreventDefault) e.preventDefault();
    if (optPreventDefault) e.stopPropagation();
    listener(e);
  };
  element.addEventListener('keydown', wrappedListener);
  return () => element.removeEventListener('keydown', wrappedListener);
}

export function modifierPressed(e: KeyboardEvent) {
  return e.altKey || e.ctrlKey || e.metaKey || e.shiftKey;
}

export function shiftPressed(e: KeyboardEvent) {
  return e.shiftKey;
}

/**
 * When you listen on keyboard events, then within Gerrit's web app you may want
 * to avoid firing in certain common scenarios such as key strokes from <input>
 * elements. But this can also be undesirable, for example Ctrl-Enter from
 * <input> should trigger a save event.
 *
 * The shortcuts-service has a stateful method `shouldSuppress()` with
 * reporting functionality, which delegates to here.
 */
export function shouldSuppress(e: KeyboardEvent): boolean {
  // Note that when you listen on document, then `e.currentTarget` will be the
  // document and `e.target` will be `<gr-app>` due to shadow dom, but by
  // using the composedPath() you can actually find the true origin of the
  // event.
  const rootTarget = e.composedPath()[0];
  if (!isElementTarget(rootTarget)) return false;
  const tagName = rootTarget.tagName;
  const type = rootTarget.getAttribute('type');

  if (
    // Suppress shortcuts on <input> and <textarea>, but not on
    // checkboxes, because we want to enable workflows like 'click
    // mark-reviewed and then press ] to go to the next file'.
    (tagName === 'INPUT' && type !== 'checkbox') ||
    tagName === 'TEXTAREA' ||
    (e.key === 'Enter' &&
      (tagName === 'A' ||
        tagName === 'BUTTON' ||
        tagName === 'GR-BUTTON' ||
        tagName === 'PAPER-TAB'))
  ) {
    return true;
  }
  const path: EventTarget[] = e.composedPath() ?? [];
  for (const el of path) {
    if (!isElementTarget(el)) continue;
    if (el.tagName === 'DIALOG') return true;
  }
  return false;
}

/** Returns a promise that waits for the element's height to become > 0. */
export function untilRendered(el: HTMLElement) {
  return new Promise(resolve => {
    whenRendered(el, resolve);
  });
}

/** Executes the given callback when the element's height is > 0. */
export function whenRendered(
  el: HTMLElement,
  callback: (value?: unknown) => void
) {
  if (el.clientHeight > 0) {
    callback();
    return;
  }
  const obs = new ResizeObserver(() => {
    if (el.clientHeight > 0) {
      callback();
      obs.unobserve(el);
    }
  });
  obs.observe(el);
}
