import { PageElementAny } from './page-element-any';
import { IPageElement, PageElement } from './page-element';
import { PageElementButton } from './page-element-button';
import { PageElementPaginator } from './page-element-paginator';
import { PageElementTableRow } from './page-element-table-row';
import { PageElementTableHeader } from './page-element-table-header';
import { IAbstractObject } from '@vmfvmf/kraftos-lib';

export interface IPageElementTable extends IPageElement {

  emptyTableRow?: PageElementAny;
  emptyTableRowMsg?: string;

  checkAllButton?: PageElementButton;
  batchDeleteButton?: PageElementButton;

  header?: PageElementTableHeader;
  headerTexts: Array<string>;

  frstItem?: PageElementTableRow;
  lastItem?: PageElementTableRow;

  paginator?: PageElementPaginator | boolean;

  headerActionsMenuButton?: PageElementButton;
  headerActions?: Array<string>;

  actionsMenuButton?: PageElementButton;
  actions?: Array<string>;

  updateDeleteControl?: boolean;

  interfaceToRowConverter: (iabs: IAbstractObject) => string[];

  initialData: any[];
}

export const TABLE_HEADER_DEFAULT_ID = ' thead > tr';
export const TABLE_FIRST_ROW_DEFAULT_ID = ' tbody > tr:first-child';
export const TABLE_LAST_ROW_DEFAULT_ID = ' tbody > tr:last-child';
export const TABLE_NTH_ROW_DEFAULT_ID = ' tbody > tr:nth-child';

export const DEFAULT_BATCH_DELETE_BUTTON = new PageElementButton({tooltip: 'Batch delete', id: '#btnExcluirLote' });
export const DEFAULT_CHECK_ALL_BUTTON = new PageElementButton({tooltip: 'Marcar todos', id: '#btnMarcarTodos' });

export class PageElementTable<I> extends PageElement {
  _emptyTableRow?: PageElementAny;

  validateTableWithData = false;
  header: PageElementTableHeader;
  headerTexts: Array<string>;
  firstRow?: PageElementTableRow;
  lastRow?: PageElementTableRow;
  emptyTableRowMsg?: string;
  interfaceToRowConverter: (iabs: IAbstractObject) => string[];
  initialData: I[];

  constructor(ipe: IPageElementTable) {
    super(ipe);

    if (ipe.paginator instanceof PageElementPaginator) this._paginator = ipe.paginator;
    else if (ipe.paginator) this._paginator  = new PageElementPaginator({id: 'app-paginator'});

    this.headerTexts = ipe.headerTexts;
    this.emptyTableRowMsg = ipe.emptyTableRowMsg;
    this._emptyTableRow = ipe.emptyTableRow;
    this.interfaceToRowConverter = ipe.interfaceToRowConverter;
    this.initialData = [...ipe.initialData];

    this.header = ipe.header ||
      new PageElementTableHeader({
        id: this.id + TABLE_HEADER_DEFAULT_ID,
        tableId: this.id,
        thTdsTexts: ipe.headerTexts,
        actions: ipe.headerActions,
        actionsMenuButton: ipe.headerActionsMenuButton
      });

    this.firstRow = ipe.frstItem ||
        new PageElementTableRow({
          id: this.id + TABLE_FIRST_ROW_DEFAULT_ID,
          tableId: this.id,
          actions: ipe.actions,
          thTdsTexts: ipe.initialData,
          actionsMenuButton: ipe.actionsMenuButton,
          updateDeleteControl: ipe.updateDeleteControl
        });

    this.lastRow = ipe.lastItem ||
        new PageElementTableRow({
          id: this.id + TABLE_LAST_ROW_DEFAULT_ID,
          tableId: this.id,
          actions: ipe.actions,
          actionsMenuButton: ipe.actionsMenuButton,
          rowNumber:  '' + (ipe.initialData?.length || 99),
          updateDeleteControl: ipe.updateDeleteControl
        });
  }
  _paginator?: PageElementPaginator;

