// Copyright (C) 2021 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 * as m from 'mithril';

import {Actions} from '../common/actions';
import {
  ColumnAttrs,
  PivotTableQueryResponse,
  RowAttrs,
} from '../common/pivot_table_common';

import {globals} from './globals';
import {Panel} from './panel';
import {
  PivotTableHelper,
} from './pivot_table_helper';

interface ExpandableCellAttrs {
  pivotTableId: string;
  row: RowAttrs;
  column: ColumnAttrs;
  rowIndices: number[];
  expandedRowColumns: string[];
}

interface PivotTableRowAttrs {
  pivotTableId: string;
  row: RowAttrs;
  columns: ColumnAttrs[];
  rowIndices: number[];
  expandedRowColumns: string[];
}

interface PivotTableBodyAttrs {
  pivotTableId: string;
  rows: RowAttrs[];
  columns: ColumnAttrs[];
  rowIndices: number[];
  expandedRowColumns: string[];
}

interface PivotTableHeaderAttrs {
  helper: PivotTableHelper;
}

interface PivotTableAttrs {
  pivotTableId: string;
  helper?: PivotTableHelper;
}

class PivotTableHeader implements m.ClassComponent<PivotTableHeaderAttrs> {
  view(vnode: m.Vnode<PivotTableHeaderAttrs>) {
    const {helper} = vnode.attrs;
    const pivotTableId = helper.pivotTableId;
    const pivotTable = globals.state.pivotTable[pivotTableId];
    const resp =
        globals.queryResults.get(pivotTableId) as PivotTableQueryResponse;

    const cols = [];
    for (const column of resp.columns) {
      const isPivot = column.aggregation === undefined;
      let sortIcon;
      if (!isPivot) {
        sortIcon =
            column.order === 'DESC' ? 'arrow_drop_down' : 'arrow_drop_up';
      }
      cols.push(m(
          'td',
          {
            class: pivotTable.isLoadingQuery ? 'disabled' : '',
            draggable: !pivotTable.isLoadingQuery,
            ondragstart: (e: DragEvent) => {
              helper.selectedColumnOnDrag(e, isPivot, column.index);
            },
            ondrop: (e: DragEvent) => {
              helper.removeHighlightFromDropLocation(e);
              helper.selectedColumnOnDrop(e, isPivot, column.index);
              helper.queryPivotTableChanges();
            },
            ondragenter: (e: DragEvent) => {
              helper.highlightDropLocation(e, isPivot);
            },
            ondragleave: (e: DragEvent) => {
              helper.removeHighlightFromDropLocation(e);
            }
          },
          column.name,
          (!isPivot && sortIcon !== undefined ?
               m('i.material-icons',
                 {
                   onclick: () => {
                     if (!pivotTable.isLoadingQuery) {
                       helper.togglePivotTableAggregationSorting(column.index);
                       helper.queryPivotTableChanges();
                     }
                   }
                 },
                 sortIcon) :
               null),
          (!isPivot && resp.totalAggregations !== undefined ?
               m('.total-aggregation',
                 `(${resp.totalAggregations[column.name]})`) :
               null)));
    }
    return m('tr', cols);
  }
}

class ExpandableCell implements m.ClassComponent<ExpandableCellAttrs> {
  view(vnode: m.Vnode<ExpandableCellAttrs>) {
    const {pivotTableId, row, column, rowIndices, expandedRowColumns} =
        vnode.attrs;
    const pivotTable = globals.state.pivotTable[pivotTableId];
    let expandIcon = 'expand_more';
    if (row.expandedRows.has(column.name)) {
      expandIcon = row.expandedRows.get(column.name)!.isExpanded ?
          'expand_less' :
          'expand_more';
    }
    let spinnerVisibility = 'hidden';
    let animationState = 'paused';
    if (row.loadingColumn === column.name) {
      spinnerVisibility = 'visible';
      animationState = 'running';
    }
    const padValue = new Array(row.depth * 2).join(' ');

    return m(
        'td.allow-white-space',
        padValue,
        m('i.material-icons',
          {
            class: pivotTable.isLoadingQuery ? 'disabled' : '',
            onclick: () => {
              if (pivotTable.isLoadingQuery) {
                return;
              }
              const value = row.row[column.name]?.toString();
              if (value === undefined) {
                throw Error('Expanded row has undefined value.');
              }
              if (row.expandedRows.has(column.name) &&
                  row.expandedRows.get(column.name)!.isExpanded) {
                globals.dispatch(Actions.setPivotTableRequest({
                  pivotTableId,
                  action: 'UNEXPAND',
                  attrs: {
                    rowIndices,
                    columnIdx: column.index,
                    value,
                    expandedRowColumns
                  }
                }));
              } else {
                globals.dispatch(Actions.setPivotTableRequest({
                  pivotTableId,
                  action: column.isStackColumn ? 'DESCENDANTS' : 'EXPAND',
                  attrs: {
                    rowIndices,
                    columnIdx: column.index,
                    value,
                    expandedRowColumns
                  }
                }));
              }
            },
          },
          expandIcon),
        ' ',
        row.row[column.name],
        ' ',
        // Adds a loading spinner while querying the expanded column.
        m('.pivot-table-spinner', {
          style: {
            visibility: spinnerVisibility,
            animationPlayState: animationState
          }
        }));
  }
}

