import type { Dispatch, JSX, SetStateAction } from 'react';
import React, { useEffect, useState } from 'react';
import { useReactiveVar } from '@apollo/client';
import { Link, useParams } from 'react-router-dom';
import { usePendingPaymentGroupPaymentAccounts } from 'src/apollo/queries/payment-group-payment-account';
import paginationStateVar from 'src/apollo/reactive-vars/tables-state';
import TableWithSortableHeader from 'src/components/shared/table-with-sortable-header';
import {
    DEFAULT_ITEMS_PER_PAGE,
    NO_PENDING_PAYMENT_RESULTS,
} from 'src/constants';
import usePagination, { type PaginationPropType } from 'src/hooks/pagination';
import {
    getPaymentGroupPaymentDetail,
    selectAccountingTab,
} from 'src/urls/frontend-royalties';
import type { AbacusPaymentGroupPaymentAccountsItem } from 'src/types/payment-group';

export interface PaymentGroupPendingPaymentPropTypes {
    pendingPaymentCount: number;
    updatePendingPaymentCount: Dispatch<SetStateAction<number>>;
}

export default function PaymentGroupPendingPayment({
    pendingPaymentCount,
    updatePendingPaymentCount,
}: PaymentGroupPendingPaymentPropTypes) {
    const HEADER = [
        { label: 'Name', value: 'account_name', sortable: true },
        { label: 'Payment Link', value: 'prior_payment_name', sortable: false },
    ];
    const itemsPerPage = DEFAULT_ITEMS_PER_PAGE;
    const { paymentGroupPaymentId } = useParams<{
        paymentGroupPaymentId: string;
    }>();
    const [accountList, setAccountList] = useState<
        { id: string; cols: (JSX.Element | null)[] }[]
    >([]);
    const [requestParams, setRequestParams] = useState({
        limit: itemsPerPage,
        offset: 0,
        sortBy: 'account_name',
        sortOrder: 'asc' as 'asc' | 'desc',
        paymentGroupPaymentId,
    });
    const paginationState = useReactiveVar(paginationStateVar);
    const { data, loading: isLoading } =
        usePendingPaymentGroupPaymentAccounts(requestParams);

    const formatAccountList = (
        items: AbacusPaymentGroupPaymentAccountsItem[]
    ) => {
        const accounts = items.map(item => {
            const {
                // @ts-expect-error: ignoring nulls
                account: { accountId, accountName },
                paymentGroupPaymentAccountId,
                // @ts-expect-error: The gql type doesn't define this field, maybe it's old and not used anymore?
                priorPaymentGroupPayment,
            } = item;

            const accountLink = (
                <Link
                    key={`account-link-${accountId}`}
                    to={selectAccountingTab(accountId)}
                >
                    {accountName}
                </Link>
            );
            const paymentLink = priorPaymentGroupPayment ? (
                <Link
                    key={`payment-link-${paymentGroupPaymentAccountId}`}
                    to={`${getPaymentGroupPaymentDetail(
                        priorPaymentGroupPayment?.paymentGroupPaymentId
                    )}`}
                >
                    {priorPaymentGroupPayment?.paymentName}
                </Link>
            ) : null;
            return {
                id: paymentGroupPaymentAccountId ?? '',
                cols: [accountLink, paymentLink],
            };
        });
        setAccountList(accounts);
    };

    const fetchMoreWrapper: PaginationPropType['fetchMore'] = ({
        variables: { limit, offset },
    }) => {
        const variables = { ...requestParams, limit, offset };
        setRequestParams(variables);
    };

    const { renderPagination } = usePagination({
        fetchMore: fetchMoreWrapper,
        totalItemCount: pendingPaymentCount,
        tableId: 'payment-group-pending-payment',
    });

    useEffect(() => {
        if (data && data.abacusPendingPaymentGroupPaymentAccounts) {
            const {
                abacusPendingPaymentGroupPaymentAccounts: { items, totalCount },
            } = data;

            // @ts-expect-error: ignore nulls
            formatAccountList(items);
            updatePendingPaymentCount(totalCount ?? 0);
        }
    }, [data]);

    useEffect(() => {
        if (paymentGroupPaymentId !== requestParams.paymentGroupPaymentId)
            setRequestParams({ ...requestParams, paymentGroupPaymentId });
    }, [paymentGroupPaymentId]);

    const handleSortingDirection = (sortValue: string) => {
        const { sortBy, sortOrder } = requestParams;
        let sortDirection = 'asc' as 'asc' | 'desc';

        if (sortBy === sortValue)
            sortDirection = sortOrder === 'asc' ? 'desc' : 'asc';

        paginationStateVar({
            ...paginationState,
            'payment-group-pending-payment': 1,
        });
        setRequestParams({
            ...requestParams,
            offset: 0,
            sortBy: sortValue,
            sortOrder: sortDirection,
        });
    };

    return (
        <div className="PaymentGroupDetails-pending-payment">
            <div className="PaymentGroupDetails-pending-payment-table">
                <TableWithSortableHeader
                    headers={HEADER}
                    isLoading={isLoading}
                    rows={accountList}
                    itemsPerPage={itemsPerPage}
                    onClickHandler={handleSortingDirection}
                    sortBy={requestParams.sortBy}
                    sortOrder={requestParams.sortOrder}
                    className=""
                />
                {!accountList.length && (
                    <div className="NoResultsFound">
                        {' '}
                        {NO_PENDING_PAYMENT_RESULTS}{' '}
                    </div>
                )}
            </div>
            {renderPagination()}
        </div>
    );
}
