import type { FC } from 'react';
import React, { useCallback, useState } from 'react';
import { Button, GridTable } from '@theorchard/suite-components';
import { useToast } from '@theorchard/suite-frontend';
import { Illustration } from '@theorchard/suite-icons';
import {
    PhysicalDeliveryOrderBy,
    PhysicalDeliveryOrderStatus,
} from 'src/data/globalTypes';
import { useUpdatePhysicalDeliveryOrdersMutation } from 'src/data/mutations/updatePhysicalDeliveryOrders/updatePhysicalDeliveryOrders';
import {
    DateCell,
    TextCell,
    JobStatusCell,
    OrderIdLinkCell,
    DownloadFileCell,
    DeliveryFulfilledDateCell,
    DeliveryFulfilledTextCell,
} from 'src/tableCells';
import {
    recordCancelDeliveryClicked,
    recordCompleteDeliveryClicked,
} from 'src/utils/segment';
import { TRANSLATION_KEY } from '../constants';
import type { DeliveryOrders } from 'src/data/queries';
import type { RowInstance, SortBy } from 'src/types';

export const CLASSNAME = 'OrdersTable';

interface Props {
    orders: DeliveryOrders[];
    totalOrders?: number;
    loading: boolean;
    onClearFilters: () => void;
    filtersApplied: boolean;
    onSort: (sortBy: SortBy[]) => void;
    sortBy: SortBy;
    page: number;
    pageSize: number;
    handlePageChange: (page: number) => void;
    handlePageSizeChange: (pageSize: number) => void;
}

const OrdersTable: FC<Props> = ({
    orders,
    totalOrders,
    loading,
    onClearFilters,
    filtersApplied,
    onSort,
    sortBy,
    page,
    pageSize,
    handlePageChange,
    handlePageSizeChange,
}) => {
    const [selectedRows, setSelectedRows] = useState<string[]>([]);
    const addToast = useToast();
    const { updateOrders } = useUpdatePhysicalDeliveryOrdersMutation();

    const handleCompleteClick = useCallback(async () => {
        await updateOrders({
            variables: {
                input: selectedRows.map(id => ({
                    id,
                    status: PhysicalDeliveryOrderStatus.COMPLETE,
                })),
            },
        });
        addToast(
            $t(`${TRANSLATION_KEY}.orderActions.complete`, {
                count: selectedRows.length ?? '-',
            })
        );
        recordCompleteDeliveryClicked();
        setSelectedRows([]);
    }, [selectedRows, addToast, updateOrders]);

    const handleCancelClick = useCallback(async () => {
        await updateOrders({
            variables: {
                input: selectedRows.map(id => ({
                    id,
                    status: PhysicalDeliveryOrderStatus.CANCELLED,
                })),
            },
        });
        addToast(
            $t(`${TRANSLATION_KEY}.orderActions.cancelled`, {
                count: selectedRows.length ?? '-',
            })
        );
        recordCancelDeliveryClicked();
        setSelectedRows([]);
    }, [selectedRows, addToast, updateOrders]);

    const countSummary = () => (
        <div className={`${CLASSNAME}-itemsSelected`}>
            {selectedRows.length > 0 &&
                $t(`${TRANSLATION_KEY}.items.selected`, {
                    selected: selectedRows.length,
                    totalCount: totalOrders ?? '-',
                })}
        </div>
    );

    const header = (
        <>
            {countSummary()}
            {selectedRows.length > 0 && (
                <div className={`${CLASSNAME}-deliveryButtons`}>
                    <Button
                        className={`${CLASSNAME}-completeDelivery`}
                        onClick={handleCompleteClick}
                    >
                        {$t(
                            `${TRANSLATION_KEY}.tableHeaderActions.completeDelivery`
                        )}
                    </Button>
                    <Button
                        className={`${CLASSNAME}-cancelDelivery`}
                        onClick={handleCancelClick}
                    >
                        {$t(
                            `${TRANSLATION_KEY}.tableHeaderActions.cancelDelivery`
                        )}
                    </Button>
                </div>
            )}
        </>
    );

    const handleRowSelection = (rows: string[]) => {
        const readyForDeliveryOrders = orders
            .map(item =>
                item.orderDeliveryStatus ===
                PhysicalDeliveryOrderStatus.READY_FOR_DELIVERY
                    ? item.orderId
                    : ''
            )
            .filter(item => item);
        setSelectedRows(
            rows.filter(item => readyForDeliveryOrders.includes(item))
        );
    };

    return (
        <GridTable
            className={CLASSNAME}
            data={orders}
            loading={loading}
            bordered
            emptyStateIcon={() => <Illustration name="noResults" />}
            emptyStateTitle={$t(`${TRANSLATION_KEY}.noOrders`)}
            rowKey={(row: DeliveryOrders) => row.orderId}
            selectable
            rowSelectEnabled={(row: RowInstance<DeliveryOrders>) =>
                row.data.orderDeliveryStatus ===
                PhysicalDeliveryOrderStatus.READY_FOR_DELIVERY
            }
            selectedRowKeys={selectedRows}
            onSelectedRowsChanged={handleRowSelection}
            onSort={onSort}
            sortBy={sortBy}
            headerRight={header}
            paginated
            totalCount={totalOrders}
            page={page}
            pageSize={pageSize}
            onPageChange={handlePageChange}
            onPageSizeChange={handlePageSizeChange}
            onClearFilters={onClearFilters}
            showClearFilters={filtersApplied}
            showUpdateIndicator
        >
            <GridTable.Column
                className={`${CLASSNAME}-cell-orderId`}
                name="orderId"
                title={$t(`${TRANSLATION_KEY}.orderId`)}
                fixed
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-store`}
                name="store"
                title={$t(`${TRANSLATION_KEY}.serviceName`)}
                Cell={TextCell}
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-products`}
                name="totalProducts"
                title={$t(`${TRANSLATION_KEY}.numberProducts`)}
                Cell={OrderIdLinkCell}
                maxWidth="90px"
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-type`}
                name="deliveryType"
                title={$t(`${TRANSLATION_KEY}.type`)}
                maxWidth="90px"
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-createdAt`}
                name="createdAt"
                title={$t(`${TRANSLATION_KEY}.createdAt`)}
                Cell={DateCell}
                sortable
                sortKey={PhysicalDeliveryOrderBy.CREATED_AT}
                defaultSortDirection="desc"
                maxWidth="110px"
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-createdBy`}
                name="createdBy"
                title={$t(`${TRANSLATION_KEY}.createdBy`)}
                Cell={TextCell}
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-status`}
                name="orderDeliveryStatus"
                title={$t(`${TRANSLATION_KEY}.status`)}
                Cell={JobStatusCell}
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-outputFile`}
                name="outputFile"
                title={$t(`${TRANSLATION_KEY}.file`)}
                Cell={DownloadFileCell}
                maxWidth="110px"
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-lastUpdated`}
                name="lastUpdated"
                title={$t(`${TRANSLATION_KEY}.lastUpdatedAt`)}
                Cell={DeliveryFulfilledDateCell}
                sortable
                sortKey={PhysicalDeliveryOrderBy.LAST_UPDATED}
                defaultSortDirection="desc"
                maxWidth="110px"
            />
            <GridTable.Column
                className={`${CLASSNAME}-cell-lastUpdated`}
                name="lastUpdatedBy"
                title={$t(`${TRANSLATION_KEY}.lastUpdatedBy`)}
                Cell={DeliveryFulfilledTextCell}
                maxWidth="110px"
            />
        </GridTable>
    );
};

export default OrdersTable;
