import React, {
    useEffect,
    useMemo,
    useState,
    useRef,
    type Dispatch,
    type SetStateAction,
} from 'react';
import { Alert, GridTable, Section } from '@theorchard/suite-components';
import { Illustration } from '@theorchard/suite-icons';
import { cloneDeep, debounce } from 'lodash-es';
import { useReferenceSapProfitCenters } from 'src/apollo/queries/reference-sap-profit-center';
import { PROFIT_CENTER_ERROR_MESSAGE } from 'src/apollo/type-constants/reference-sap-profit-center';
import { ReferenceSapProfitCentersFilters } from 'src/components/reference-sap-profit-centers-list/reference-sap-profit-centers-filters';
import { ReferenceSapProfitCentersListColumns } from 'src/components/reference-sap-profit-centers-list/reference-sap-profit-centers-list-columns';
import { ReferenceSapProfitCenterForm } from 'src/components/reference-sap-profit-center-create/reference-sap-profit-center-form';
import { EditableDisplayNameProvider } from 'src/components/reference-sap-profit-center-edit/editable-display-name-context';
import { EditMappedSigningEntities } from 'src/components/reference-sap-profit-center-edit/edit-mapped-signing-entities';
import {
    ADJUST_FILTERS_MSG,
    DEFAULT_ITEMS_PER_PAGE,
    DEFAULT_NO_RESULTS_MSG,
} from 'src/constants';
import {
    ReferenceSapProfitCenterSortOptions,
    SortOrder,
} from 'src/apollo/definitions/globalTypes';
import type { ReferenceSapProfitCenterFilter } from 'src/types/reference-sap-profit-center';

interface ReferenceSapProfitCentersListPropTypes {
    isSidecarOpen: boolean;
    setIsSidecarOpen: Dispatch<SetStateAction<boolean>>;
}

export const ReferenceSapProfitCentersList: React.FC<
    ReferenceSapProfitCentersListPropTypes
> = ({ isSidecarOpen, setIsSidecarOpen }) => {
    const [pageSize, setPageSize] = useState<number>(DEFAULT_ITEMS_PER_PAGE);
    const [page, setPage] = useState<number>(0);
    const [isEditSidecarOpen, setIsEditSidecarOpen] = useState<boolean>(false);
    const [selectedProfitCenter, setSelectedProfitCenter] = useState<any>(null);

    const [searchTerm, setSearchTerm] = useState<string | undefined>('');

    const [requestParams, setRequestParams] =
        useState<ReferenceSapProfitCenterFilter>({
            limit: DEFAULT_ITEMS_PER_PAGE,
            offset: 0,
            sortBy: ReferenceSapProfitCenterSortOptions.DISPLAY_NAME,
            sortOrder: SortOrder.ASC,
        });

    const hasFilterApplied = () =>
        Boolean(
            requestParams?.orphan ||
            searchTerm?.trim() ||
            requestParams?.signingEntityIds?.length
        );

    useEffect(() => {
        setRequestParams({
            ...requestParams,
            limit: pageSize,
            offset: page * pageSize,
        });
    }, [page, pageSize]);

    useEffect(() => {
        setPage(0);
        setRequestParams({
            ...requestParams,
            offset: 0,
        });
    }, [searchTerm]);

    const { data, error, loading, refetch } = useReferenceSapProfitCenters({
        limit: requestParams.limit,
        offset: requestParams.offset,
        sortBy: requestParams.sortBy,
        sortOrder: requestParams.sortOrder,
        filters: {
            orphan: requestParams.orphan || null,
            searchTerm: searchTerm?.trim() || null,
            signingEntityIds: requestParams?.signingEntityIds?.length
                ? requestParams?.signingEntityIds
                : null,
        },
    });

    const debouncedRefetch = useRef(
        debounce((p, size) => {
            refetch({ limit: size, offset: p * size });
        }, 200)
    ).current;

    const columnDefs = useMemo(
        () => ReferenceSapProfitCentersListColumns(),
        []
    );

    const editableDisplayNameContextValue = useMemo(
        () => ({ debouncedRefetch, page, pageSize }),
        [debouncedRefetch, page, pageSize]
    );

    const changeHandler = (
        fieldName: string,
        value: string | boolean | undefined | null
    ) => {
        const key = fieldName as keyof ReferenceSapProfitCenterFilter;
        if (value === null || value === undefined || value === '') {
            const params = cloneDeep(requestParams);
            delete params[key];
            setRequestParams({ ...params, offset: 0 });
        } else {
            setRequestParams({
                ...requestParams,
                offset: 0,
                [key]: value,
            });
        }

        setPage(0);
    };

    const onClearFilters = () => {
        setRequestParams({
            limit: DEFAULT_ITEMS_PER_PAGE,
            offset: 0,
            sortBy: ReferenceSapProfitCenterSortOptions.DISPLAY_NAME,
            sortOrder: SortOrder.ASC,
        });
        setPage(0);
        setSearchTerm('');
    };

    return (
        <div
            className="ReferenceSapProfitCentersPageGrid"
            data-testid="ReferenceSapProfitCenters"
        >
            <Section>
                <Section.Body>
                    {error && (
                        <Alert
                            variant="error"
                            text={PROFIT_CENTER_ERROR_MESSAGE}
                            className="error-alert"
                        />
                    )}
                    <ReferenceSapProfitCentersFilters
                        changeHandler={changeHandler}
                        requestParams={requestParams}
                        searchTerm={searchTerm}
                        setSearchTerm={setSearchTerm}
                    />
                    <EditableDisplayNameProvider
                        value={editableDisplayNameContextValue}
                    >
                        <GridTable
                            bordered
                            className="ReferenceSapProfitCenterTable"
                            columnDefs={columnDefs}
                            data={
                                data?.abacusReferenceSapProfitCenterList
                                    ?.items || []
                            }
                            defaultColumnDefs={{ headerTextWrap: 'nowrap' }}
                            emptyStateTitle={DEFAULT_NO_RESULTS_MSG}
                            emptyStateIcon={<Illustration name="noResults" />}
                            emptyStateBody={
                                hasFilterApplied() ? ADJUST_FILTERS_MSG : ''
                            }
                            loading={loading}
                            loadingRows={DEFAULT_ITEMS_PER_PAGE}
                            page={page}
                            pageSize={pageSize}
                            paginated
                            onClearFilters={onClearFilters}
                            onPageChange={setPage}
                            onPageSizeChange={setPageSize}
                            rowActions={{
                                edit: (row: any) => {
                                    setIsEditSidecarOpen(true);
                                    setSelectedProfitCenter(row);
                                },
                            }}
                            rowKey="referenceSapProfitCenterId"
                            showClearFilters={hasFilterApplied()}
                            showUpdateIndicator
                            stickyHeader
                            testId="ReferenceSapProfitCenterGridTable"
                            totalCount={
                                data?.abacusReferenceSapProfitCenterList
                                    ?.totalCount || 0
                            }
                            variant="zebra"
                        />
                    </EditableDisplayNameProvider>
                    <ReferenceSapProfitCenterForm
                        isSidecarOpen={isSidecarOpen}
                        setIsSidecarOpen={setIsSidecarOpen}
                        setPage={setPage}
                    />
                    <EditMappedSigningEntities
                        isSidecarOpen={isEditSidecarOpen}
                        profitCenter={selectedProfitCenter}
                        setIsSidecarOpen={setIsEditSidecarOpen}
                    />
                </Section.Body>
            </Section>
        </div>
    );
};

export default ReferenceSapProfitCentersList;
