/* eslint-disable indent,react/jsx-indent,prefer-arrow-callback */
import React, { useState, useRef, useEffect, useMemo, useCallback } from 'react';
import {
    Table,
    ScrollArea,
    Text,
    useMantineTheme,
    useComputedColorScheme,
} from '@mantine/core';

import InfinityScrollSkeleton from '@index/components/Tests/Table/InfinityScrollSkeleton';
import PagesCountAffix from '@index/components/Tests/Table/PagesCountAffix';
import ILog from '@shared/interfaces/ILog';
import { testsCreateStyle } from '@index/components/Tests/Table/testsCreateStyle';
import Rows from '@index/components/Tests/Table/Rows';
import Heads from '@index/components/Tests/Table/Heads';
import { CheckModal } from '@index/components/Tests/Table/Checks/CheckModal';
import RemoveTestsButton from '@index/components/Tests/Table/RemoveTestsButton';
import AcceptTestsButton from '@index/components/Tests/Table/AcceptTestsButton';
import { useParams } from '@hooks/useParams';

interface Props {
    infinityQuery: any
    firstPageQuery: any,
    visibleFields: any
    updateToolbar: any
    size?: string
    navbarWidth?: number
}

export default function TestsTable(
    {
        infinityQuery,
        firstPageQuery,
        visibleFields,
        updateToolbar,
        size = '100%',
        navbarWidth = 350,
    }: Props,
) {
    const { query } = useParams();
    const { data } = infinityQuery;
    const flatData = useMemo(
        () => (data ? data.pages.flat().map((x: any) => x.results).flat() : []),
        [data],
    );

    const theme = useMantineTheme();
    const colorScheme = useComputedColorScheme();
    const styles = testsCreateStyle(theme, colorScheme);
    const [selection, setSelection]: [string[], any] = useState([]);

    useEffect(function resetSelection() {
        setSelection(() => ([]));
        // eslint-disable-next-line react-hooks/exhaustive-deps
    }, [query.base_filter, query.app]);

    const scrollAreaRef = useRef(null);
    const viewportRef = useRef<HTMLDivElement>(null);
    // eslint-disable-next-line max-len
    const toggleAllRows = useCallback(() => setSelection((current: string) => (current.length === flatData.length ? [] : flatData.map((item: ILog) => item.id))), [flatData]);

    useEffect(function onSelectionUpdate() {
        updateToolbar(
            <RemoveTestsButton
                selection={selection}
                setSelection={setSelection}
                infinityQuery={infinityQuery}
            />,
            31,
        );
        updateToolbar(
            <AcceptTestsButton
                selection={selection}
                setSelection={setSelection}
                infinityQuery={infinityQuery}
                // firstPageQuery={firstPageQuery}
            />,
            32,
        );
    }, [selection.length]);

    const resetHorizontalScroll = useCallback(() => {
        if (!viewportRef.current) {
            return;
        }
        viewportRef.current.scrollLeft = 0;
        requestAnimationFrame(() => {
            if (viewportRef.current) {
                viewportRef.current.scrollLeft = 0;
            }
        });
    }, []);

    useEffect(() => {
        resetHorizontalScroll();
    }, [navbarWidth, size, visibleFields.join(','), resetHorizontalScroll]);

    return (
        <>
            <ScrollArea.Autosize
                data-test="table-scroll-area"
                ref={scrollAreaRef}
                viewportRef={viewportRef}
                mah="100vh"
                style={{ width: size }}
                pb={124}
                scrollbarSize={8}
                onBottomReached={() => {
                    if (infinityQuery.hasNextPage && !infinityQuery.isFetchingNextPage) {
                        infinityQuery.fetchNextPage();
                    }
                }}
            >

                <Table
                    style={{ width: '100%' }}
                    verticalSpacing="sm"
                    highlightOnHover
                >
                    <Table.Thead
                        style={{ zIndex: 10, ...styles.header }}
                    >
                    <Heads
                        data={data}
                        toggleAllRows={toggleAllRows}
                        selection={selection}
                        visibleFields={visibleFields}
                    />
                    </Table.Thead>

                    {
                        // eslint-disable-next-line no-nested-ternary
                        infinityQuery.isLoading
                            ? (<InfinityScrollSkeleton infinityQuery={null} visibleFields={visibleFields} scrollRootRef={viewportRef} />)
                            : infinityQuery.isError
                                ? (
                                    <Text c="red">
                                        Error:
                                        {infinityQuery.error.message}
                                    </Text>
                                )
                                : (
                                    <Table.Tbody style={styles.tableBody}>
                                    <Rows
                                        updateToolbar={updateToolbar}
                                        infinityQuery={infinityQuery}
                                        selection={selection}
                                        setSelection={setSelection}
                                        visibleFields={visibleFields}
                                    />
                                    </Table.Tbody>
                                )
                    }
                    <InfinityScrollSkeleton infinityQuery={infinityQuery} visibleFields={visibleFields} scrollRootRef={viewportRef} />
                </Table>
            </ScrollArea.Autosize>
            <PagesCountAffix
                loaded={infinityQuery.data?.pages?.length.toString()}
                total={infinityQuery.data?.pages && infinityQuery.data?.pages[0].totalPages}
                scrollAreaRef={scrollAreaRef}
            />
            <CheckModal firstPageQuery={firstPageQuery} testList={flatData} />
        </>
    );
}
