// Copyright (C) 2022 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 m from 'mithril';
import {SortDirection} from '../base/comparison_utils';
import {scheduleFullRedraw} from './raf';

export interface RegularPopupMenuItem {
  itemType: 'regular';
  // Display text
  text: string;
  // Action on menu item click
  callback: () => void;
}

// Helper function for simplifying defining menus.
export function menuItem(
  text: string,
  action: () => void,
): RegularPopupMenuItem {
  return {
    itemType: 'regular',
    text,
    callback: action,
  };
}

export interface GroupPopupMenuItem {
  itemType: 'group';
  text: string;
  itemId: string;
  children: PopupMenuItem[];
}

export type PopupMenuItem = RegularPopupMenuItem | GroupPopupMenuItem;

export interface PopupMenuButtonAttrs {
  // Icon for button opening a menu
  icon: string;
  // List of popup menu items
  items: PopupMenuItem[];
}

// To ensure having at most one popup menu on the screen at a time, we need to
// listen to click events on the whole page and close currently opened popup, if
// there's any. This class, used as a singleton, does exactly that.
class PopupHolder {
  // Invariant: global listener should be register if and only if this.popup is
  // not undefined.
  popup: PopupMenuButton | undefined = undefined;
  initialized = false;
  listener: (e: MouseEvent) => void;

  constructor() {
    this.listener = (e: MouseEvent) => {
      // Only handle those events that are not part of dropdown menu themselves.
      const hasDropdown =
        e.composedPath().find(PopupHolder.isDropdownElement) !== undefined;
      if (!hasDropdown) {
        this.ensureHidden();
      }
    };
  }

  static isDropdownElement(target: EventTarget) {
    if (target instanceof HTMLElement) {
      return target.tagName === 'DIV' && target.classList.contains('dropdown');
    }
    return false;
  }

  ensureHidden() {
    if (this.popup !== undefined) {
      this.popup.setVisible(false);
    }
  }

  clear() {
    if (this.popup !== undefined) {
      this.popup = undefined;
      window.removeEventListener('click', this.listener);
    }
  }

  showPopup(popup: PopupMenuButton) {
    this.ensureHidden();
    this.popup = popup;
    window.addEventListener('click', this.listener);
  }
}

// Singleton instance of PopupHolder
const popupHolder = new PopupHolder();

// For a table column that can be sorted; the standard popup icon should
// reflect the current sorting direction. This function returns an icon
// corresponding to optional SortDirection according to which the column is
// sorted. (Optional because column might be unsorted)
export function popupMenuIcon(sortDirection?: SortDirection) {
  switch (sortDirection) {
    case undefined:
      return 'more_horiz';
    case 'DESC':
      return 'arrow_drop_down';
    case 'ASC':
      return 'arrow_drop_up';
  }
}

// Component that displays a button that shows a popup menu on click.
export class PopupMenuButton implements m.ClassComponent<PopupMenuButtonAttrs> {
  popupShown = false;
  expandedGroups: Set<string> = new Set();

  setVisible(visible: boolean) {
    this.popupShown = visible;
    if (this.popupShown) {
      popupHolder.showPopup(this);
    } else {
      popupHolder.clear();
    }
    scheduleFullRedraw();
  }

  renderItem(item: PopupMenuItem): m.Child {
    switch (item.itemType) {
      case 'regular':
        return m(
          'button.open-menu',
          {
            onclick: () => {
              item.callback();
              // Hide the menu item after the action has been invoked
              this.setVisible(false);
            },
          },
          item.text,
        );
      case 'group':
        const isExpanded = this.expandedGroups.has(item.itemId);
        return m(
          'div',
          m(
            'button.open-menu.disallow-selection',
            {
              onclick: () => {
                if (this.expandedGroups.has(item.itemId)) {
                  this.expandedGroups.delete(item.itemId);
                } else {
                  this.expandedGroups.add(item.itemId);
                }
                scheduleFullRedraw();
              },
            },
            // Show text with up/down arrow, depending on expanded state.
            item.text + (isExpanded ? ' \u25B2' : ' \u25BC'),
          ),
          isExpanded
            ? m(
                'div.nested-menu',
                item.children.map((item) => this.renderItem(item)),
              )
            : null,
        );
    }
  }

  view(vnode: m.Vnode<PopupMenuButtonAttrs, this>) {
    return m(
      '.dropdown',
      m(
        '.dropdown-button',
        {
          onclick: () => {
            this.setVisible(!this.popupShown);
          },
        },
        vnode.children,
        m('i.material-icons', vnode.attrs.icon),
      ),
      m(
        this.popupShown ? '.popup-menu.opened' : '.popup-menu.closed',
        vnode.attrs.items.map((item) => this.renderItem(item)),
      ),
    );
  }
}