  get paginator() {
    return this._paginator;
  }

  clickUpdateLastRow() {
    this.lastRow?.buttonEditClick();
    // this.pageElement.get('tbody tr:last-child button:first-child')
    // .focus()
    // .click();

    // cy.contains('Editar').click({force: true});
  }

  getNthRow(n: number) {
    return new PageElementTableRow({id: this.id + TABLE_NTH_ROW_DEFAULT_ID + `(${n})`, tableId: this.id});
  }

   get newButton() {
    return cy.get(`mat-card:has(${this.id}) app-new-button`);
  }

  get emptyTableRow() {
    return this._emptyTableRow ||
      new PageElementAny({
        id: this.id + ' tr[class*="no-rows"]',
        text: this.emptyTableRowMsg ? this.emptyTableRowMsg : Cypress.env('RESULT_TABLE_EMPTY_RESULT')
      });
  }

  validateTableResult(result: string[][]) {
    const end = this.paginator ? (1 + this.paginator!.itemsPerPage) > result.length ? result.length : this.paginator!.itemsPerPage : result.length;
    for(let i = 1; i <= end; i++) {
      let nRow = this.getNthRow(i);
      nRow.thTdsText = result[i-1];
      nRow.validateDefaultFieldValues();
    }
  }

  setFrstRowValuesFromObject<I extends IAbstractObject>(iAbs: I) {
    this.firstRow!.thTdsText = this.interfaceToRowConverter(iAbs);
  }

  validateTableResultPaginatedWithInterfaceObjects(iAbs: IAbstractObject[]) {
    this.validateTableResultPaginated(iAbs.map(this.interfaceToRowConverter));
  }

  validateTableResultWithInterfaceObjects(iAbs: IAbstractObject[]) {
    if (!iAbs) throw Error('interface object is undefined, cant be converted')
    this.validateTableResult(iAbs.map(this.interfaceToRowConverter));
  }

  validateLastRowStatus(status: 'Created' | 'Updated' | 'Deleted') {
    this.pageElement.get('tbody tr:last-child button:first-child mat-icon')
    .should('have.attr', 'mattooltip', status);
  }

  validateLastRowWithoutStatus() {
    this.pageElement.get('tbody tr:last-child button:first-child mat-icon')
    .should('not.have.attr', 'mattooltip')
  }

  validateTableResultPaginated(allItems: string[][]) {
    const start = 1 + ((this.paginator!.currentPage - 1) * this.paginator!.itemsPerPage);
    const end = (start + this.paginator!.itemsPerPage) > allItems.length ? allItems.length : start + this.paginator!.itemsPerPage - 1;
    for(let i = start; i <= end; i++) {
      let nRow = this.getNthRow(i-start+1);
      nRow.thTdsText = allItems[i-1];
      nRow.validateDefaultFieldValues();
    }
  }

  validateLastRow(iObject: IAbstractObject) {
    this.lastRow?.validateRowWObject(iObject, this.interfaceToRowConverter);
  }

  override validateDefaultFieldValues(): void {
    super.validateDefaultFieldValues();

    // VALIDATE HEADERS
    if (this.header) {
      this.header.validateDefaultFieldValues();
    }

    // VALIDATE ITEM MENU
    if (this.firstRow?.thTdsText) {
      this.firstRow.validateDefaultFieldValues();
      this.lastRow!.validateDefaultFieldValues();
    }
    else {
      this.validateEmptyTableOrNoResult();
    }

    // // VALIDATE NEW BUTTON

    if (this.paginator) {
      this.paginator.validateDefaultFieldValues();
      this.paginator.validateNavigateButtons();
    }
  }

  validateEmptyTableOrNoResult() {
    this.emptyTableRow.validateDefaultFieldValues();
  }

  checkRowsLength() {
    return this.pageElement!.get('tbody tr');
  }
}