class PivotTableRow implements m.ClassComponent<PivotTableRowAttrs> {
  view(vnode: m.Vnode<PivotTableRowAttrs>) {
    const cells = [];
    const {pivotTableId, row, columns, rowIndices, expandedRowColumns} =
        vnode.attrs;

    for (const column of columns) {
      if (row.row[column.name] === undefined &&
          row.expandableColumns.has(column.name)) {
        throw Error(
            `Row data at expandable column "${column.name}" is undefined.`);
      }
      if (row.row[column.name] === undefined || row.row[column.name] === null) {
        cells.push(m('td', ''));
        continue;
      }
      if (row.expandableColumns.has(column.name)) {
        cells.push(
            m(ExpandableCell,
              {pivotTableId, row, column, rowIndices, expandedRowColumns}));
        continue;
      }
      let indentationLevel = 0;
      let expandIconSpace = 0;
      if (column.aggregation !== undefined) {
        indentationLevel = rowIndices.length - 1;
      } else {
        indentationLevel = row.depth;
        if (row.depth > 0 && column.isStackColumn) {
          expandIconSpace = 3;
        }
      }
      // For each indentation level add 2 spaces, if we have an expansion button
      // add 3 spaces to cover the icon size.
      let value = row.row[column.name]!.toString();
      value = value.padStart(
          (indentationLevel * 2) + expandIconSpace + value.length, ' ');
      cells.push(m('td.allow-white-space', value));
    }
    return m('tr', cells);
  }
}

class PivotTableBody implements m.ClassComponent<PivotTableBodyAttrs> {
  view(vnode: m.Vnode<PivotTableBodyAttrs>): m.Children {
    const pivotTableRows = [];
    const {pivotTableId, rows, columns, rowIndices, expandedRowColumns} =
        vnode.attrs;
    for (let i = 0; i < rows.length; ++i) {
      pivotTableRows.push(m(PivotTableRow, {
        pivotTableId,
        row: rows[i],
        columns,
        rowIndices: rowIndices.concat(i),
        expandedRowColumns
      }));
      for (const column of columns.slice().reverse()) {
        const expandedRows = rows[i].expandedRows.get(column.name);
        if (expandedRows !== undefined && expandedRows.isExpanded) {
          pivotTableRows.push(m(PivotTableBody, {
            pivotTableId,
            rows: expandedRows.rows,
            columns,
            rowIndices: rowIndices.concat(i),
            expandedRowColumns: expandedRowColumns.concat(column.name)
          }));
        }
      }
    }
    return pivotTableRows;
  }
}

export class PivotTable extends Panel<PivotTableAttrs> {
  view(vnode: m.CVnode<PivotTableAttrs>) {
    const {pivotTableId, helper} = vnode.attrs;
    const pivotTable = globals.state.pivotTable[pivotTableId];
    const resp =
        globals.queryResults.get(pivotTableId) as PivotTableQueryResponse;

    let body;
    let header;
    if (helper !== undefined && resp !== undefined) {
      header = m(PivotTableHeader, {helper});
      body = m(PivotTableBody, {
        pivotTableId,
        rows: resp.rows,
        columns: resp.columns,
        rowIndices: [],
        expandedRowColumns: []
      });
    }

    const startSec = pivotTable.traceTime ? pivotTable.traceTime.startSec :
                                            globals.state.traceTime.startSec;
    const endSec = pivotTable.traceTime ? pivotTable.traceTime.endSec :
                                          globals.state.traceTime.endSec;

    return m(
        'div.pivot-table-tab',
        m(
            'header.overview',
            m('span',
              m('button',
                {
                  disabled: helper === undefined || pivotTable.isLoadingQuery,
                  onclick: () => {
                    if (helper !== undefined) {
                      helper.toggleEditPivotTableModal();
                      globals.rafScheduler.scheduleFullRedraw();
                    }
                  }
                },
                'Edit'),
              ' ',
              (pivotTable.isLoadingQuery ? m('.pivot-table-spinner') : null),
              (resp !== undefined && !pivotTable.isLoadingQuery ?
                   m('span.code',
                     `Query took ${Math.round(resp.durationMs)} ms -`) :
                   null),
              m('span.code', `Selected range: ${endSec - startSec} s`)),
            m('button',
              {
                disabled: helper === undefined || pivotTable.isLoadingQuery,
                onclick: () => {
                  globals.frontendLocalState.togglePivotTable();
                  globals.queryResults.delete(pivotTableId);
                  globals.pivotTableHelper.delete(pivotTableId);
                  globals.dispatch(Actions.deletePivotTable({pivotTableId}));
                }
              },
              'Close'),
            ),
        m('.query-table-container',
          m('table.query-table.pivot-table',
            m('thead', header),
            m('tbody', body))));
  }

  renderCanvas() {}
}
