// tslint:disable
import * as React from "react";
import { differenceWith, isEqual, cloneDeep } from "lodash";
import { Grid } from "semantic-ui-react";
import { Picky } from "react-picky";
import ExportFile from "./components/ExportFile";
const ReactTable = require("react-table").default;
import checkboxHOC from "react-table/lib/hoc/selectTable";
const CheckboxTable = checkboxHOC(ReactTable);
import Pagination from "./components/Pagination";
import { multiselectList, multiselectListDefault } from "../../common";

interface Props {
  data: any;
  originalData?: any;
  columns: any[];
  defaultSorted?: any[];
  SubComponent?: any;
  filterable?: boolean;
  checkboxed?: boolean;
  showPagination?: boolean;
  showAllData?: boolean;
  showPageJump?: boolean;
  loading?: boolean;
  defaultPageSize?: number;
  getDataList?: any; // (data: any) => void;
  noDataText: string;
  serverSide?: boolean;
  pages?: number;
  tableAction?: any;
  sorted?: any;
  reset?: boolean;
  expanded?: any;
  getTrProps?: any;
  getTdProps?: any;
  collapseOnDataChange?: boolean;
  pageSizeOptions?: number[];
  selectedCheckbox?: boolean;
  sortable?: boolean;
  resolveData?: any;
  exportTable?: any;
  onSortedChange?: any;
  minRows?: number | undefined;
  className?: any;
  style?: any;
  visibleColumns: boolean;
}

interface State {
  data: any[];
  columns: any[];
  columnsSelected: any[];
  selection: any[];
  selectionRow: any[];
  selectAll: boolean;
  pages: number;
  page: number;
}

export default class MagaTable extends React.Component<Props, State> {
  // private checkboxTable: React.RefObject<HTMLInputElement>;
  // @ts-ignore
  private table: any;
  private checkboxTable: any;
  static defaultProps = {
    data: [],
    originalData: [],
    getDataList: [],
    tableAction: [],
    columns: [],
    defaultSorted: [],
    SubComponent: "",
    filterable: false,
    checkboxed: false,
    loading: false,
    showPagination: true,
    showPageJump: true,
    defaultPageSize: 10,
    showAllData: false,
    noDataText: "Nenhum registro encontrado",
    serverSide: false,
    pages: 20,
    reset: false,
    expanded: null,
    collapseOnDataChange: true,
    selectedCheckbox: false,
    sortable: true,
    className: "",
    style: {},
    visibleColumns: false,
  };

  constructor(props: Props) {
    super(props);
    this.state = {
      data: this.props.data,
      columns: this.props.columns,
      columnsSelected: multiselectListDefault(this.props.columns),
      selection: [],
      selectionRow: [],
      selectAll: false,
      pages: 20,
      page: 0,
    };
    this.table = React.createRef();
    this.checkboxTable = React.createRef();
  }

  componentDidMount() {
    const { selectedCheckbox } = this.props;
    if (selectedCheckbox) {
      this.toggleAll();
    }
  }

  UNSAFE_componentWillReceiveProps(props: any) {
    const { data, reset } = this.props;
    if (reset) {
      this.setState({ page: 0 });
    }
    this.setState({ data });
  }

  updateTable(props: any) {
    const { data } = this.props;
    this.setState({
      data,
    });
  }

  resetCheboxList() {
    this.setState({
      selection: [],
      selectionRow: [],
      selectAll: false,
    });
  }

  formatDataCheck(data: any) {
    const newData = data.map((item: { id: number }) => {
      const _id = item.id;
      return {
        _id,
        ...item,
      };
    });
    return newData;
  }

