import * as React from "react";
import { Table } from "./Table";
import { ContextOptions } from "../context";
import { Get, Download } from '../../helpers/fetch'
import ThemeProvider from '../theme/theme-provider'

interface AuditsContainerProps {
  context: ContextOptions;
  hideStatistics?: boolean;
}
export default class AuditsContainer extends React.Component<AuditsContainerProps, {}> {
  state = {
    rowsData: [],
    headerProps: [],
    stats: {},
    filters: [],
    sortBy: "time",
    sortDirection: "desc",
    error: "",
    isLoading: true,
    tenantId: "",
    token: "",
    searchText: ""
  };

  constructor(props) {
    super(props);

    this._textSearch = this._textSearch.bind(this);
    this._filterData = this._filterData.bind(this);
    this._removeFilter = this._removeFilter.bind(this);
    this._dataSorting = this._dataSorting.bind(this);
    this._exportCSV = this._exportCSV.bind(this);
    this._exportPDF = this._exportPDF.bind(this);
    this._deleteAudits = this._deleteAudits.bind(this);
  }

  componentDidMount() {
    this.__init();
  }

  async __init() {
    this.setState({ isLoading: true });
    console.log('getting metadata');

    const params = {
      filter: "",
      filters: [],
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    }

    await this.loadMetadata()
    await this.loadAudits(params)
    await this.loadStats()

    this.setState({ isLoading: false })
  }

  private async loadStats() {
    console.log('getting audits stats');
    const params = {
      filter: "",
      filters: [],
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    }

    const paramsToSend = { ...params, ...params.filters }
    delete paramsToSend.filters


    try {
      const stats = await Get(this.props.context, '/audits/stats', paramsToSend);
      console.log('got audits stats - ', stats)
      this.setState({ stats })
    } catch (e) {
      console.error('failed to load stats - ', e)
    }
  }

  private async loadMetadata() {
    try {
      const params = { entityName: "audits" }
      const metaData = await Get(this.props.context, `/metadata`, params);
      const headerProps = metaData.rows[0].properties;
      this.setState({
        headerProps,
      });
    } catch (e) {
      console.error('failed to load metadata - ', e)
    }
  }

  private async loadAudits(params) {
    const paramsToSend = { ...params, ...params.filters }
    delete paramsToSend.filters

    console.log('getting audits');
    try {
      const rows = await Get(this.props.context, '/audits', paramsToSend)
      console.log('got audits - ', rows)
      let rowsData = rows.data;
      this.setState({ rowsData })
    } catch (e) {
      console.error('failed to load audits - ', e)
    }
  }

  private async exportAudits(params, format: string) {
    const paramsToSend = { ...params, ...params.filters }
    delete paramsToSend.filters

    console.log('getting audits');
    try {
      const body = { properties: this.state.headerProps };
      const data = await Download(this.props.context, `/audits/export/${format}`, body, paramsToSend)
      const fileURL = URL.createObjectURL(data);
      let tempLink = document.createElement("a");
      tempLink.href = fileURL;
      tempLink.setAttribute("download", `audits.${format}`);
      tempLink.click();
    } catch (e) {
      console.error('failed to export audits - ', e)
    }
  }

  private async _textSearch(term) {
    this.setState({ isLoading: true, searchText: term });
    console.log("searching...");
    await this.loadAudits({
      filter: term,
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    });
    this.setState({ isLoading: false });
  }

  private async _filterData(filter) {
    const allFilters = this.state.filters;
    const filterIndex = allFilters.findIndex(item => item.key == filter.key);
    let updatedFilters;
    if (filterIndex >= 0) {
      allFilters[filterIndex] = filter;
      updatedFilters = allFilters;
    } else {
      updatedFilters = [...allFilters, filter];
    }
    let filterObj = {};
    updatedFilters.map(filter => (filterObj[filter.key] = filter.value));
    this.setState({ isLoading: true, filters: updatedFilters });

    console.log("filtering...");
    await this.loadAudits({
      filter: this.state.searchText,
      filters: filterObj,
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    });

    this.setState({ isLoading: false });
  }

  private async _removeFilter(removedFilter) {
    const allFilters = this.state.filters;
    const removedFilterIndex = allFilters.findIndex(
      item => item.key == removedFilter.key
    );
    let updatedFilters;
    if (removedFilterIndex > -1) {
      allFilters.splice(removedFilterIndex, 1);
    }
    updatedFilters = allFilters;
    let filterObj = {};
    updatedFilters.map(filter => (filterObj[filter.key] = filter.value));
    this.setState({ isLoading: true, filters: updatedFilters });

    console.log("filtering...");
    await this.loadAudits({
      filter: this.state.searchText,
      filters: filterObj,
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    });

    this.setState({
      isLoading: false
    });
  }

  private async _dataSorting(colName, direction) {
    const switcher = { asc: true, desc: false };
    let directionIdentifier;
    if (switcher[direction]) {
      directionIdentifier = "desc";
    } else {
      directionIdentifier = "asc";
    }
    this.setState({
      isLoading: true,
      sortBy: colName,
      sortDirection: directionIdentifier
    });
    let filterObj = {};
    this.state.filters.map(filter => (filterObj[filter.key] = filter.value));

    await this.loadAudits({
      filter: this.state.searchText,
      filters: filterObj,
      sortBy: colName,
      sortDirection: directionIdentifier,
      offset: 0,
      count: 50
    });

    this.setState({
      isLoading: false
    });
  }

  private async _exportCSV() {
    await this.exportAudits({
      filter: this.state.searchText,
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    }, 'csv')
  }

  private async _exportPDF() {
    await this.exportAudits({
      filter: this.state.searchText,
      sortBy: this.state.sortBy,
      sortDirection: this.state.sortDirection,
      offset: 0,
      count: 50
    }, 'pdf')
  }

  private async _deleteAudits() {
    // this.setState({ isLoading: false });
    // const res = await fetch(
    //   `${baseURL}/audits?tenantId=${this.props.tenantId}`,
    //   {
    //     method: "delete",
    //     headers: {
    //       "Authorization": "Bearer " + this.state.token
    //     }
    //   }
    // );

    // const json = await res.json();
    // await this.loadAudits({
    //   tenantId: this.props.tenantId,
    //   filter: "",
    //   filters: [],
    //   sortBy: this.state.sortBy,
    //   sortDirection: this.state.sortDirection,
    //   offset: 0,
    //   count: 50
    // });
  }

  render() {
    const {
      headerProps,
      rowsData,
      isLoading,
      error,
      filters,
      stats
    } = this.state;
    if (headerProps && headerProps.length > 0) {
      return (
        <ThemeProvider context={this.props.context}>
          <Table
            rowsData={rowsData}
            headerProps={headerProps}
            textSearch={this._textSearch}
            filterData={this._filterData}
            removeFilter={this._removeFilter}
            isLoading={isLoading}
            filters={filters}
            sortBy={this.state.sortBy}
            sortDirection={this.state.sortDirection}
            handleSorting={this._dataSorting}
            exportCSV={this._exportCSV}
            exportPDF={this._exportPDF}
            deleteAudits={this._deleteAudits}
            stats={stats}
            hideStatistics={this.props.hideStatistics}
          />
        </ThemeProvider>
      );
    }
    if (isLoading) {
      return <div style={{ textAlign: "center" }}>Loading audits...</div>;
    }
    if (error) {
      return <div>{error}</div>;
    }
    return <div>No data was found!</div>;
  }
}
