import { Group } from '@material-ui/icons';
import { createNextState } from '@reduxjs/toolkit';
import api from 'api/api';
import Page from 'components/Page';
import { User } from 'features/user/userSlice';
import MaterialTable from 'material-table';
import React, { useEffect, useState } from 'react';
import tableIcons from 'utils/tableIcons';

import EditRole from './EditRole';
import EditUsersModal from './EditUsersModal';
import renderUser from './renderUser';

export type AllUsers = Omit<User, 'loading' | 'token'>[];
export type UpdateUser = (
  user: Omit<User, 'loading' | 'token'> | Omit<User, 'loading' | 'token'>[],
) => Promise<void>;

export default function Admin() {
  const [loading, setLoading] = useState(true);
  const [users, setUsers] = useState<AllUsers>([]);
  const [usersToEdit, setUsersToEdit] = useState<AllUsers>([]);
  useEffect(() => {
    setLoading(true);
    api.getUsers().then(newUsers => {
      setUsers(newUsers);
      setLoading(false);
    });
  }, [setUsers]);
  const updateUser: UpdateUser = async user => {
    setLoading(true);
    let users = Array.isArray(user) ? user : [user];
    await Promise.all(
      users.map(({ id, ref, preferences }) =>
        api.setUserPreferences({ id, ref, preferences }),
      ),
    );
    setUsers(
      createNextState((prevUsers: AllUsers) => {
        users.forEach(({ id, preferences }) => {
          const prevUser = prevUsers.find(({ id: userId }) => id === userId);
          if (prevUser) prevUser.preferences = preferences;
        });
      }),
    );
    setLoading(false);
    return;
  };
  return (
    <Page>
      <EditUsersModal
        usersToEdit={usersToEdit}
        setUsersToEdit={setUsersToEdit}
        updateUser={updateUser}
      />
      <MaterialTable
        icons={tableIcons}
        data={users.map(row => ({ ...row }))}
        isLoading={loading}
        columns={[
          {
            field: 'profile.name',
            title: 'User',
            render: renderUser,
            editable: 'never',
          },
          {
            field: 'preferences.roles',
            title: 'Roles',
            render: ({ preferences: { roles } }) => roles.join(', '),
            editComponent: EditRole,
          },
        ]}
        editable={{
          onRowUpdate: updateUser,
        }}
        options={{
          padding: 'dense',
          selection: true,
        }}
        title="Users"
        actions={[
          {
            tooltip: 'Add/Remove Roles',
            icon: () => <Group />,
            onClick: (e, data) =>
              setUsersToEdit(Array.isArray(data) ? data : [data]),
          },
        ]}
      />
    </Page>
  );
}