  toggleSelection = (selectKey: string, shift: any, row: any) => {
    let selection = [...this.state.selection];
    let selectionRow = [...this.state.selectionRow];
    let data = [...this.state.data];
    const key = Number(selectKey.replace("select-", ""));
    const keyIndex = selection.indexOf(key);
    if (keyIndex >= 0) {
      selection = [
        ...selection.slice(0, keyIndex),
        ...selection.slice(keyIndex + 1),
      ];
      selectionRow = [
        ...selectionRow.slice(0, keyIndex),
        ...selectionRow.slice(keyIndex + 1),
      ];
    } else {
      selection.push(key);
      selectionRow.push(row);
    }
    this.sendaDataList(selectionRow, "one");
    if (selection.length === data.length) {
      this.setState({ selectAll: true });
    } else {
      this.setState({ selectAll: false });
    }
    this.setState({ selection, selectionRow });
  };

  toggleAll = () => {
    const selectAll = this.state.selectAll ? false : true;
    const selectionRow: any[] = [];
    const wrappedInstance = this.checkboxTable.getWrappedInstance();
    let selection: any[] = [];
    if (selectAll) {
      const currentRecords = wrappedInstance.getResolvedState().sortedData;
      currentRecords.forEach((item: any) => {
        selection.push(item._original._id);
        selectionRow.push(item._original);
      });
    } else {
      const { originalData } = this.props;
      if (originalData.length) {
        const selectedData = JSON.parse(JSON.stringify(originalData));
        const changedData = wrappedInstance.resolvedData;
        selection = differenceWith(selectedData, changedData, isEqual).map(
          (item) => item._id
        );
      }
    }
    this.sendaDataList(selectionRow, "all");
    this.setState({
      selectAll,
      selectionRow,
      selection,
    });
  };

  isSelected = (key: number) => {
    const selection = this.state.selection;
    return selection.includes(key);
  };

  sendaDataList = (selection: any[], typeCheckbox?: string) => {
    this.props.getDataList(selection, typeCheckbox);
  };

  fetchData(state: any) {
    const tableAction = {
      limit: state.pageSize,
      offset: state.page * state.pageSize,
      pageSize: state.pageSize,
      sorted: state.sorted,
      filtered: state.filtered,
      page: state.page + 1,
    };
    this.props.tableAction(tableAction);
  }

  handlePageChange(pageIndex: number) {
    this.setState({ page: pageIndex });
  }

  handleToggleColumn = (list: any) => {
    const { columns } = this.state;
    columns.forEach((item: any) => {
      const columnsFiltered = list.some(
        (element: any) => element.value === item.accessor
      );
      if (columnsFiltered || item.Header.length === 0) {
        item.show = true;
      } else {
        item.show = false;
      }
    });
    this.setState({
      columns: cloneDeep(columns),
      columnsSelected: list,
    });
  };

  filterMethod = (filter: any, row: any, column: any) => {
    const id = this.getColumnFilterId(filter);
    const rowToFilter = row[id];
    let result = this.filterRow(String(rowToFilter), filter.value);
    if (result) {
      this.setState({ page: 0 });
    }
    return rowToFilter !== undefined
      ? this.filterRow(String(rowToFilter), filter.value)
      : true;
  };

  getColumnFilterId = (filter: any) => filter.pivotId || filter.id;

  filterRow = (rowValue: string, filterValue: string) =>
    rowValue.toLowerCase().includes(filterValue.toLowerCase());

  renderExportFile = (exportTable: any, visibleColumns: boolean) =>
    exportTable && (
      <Grid.Column width={visibleColumns ? 13 : 16} style={{ padding: 5 }}>
        <ExportFile exportTable={exportTable} />
      </Grid.Column>
    );

  renderVisibleColumns = (
    visibleColumns: boolean,
    columnsSelected: any,
    handleToggleColumn: any,
    columns: any
  ) =>
    visibleColumns && (
      <Grid.Column width={3} floated="right" style={{ padding: 5 }}>
        <Picky
          id={"visibleColumns"}
          filterPlaceholder={"Pesquisar"}
          value={columnsSelected}
          onChange={handleToggleColumn}
          valueKey="value"
          labelKey="text"
          multiple={true}
          includeSelectAll={true}
          includeFilter={false}
          dropdownHeight={250}
          options={multiselectList(columns)}
          open={false}
          selectAllText={"Selecionar todas"}
          placeholder={"Colunas da listagem"}
          manySelectedPlaceholder={"%s colunas selecionadas"}
          allSelectedPlaceholder={"%s colunas selecionadas"}
        />
      </Grid.Column>
    );

