import type { FC } from 'react';
import React, { useCallback, useState } from 'react';
import { Page } from '@theorchard/suite-frontend';
import { useGetPhysicalDeliveryProducts } from 'src/data/queries';
import Filters from 'src/pages/monitorPage/components/filters';
import { ensureSortByType } from 'src/pages/monitorPage/utils';
import { ensureSortDirectionType } from 'src/utils';
import { recordPhysicalProductsSortingByKey } from 'src/utils/segment';
import {
    DEFAULT_SORT_DIR_MONITOR_PAGE,
    DEFAULT_SORT_FIELD_MONITOR_PAGE,
    PAGE_SIZE,
} from '../constants';
import ProductsTable from './productsTable';
import type { MonitorRouteParams } from '../types';
import type { SortBy, SortDirection } from 'src/types';
import type { ParamValue } from 'src/utils';
import type { SetParamsCallback } from 'src/utils/routes';

export const CLASSNAME = 'Products';

interface Props {
    params: MonitorRouteParams;
    handleParams: SetParamsCallback;
}

const Products: FC<Props> = ({ params, handleParams }) => {
    const [page, setPage] = useState(0);
    const [pageSize, setPageSize] = useState(PAGE_SIZE);
    const { selectedOrder, selectedStore, orderBy, orderDir } = params;

    const { data, loading, error } = useGetPhysicalDeliveryProducts({
        limit: pageSize,
        orderBy: ensureSortByType(orderBy),
        orderDir: ensureSortDirectionType(orderDir),
        storeIds: selectedStore ? [selectedStore] : null,
        orderIds: selectedOrder ? [selectedOrder] : null,
        offset: page * pageSize,
    });

    const sortingApplied =
        orderDir !== DEFAULT_SORT_FIELD_MONITOR_PAGE ||
        orderBy !== DEFAULT_SORT_DIR_MONITOR_PAGE;

    const handleSort = (sortBy: SortBy[]) => {
        recordPhysicalProductsSortingByKey(sortBy[0].key, sortBy[0].direction);
        handleParams({ orderBy: sortBy[0].key, orderDir: sortBy[0].direction });
    };

    const filtersApplied = !!selectedOrder;

    const handleClearFilters = useCallback(() => {
        setPage(0);
        handleParams({
            orderId: undefined,
            tab: 'physical',
            // store: undefined, commented out for now as we have the store filter permanently set to show Above Board only
        });
    }, [handleParams]);

    const handleFiltersChange = useCallback(
        (filters: string | Record<string, ParamValue | undefined>) => {
            // reset pagination when filters change
            setPage(0);
            handleParams(filters);
        },
        [handleParams]
    );

    const isLoading = loading && (filtersApplied || sortingApplied);
    const productsData =
        filtersApplied && !isLoading ? data?.products ?? [] : [];
    const totalProducts = filtersApplied && !isLoading ? data?.totalCount : 0;

    return (
        <div className={CLASSNAME}>
            <Page.View loading={isLoading} error={error} hasData>
                <Filters setParams={handleFiltersChange} params={params} />
                <ProductsTable
                    products={productsData}
                    totalProducts={totalProducts}
                    loading={isLoading}
                    onClearFilters={handleClearFilters}
                    filtersApplied={filtersApplied}
                    onSort={handleSort}
                    sortBy={{
                        key: orderBy,
                        direction: orderDir as SortDirection,
                    }}
                    page={page}
                    pageSize={pageSize}
                    handlePageChange={setPage}
                    handlePageSizeChange={setPageSize}
                />
            </Page.View>
        </div>
    );
};

export default Products;
