// Copyright (C) 2023 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use size 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 {allUnique, range} from '../../base/array_utils';
import {
  compareUniversal,
  comparingBy,
  ComparisonFn,
  SortableValue,
  SortDirection,
  withDirection,
} from '../../base/comparison_utils';
import {raf} from '../../core/raf_scheduler';
import {
  menuItem,
  PopupMenuButton,
  popupMenuIcon,
  PopupMenuItem,
} from '../popup_menu';

export interface ColumnDescriptorAttrs<T> {
  // Context menu items displayed on the column header.
  contextMenu?: PopupMenuItem[];

  // Unique column ID, used to identify which column is currently sorted.
  columnId?: string;

  // Sorting predicate: if provided, column would be sortable.
  ordering?: ComparisonFn<T>;

  // Simpler way to provide a sorting: instead of full predicate, the function
  // can map the row for "sorting key" associated with the column.
  sortKey?: (value: T) => SortableValue;
}

export class ColumnDescriptor<T> {
  name: string;
  render: (row: T) => m.Child;
  id: string;
  contextMenu?: PopupMenuItem[];
  ordering?: ComparisonFn<T>;

  constructor(
      name: string, render: (row: T) => m.Child,
      attrs?: ColumnDescriptorAttrs<T>) {
    this.name = name;
    this.render = render;
    this.id = attrs?.columnId === undefined ? name : attrs.columnId;

    if (attrs === undefined) {
      return;
    }

    if (attrs.sortKey !== undefined && attrs.ordering !== undefined) {
      throw new Error('only one way to order a column should be specified');
    }

    if (attrs.sortKey !== undefined) {
      this.ordering = comparingBy(attrs.sortKey, compareUniversal);
    }
    if (attrs.ordering !== undefined) {
      this.ordering = attrs.ordering;
    }
  }
}

export function numberColumn<T>(
    name: string, getter: (t: T) => number, contextMenu?: PopupMenuItem[]):
    ColumnDescriptor<T> {
  return new ColumnDescriptor<T>(name, getter, {contextMenu, sortKey: getter});
}

export function stringColumn<T>(
    name: string, getter: (t: T) => string, contextMenu?: PopupMenuItem[]):
    ColumnDescriptor<T> {
  return new ColumnDescriptor<T>(name, getter, {contextMenu, sortKey: getter});
}

interface SortingInfo<T> {
  columnId: string;
  direction: SortDirection;
  // TODO(ddrone): figure out if storing this can be avoided.
  ordering: ComparisonFn<T>;
}

// Encapsulated table data, that contains the input to be displayed, as well as
// some helper information to allow sorting.
export class TableData<T> {
  data: T[];
  private _sortingInfo?: SortingInfo<T>;
  private permutation: number[];

  constructor(data: T[]) {
    this.data = data;
    this.permutation = range(data.length);
  }

  * iterateItems(): Generator<T> {
    for (const index of this.permutation) {
      yield this.data[index];
    }
  }

  items(): T[] {
    return Array.from(this.iterateItems());
  }

  setItems(newItems: T[]) {
    this.data = newItems;
    this.permutation = range(newItems.length);
    if (this._sortingInfo !== undefined) {
      this.reorder(this._sortingInfo);
    }
    raf.scheduleFullRedraw();
  }

  resetOrder() {
    this.permutation = range(this.data.length);
    this._sortingInfo = undefined;
    raf.scheduleFullRedraw();
  }

  get sortingInfo(): SortingInfo<T>|undefined {
    return this._sortingInfo;
  }

  reorder(info: SortingInfo<T>) {
    this._sortingInfo = info;
    this.permutation.sort(withDirection(
        comparingBy((index: number) => this.data[index], info.ordering),
        info.direction));
    raf.scheduleFullRedraw();
  }
}

export interface TableAttrs<T> {
  data: TableData<T>;
  columns: ColumnDescriptor<T>[];
}

function directionOnIndex(
    columnId: string,
    // eslint-disable-next-line @typescript-eslint/no-explicit-any
    info?: SortingInfo<any>): SortDirection|undefined {
  if (info === undefined) {
    return undefined;
  }
  return info.columnId === columnId ? info.direction : undefined;
}

// eslint-disable-next-line @typescript-eslint/no-explicit-any
export class Table implements m.ClassComponent<TableAttrs<any>> {
  renderColumnHeader(
      // eslint-disable-next-line @typescript-eslint/no-explicit-any
      vnode: m.Vnode<TableAttrs<any>>, column: ColumnDescriptor<any>): m.Child {
    let currDirection: SortDirection|undefined = undefined;

    let items = column.contextMenu;
    if (column.ordering !== undefined) {
      const ordering = column.ordering;
      currDirection = directionOnIndex(column.id, vnode.attrs.data.sortingInfo);
      const newItems: PopupMenuItem[] = [];
      if (currDirection !== 'ASC') {
        newItems.push(menuItem('Sort ascending', () => {
          vnode.attrs.data.reorder(
              {columnId: column.id, direction: 'ASC', ordering});
        }));
      }
      if (currDirection !== 'DESC') {
        newItems.push(menuItem('Sort descending', () => {
          vnode.attrs.data.reorder({
            columnId: column.id,
            direction: 'DESC',
            ordering,
          });
        }));
      }
      if (currDirection !== undefined) {
        newItems.push(menuItem('Restore original order', () => {
          vnode.attrs.data.resetOrder();
        }));
      }
      items = [
        ...newItems,
        ...(items ?? []),
      ];
    }

    return m(
        'td', column.name, items === undefined ? null : m(PopupMenuButton, {
          icon: popupMenuIcon(currDirection),
          items,
        }));
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  checkValid(attrs: TableAttrs<any>) {
    if (!allUnique(attrs.columns.map((c) => c.id))) {
      throw new Error('column IDs should be unique');
    }
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  oncreate(vnode: m.VnodeDOM<TableAttrs<any>, this>) {
    this.checkValid(vnode.attrs);
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  onupdate(vnode: m.VnodeDOM<TableAttrs<any>, this>) {
    this.checkValid(vnode.attrs);
  }

  // eslint-disable-next-line @typescript-eslint/no-explicit-any
  view(vnode: m.Vnode<TableAttrs<any>>): m.Child {
    const attrs = vnode.attrs;

    return m(
        'table.generic-table',
        m('thead',
          m('tr.header',
            attrs.columns.map(
                (column) => this.renderColumnHeader(vnode, column)))),
        attrs.data.items().map(
            (row) =>
                m('tr',
                  attrs.columns.map((column) => m('td', column.render(row))))));
  }
}