  render() {
    const {
      defaultSorted,
      SubComponent,
      filterable,
      defaultPageSize,
      noDataText,
      showPagination,
      showPageJump,
      loading,
      checkboxed,
      serverSide,
      pages,
      sorted,
      getTrProps,
      getTdProps,
      showAllData,
      collapseOnDataChange,
      pageSizeOptions,
      sortable,
      resolveData,
      exportTable,
      onSortedChange,
      expanded,
      minRows,
      style,
      className,
      visibleColumns,
    } = this.props;
    const {
      toggleSelection,
      isSelected,
      toggleAll,
      renderExportFile,
      renderVisibleColumns,
      handleToggleColumn,
    } = this;
    // const { data, selectAll, page, columns } = this.state;
    // const { data, selectAll, page, columns, columnsSelected } = this.state;
    const { data, selectAll, page, columns, columnsSelected } = this.state;
    const checkboxProps = {
      selectAll,
      isSelected,
      toggleSelection,
      toggleAll,
      selectType: "checkbox",
      getTrProps: (s: any, r: any) => {
        const selected = r ? this.isSelected(r.original._id) : false;
        return {
          style: {
            backgroundColor: selected && "#F7FFFF",
            color: selected && "#176F83",
          },
        };
      },
    };
    if (checkboxed && serverSide) {
      return (
        <Grid>
          {renderExportFile(exportTable, visibleColumns)}
          {renderVisibleColumns(
            visibleColumns,
            columnsSelected,
            handleToggleColumn,
            columns
          )}
          <Grid.Column width={16}>
            {/* 
  // @ts-ignore */}
            <CheckboxTable
              ref={(r: any) => (this.checkboxTable = r)}
              data={this.formatDataCheck(data)}
              columns={columns}
              defaultSorted={defaultSorted}
              SubComponent={SubComponent}
              filterable={filterable}
              defaultPageSize={
                !showPagination && showAllData ? data.length : defaultPageSize
              }
              noDataText={noDataText}
              className={`-striped -highlight ${className}`}
              showPagination={showPagination}
              showPageJump={showPageJump}
              previousText={"Anterior"}
              nextText={"Próximo"}
              pageText={"Página"}
              ofText={"de"}
              rowsText={"linhas"}
              loadingText={
                <div className="ui massive active centered inline loader"></div>
              }
              loading={loading}
              sorted={sorted}
              manual={serverSide}
              pages={pages}
              page={page}
              onFetchData={this.fetchData.bind(this)}
              onPageChange={(pageIndex: number) =>
                this.handlePageChange(pageIndex)
              }
              onSortedChange={onSortedChange}
              pageSizeOptions={pageSizeOptions}
              PaginationComponent={Pagination}
              // getTrProps={getTrProps}
              getTdProps={getTdProps}
              collapseOnDataChange={collapseOnDataChange}
              {...checkboxProps}
              sortable={sortable}
              resolveData={resolveData}
              {...(expanded && {
                expanded,
              })}
              minRows={minRows}
              style={style}
            />
          </Grid.Column>
        </Grid>
      );
    } else if (checkboxed) {
      return (
        <Grid>
          {renderExportFile(exportTable, visibleColumns)}
          {renderVisibleColumns(
            visibleColumns,
            columnsSelected,
            handleToggleColumn,
            columns
          )}
          <Grid.Column width={16}>
            {/* 
  // @ts-ignore */}
            <CheckboxTable
              ref={(r: any) => (this.checkboxTable = r)}
              data={this.formatDataCheck(data)}
              columns={columns}
              defaultSorted={defaultSorted}
              SubComponent={SubComponent}
              filterable={filterable}
              defaultPageSize={
                !showPagination && showAllData ? data.length : defaultPageSize
              }
              noDataText={noDataText}
              className={`-striped -highlight ${className}`}
              showPagination={showPagination}
              showPageJump={showPageJump}
              previousText={"Anterior"}
              nextText={"Próximo"}
              pageText={"Página"}
              ofText={"de"}
              rowsText={"linhas"}
              loadingText={
                <div className="ui massive active centered inline loader"></div>
              }
              loading={loading}
              sorted={sorted}
              page={page}
              onPageChange={(pageIndex: number) =>
                this.handlePageChange(pageIndex)
              }
              onSortedChange={onSortedChange}
              pageSizeOptions={pageSizeOptions}
              PaginationComponent={Pagination}
              {...checkboxProps}
              getTrProps={getTrProps}
              getTdProps={getTdProps}
              collapseOnDataChange={collapseOnDataChange}
              sortable={sortable}
              resolveData={resolveData}
              {...(expanded && {
                expanded,
              })}
              minRows={minRows}
              style={style}
            />
          </Grid.Column>
        </Grid>
      );
    } else if (serverSide) {
      return (
        <Grid>
          {renderExportFile(exportTable, visibleColumns)}
          {renderVisibleColumns(
            visibleColumns,
            columnsSelected,
            handleToggleColumn,
            columns
          )}
          <Grid.Column width={16}>
            <ReactTable
              ref={(ref: any) => (this.table = ref)}
              data={data}
              columns={columns}
              defaultSorted={defaultSorted}
              SubComponent={SubComponent}
              filterable={filterable}
              defaultPageSize={
                !showPagination && showAllData ? data.length : defaultPageSize
              }
              noDataText={noDataText}
              className={`-striped -highlight ${className}`}
              showPagination={showPagination}
              showPageJump={showPageJump}
              previousText={"Anterior"}
              nextText={"Próximo"}
              pageText={"Página"}
              ofText={"de"}
              rowsText={"linhas"}
              loadingText={
                <div className="ui massive active centered inline loader"></div>
              }
              loading={loading}
              manual={serverSide}
              pages={pages}
              onFetchData={this.fetchData.bind(this)}
              sorted={sorted}
              page={page}
              onPageChange={(pageIndex: number) =>
                this.handlePageChange(pageIndex)
              }
              onSortedChange={onSortedChange}
              pageSizeOptions={pageSizeOptions}
              PaginationComponent={Pagination}
              getTrProps={getTrProps}
              getTdProps={getTdProps}
              collapseOnDataChange={collapseOnDataChange}
              sortable={sortable}
              resolveData={resolveData}
              style={style}
            />
          </Grid.Column>
        </Grid>
      );
    } else {
      return (
        <Grid>
          {renderExportFile(exportTable, visibleColumns)}
          {renderVisibleColumns(
            visibleColumns,
            columnsSelected,
            handleToggleColumn,
            columns
          )}
          <Grid.Column width={16}>
            <ReactTable
              defaultFilterMethod={this.filterMethod}
              ref={(ref: any) => (this.table = ref)}
              data={data}
              columns={columns}
              defaultSorted={defaultSorted}
              SubComponent={SubComponent}
              filterable={filterable}
              defaultPageSize={
                !showPagination && showAllData ? data.length : defaultPageSize
              }
              noDataText={noDataText}
              className={`-striped -highlight ${className}`}
              showPagination={showPagination}
              showPageJump={showPageJump}
              previousText={"Anterior"}
              nextText={"Próximo"}
              pageText={"Página"}
              ofText={"de"}
              rowsText={"linhas"}
              loadingText={
                <div className="ui massive active centered inline loader"></div>
              }
              loading={loading}
              sorted={sorted}
              page={page}
              onPageChange={(pageIndex: number) =>
                this.handlePageChange(pageIndex)
              }
              onSortedChange={onSortedChange}
              pageSizeOptions={pageSizeOptions}
              PaginationComponent={Pagination}
              getTrProps={getTrProps}
              getTdProps={getTdProps}
              collapseOnDataChange={collapseOnDataChange}
              sortable={sortable}
              resolveData={resolveData}
              {...(expanded && {
                expanded,
              })}
              minRows={minRows}
              style={style}
            />
          </Grid.Column>
        </Grid>
      );
    }
  }
}
