import { LockOpenIcon, PlusIcon, SupportIcon, TrashIcon } from '@heroicons/react/solid';
import { Fragment, useEffect, useState } from 'react';
import { NavLink } from 'react-router-dom';

import { useGetUsers } from '@/api/admin/users';
import type { UUID } from '@/api/definitions';
import { Transition } from '@/components/elements/transitions';
import { Button } from '@/components/elements/button/index';
import Checkbox from '@/components/elements/inputs/Checkbox';
import InputField from '@/components/elements/inputs/InputField';
import UserTableRow from '@/components/admin/users/UserTableRow';
import TFootPaginated from '@/components/elements/table/TFootPaginated';
import type { User } from '@definitions/admin';
import extractSearchFilters from '@/helpers/extractSearchFilters';
import useDebouncedState from '@/plugins/useDebouncedState';
import { Shape } from '@/components/elements/button/types';

const filters = ['id', 'uuid', 'external_id', 'username', 'email'] as const;

function UsersContainer() {
    const [search, setSearch] = useDebouncedState('', 500);
    const [selected, setSelected] = useState<UUID[]>([]);
    const { data: users } = useGetUsers(
        extractSearchFilters(search, filters, {
            splitUnmatched: true,
            returnUnmatched: true,
        }),
    );

    useEffect(() => {
        document.title = 'Admin | Users';
    }, []);

    const onRowChange = (user: User, checked: boolean) => {
        setSelected(state => {
            return checked ? [...state, user.uuid] : selected.filter(uuid => uuid !== user.uuid);
        });
    };

    const selectAllChecked = users && users.items.length > 0 && selected.length > 0;
    const onSelectAll = () =>
        setSelected(state => (state.length > 0 ? [] : users?.items.map(({ uuid }) => uuid) || []));

    return (
        <div>
            <div className="mb-4 flex justify-end">
                <NavLink to="/admin/users/new">
                    <Button className="shadow focus:ring-offset-2 focus:ring-offset-neutral-800">
                        Add User <PlusIcon className="ml-2 h-5 w-5" />
                    </Button>
                </NavLink>
            </div>

            <div className="relative flex items-center rounded-t bg-neutral-700 px-4 py-2">
                <div className="mr-6">
                    <Checkbox
                        checked={selectAllChecked}
                        disabled={!users?.items.length}
                        indeterminate={selected.length !== users?.items.length}
                        onChange={onSelectAll}
                    />
                </div>
                <div className="flex-1">
                    <InputField
                        type="text"
                        name="filter"
                        placeholder="Begin typing to filter..."
                        className="w-56 focus:w-96"
                        onChange={e => setSearch(e.currentTarget.value)}
                    />
                </div>
                <Transition.Fade as={Fragment} show={selected.length > 0} duration="duration-75">
                    <div className="absolute top-0 left-0 flex h-full w-full items-center justify-end space-x-4 rounded-t bg-neutral-700 px-4">
                        <div className="flex-1">
                            <Checkbox
                                checked={selectAllChecked}
                                indeterminate={selected.length !== users?.items.length}
                                onChange={onSelectAll}
                            />
                        </div>
                        <Button.Text shape={Shape.IconSquare}>
                            <SupportIcon className="h-4 w-4" />
                        </Button.Text>
                        <Button.Text shape={Shape.IconSquare}>
                            <LockOpenIcon className="h-4 w-4" />
                        </Button.Text>
                        <Button.Text shape={Shape.IconSquare}>
                            <TrashIcon className="h-4 w-4" />
                        </Button.Text>
                    </div>
                </Transition.Fade>
            </div>
            <table className="min-w-full rounded bg-neutral-700">
                <thead className="bg-neutral-900">
                    <tr>
                        <th scope="col" className="w-8" />
                        <th scope="col" className="w-full px-6 py-2 text-left">
                            Email
                        </th>
                        <th scope="col" />
                        <th scope="col" />
                    </tr>
                </thead>
                <tbody>
                    {users?.items.map(user => (
                        <UserTableRow
                            key={user.uuid}
                            user={user}
                            selected={selected.includes(user.uuid)}
                            onRowChange={onRowChange}
                        />
                    ))}
                </tbody>
                {users ? <TFootPaginated span={4} pagination={users.pagination} /> : null}
            </table>
        </div>
    );
}

export default UsersContainer;