import * as React from 'react'
import UsersTable from './users-table'
import UsersToolbar, { TeamInvitationMode } from './users-toolbar'
import UsersStatistics from './users-statistics'
import { Divider } from 'semantic-ui-react'
import { Post, Put, Delete, Get } from '../../helpers/fetch'
import { ContextOptions } from '../context'
import ThemeProvider from '../theme/theme-provider';

export interface TeamProps {
  invitationMode: TeamInvitationMode;
  context: ContextOptions;
  hideStatistics?: boolean;
}

export default class TeamContainer extends React.Component<TeamProps, {}> {
  public state = {
    items: [],
    roles: [],
    loading: false,
    searchFilter: '',
    totalPages: 0,
    pageSize: 10,
    pageOffset: 0,
    totalItems: 0,
    addedThisWeek: 0,
  }

  onInviteAdmin = async (admin) => {
    console.log('got request to invite admin - ', admin)
    try {
      const data = admin
      const { item } = await Post(this.props.context, `/team`, data);
      console.log('got added item - ', item);
      if (!item.roleIds) { item.roleIds = []; }
      // And push it to the list
      const { items } = this.state;
      this.setState({
        items: [item, ...items]
      });
    } catch (e) {
      // console.error('failed to load metadata - ', e)
    } finally {
      this.loadStats();
    }
  }

  private searchUsers = async (filter) => {
    this.setState({ searchFilter: filter, items: [], pageOffset: 0 })
    this.loadItems()
  }

  private editUser = async (item) => {
    console.log('got request to edit admin - ', item.email)
    try {
      const { id } = item
      const params = { id }
      this.replaceItem(item)
      const editedItem = await Put(this.props.context, `/team`, item, params);
      this.replaceItem(editedItem)
      console.log('got response for editing item - ', editedItem);
    } catch (e) {
      // console.error('failed to load metadata - ', e)
    }
  }

  private replaceItem = (item) => {
    const { items } = this.state;
    const foundItemIndex = items.findIndex((element) => {
      return element.id === item.id
    });

    if (foundItemIndex >= 0) {
      items[foundItemIndex] = item;
      this.setState({ items });
    }
  }

  private deleteUser = async (itemToDelete) => {
    console.log('got request to delete admin - ', itemToDelete.email)
    try {
      const { id } = itemToDelete
      const params = { id };
      const response = await Delete(this.props.context, `/team`, params)
      console.log('got response for deleting item added ite - ', response);
      // Find the deleted item 
      const { items } = this.state;
      var reduced = items.filter(item => {
        return item.id != id;
      })
      this.setState({ items: reduced })
    } catch (e) {
      // console.error('failed to load metadata - ', e)
    } finally {
      this.loadStats();
    }
  }

  async componentDidMount() {
    await this.getAvailableRoles();
    this.loadItems();
    this.loadStats();
  }

  private async loadStats() {
    try {
      const stats = await Get(this.props.context, "/team/stats");
      console.log('got stats - ', stats);
      const { totalItems, addedThisWeek } = stats;
      this.setState({ totalItems, addedThisWeek });

    } catch (e) {
      console.error('failed to load metadata - ', e)
    }
  }

  private async getAvailableRoles() {
    this.setState({ loading: true })
    try {
      const roles = await Get(this.props.context, "/team/roles");
      console.log('got roles - ', roles);
      this.setState({ roles })
    } catch (e) {
      console.error('failed to load roles - ', e)
    } finally {
      this.setState({ loading: false })
    }
  }

  private async loadItems() {
    this.setState({ loading: true })
    const { pageOffset, pageSize, searchFilter } = this.state;
    try {
      let query = `/team?pageOffset=${pageOffset}&pageSize=${pageSize}`;
      if (searchFilter) { query += `&searchFilter=${searchFilter}` }

      const response = await Get(this.props.context, query);
      const { items, totalPages } = response
      const currentItems = this.state.items;
      currentItems.push(...items);
      this.setState({ items: currentItems, totalPages })
    } catch (e) {
      console.error('failed to load metadata - ', e)
    } finally {
      this.setState({ loading: false })
    }
  }

  private async fetchMoreItems() {
    console.log('going to fetch more items');
    const { pageOffset } = this.state;
    this.setState({ pageOffset: pageOffset + 1 })
    this.loadItems();
  }

  render() {
    const { hideStatistics, context } = this.props;
    return (
      <ThemeProvider context={context}>
        <div>
          {!hideStatistics && <div>
            <UsersStatistics
              totalItems={this.state.totalItems}
              addedThisWeek={this.state.addedThisWeek} />
            <Divider />
          </div>}
          <UsersToolbar
            roles={this.state.roles}
            invitationMode={this.props.invitationMode}
            onInviteAdmin={this.onInviteAdmin}
            onSearchUsers={this.searchUsers} />

          <UsersTable
            items={this.state.items}
            roles={this.state.roles}
            totalPages={this.state.totalPages}
            loading={this.state.loading}
            onDeleteUser={this.deleteUser}
            onEditUser={this.editUser}
            getNextPage={() => this.fetchMoreItems()} />
        </div>
      </ThemeProvider>
    )
  }
}