import type { FC } from 'react';
import React, { useCallback, useState } from 'react';
import { Button, GridTable, Select } from '@theorchard/suite-components';
import { useToast } from '@theorchard/suite-frontend';
import { Illustration, GlyphIcon } from '@theorchard/suite-icons';
import {
    DeliveryJobStatusCell,
    JobUpdatedAtCell,
    JobUpdatedByCell,
    ServiceNameCell,
    ProductTypeCell,
    EntityNameCell,
    InstanceCountCell,
} from 'src/components/tableCells';
import { OwnershipNrDeliveryJobStatus } from 'src/data/globalTypes';
import { useUpdateDeliveryJobStatusMutation } from 'src/data/mutations/updateNrDeliveryJobStatus/updateNrDeliveryJobStatus';
import { type OwnershipNrDeliveryJob } from 'src/data/queries';
import GridTableWrapper from 'src/pages/monitorOwnershipPage/components/gridTableWrapper';
import { TRANSLATION_KEY } from '../../constants';
import type { GridTableSelectAll } from '@theorchard/suite-components';
import type { GetOwnershipDeliveryJobsVariables } from 'src/data/queries/getNrOwnershipDeliveryJobs/__generated__/nrOwnershipDeliveryJobs';
import type { RowInstance, SortBy } from 'src/types';

export const CLASS_NAME = 'JobsTable';

interface Props {
    jobs: OwnershipNrDeliveryJob[];
    totalCount: number;
    loading: boolean;
    sortBy: SortBy;
    pageSize: number;
    page: number;
    handlePageChange: (newPageNumber: number) => void;
    handlePageSizeChange: (newPageSize: number) => void;
    onClearFilters: () => void;
    onSort: (sortBy: SortBy[]) => void;
    filtersApplied: boolean;
    getJobsVariables?: GetOwnershipDeliveryJobsVariables;
}

const JobsTable: FC<Props> = ({
    jobs,
    totalCount,
    loading,
    sortBy,
    page,
    pageSize,
    handlePageChange,
    handlePageSizeChange,
    onClearFilters,
    onSort,
    filtersApplied,
    getJobsVariables,
}) => {
    const disableSelectAll = () => setSelectAll('disabled');
    const [selectedRows, setSelectedRows] = useState<string[]>([]);
    const [selectAll, setSelectAll] = useState<
        GridTableSelectAll | undefined
    >();
    const { updateJobs } = useUpdateDeliveryJobStatusMutation(getJobsVariables);
    const addToast = useToast();

    const handleCompleteClick = useCallback(async () => {
        await updateJobs({
            variables: {
                input: {
                    jobIds: selectedRows.map(id => id),
                    status: OwnershipNrDeliveryJobStatus.DELIVERED,
                },
            },
        });
        addToast(
            $t(`${TRANSLATION_KEY}.jobActions.complete`, {
                count: selectedRows.length ?? '-',
            })
        );
        setSelectedRows([]);
    }, [selectedRows, addToast, updateJobs]);

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

    const reviewOptionKey = {
        complete: 'complete',
        cancel: 'cancel',
    } as const;

    const reviewOptions = [
        {
            value: 'complete',
            label: $t(`${TRANSLATION_KEY}.tableHeaderActions.completeDelivery`),
        },
        {
            value: 'cancel',
            label: $t(`${TRANSLATION_KEY}.tableHeaderActions.cancelDelivery`),
        },
    ];

    const SelectInput = () => (
        <Button size="sm" variant="primary">
            {$t(`${TRANSLATION_KEY}.tableHeaderActions.markAs`).toUpperCase()}
            <GlyphIcon name="chevronDown" size={12} />
        </Button>
    );

    const handleRowSelection = (rows: string[]) => {
        const readyForDeliveryJobs = jobs
            .map(item =>
                item.status === OwnershipNrDeliveryJobStatus.READY
                    ? item.id
                    : ''
            )
            .filter(item => item);
        setSelectedRows(
            rows.filter(item => readyForDeliveryJobs.includes(item))
        );
    };

    return (
        <GridTableWrapper>
            <GridTable
                className={`${CLASS_NAME}-grid-table`}
                variant="zebra"
                data={jobs}
                loading={loading}
                onSort={sortBy => {
                    onSort(sortBy);
                    disableSelectAll();
                }}
                sortBy={sortBy}
                bordered
                emptyStateIcon={() => <Illustration name="noResults" />}
                emptyStateTitle={$t(`${TRANSLATION_KEY}.noJobs`)}
                rowKey={(row: OwnershipNrDeliveryJob) => row.id}
                selectable
                rowSelectEnabled={(row: RowInstance<OwnershipNrDeliveryJob>) =>
                    row.data.status === OwnershipNrDeliveryJobStatus.READY
                }
                selectedRowKeys={selectedRows}
                onSelectedRowsChanged={handleRowSelection}
                rowBulkActions={{
                    review: {
                        icon: () => (
                            <Select
                                className={`${CLASS_NAME}-mark-as`}
                                hideFilter
                                menuAlignment="right"
                                menuMaxWidth={163}
                                menuMinWidth={163}
                                onSelect={item => {
                                    if (
                                        item?.value === reviewOptionKey.complete
                                    ) {
                                        handleCompleteClick().catch(e =>
                                            console.error(e)
                                        );
                                    }
                                    if (
                                        item?.value === reviewOptionKey.cancel
                                    ) {
                                        handleCancelClick().catch(e =>
                                            console.error(e)
                                        );
                                    }
                                }}
                                components={{ SelectInput }}
                                options={reviewOptions}
                                width="auto"
                            />
                        ),
                        onClick: () => {},
                    },
                }}
                paginated
                page={page}
                totalCount={totalCount}
                pageSize={pageSize}
                onPageChange={page => {
                    handlePageChange(page);
                    disableSelectAll();
                }}
                onPageSizeChange={size => {
                    handlePageSizeChange(size);
                    disableSelectAll();
                }}
                onClearFilters={onClearFilters}
                showClearFilters={filtersApplied}
                showUpdateIndicator
                selectAllEnabled
                selectAll={selectAll}
                onSelectAllChanged={setSelectAll}
            >
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-jobId`}
                    name="id"
                    title={$t(`${TRANSLATION_KEY}.jobId`)}
                    sortable
                    fixed
                    minWidth="90px"
                    maxWidth="90px"
                    align="right"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-orderId`}
                    name="orderId"
                    title={$t(`${TRANSLATION_KEY}.orderId`)}
                    sortable
                    fixed
                    minWidth="90px"
                    maxWidth="100px"
                    align="right"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-delivery-status`}
                    name="status"
                    Cell={DeliveryJobStatusCell}
                    title={$t(`${TRANSLATION_KEY}.deliveryStatus`)}
                    minWidth="160px"
                    maxWidth="165px"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-cmo`}
                    name="cmm.name"
                    title={$t(`${TRANSLATION_KEY}.serviceName`)}
                    Cell={ServiceNameCell}
                    minWidth="150px"
                    maxWidth="150px"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-cmo`}
                    name="entityName"
                    title={$t(`${TRANSLATION_KEY}.entityName`)}
                    Cell={EntityNameCell}
                    minWidth="100px"
                    maxWidth="100px"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-productType`}
                    name="type"
                    Cell={ProductTypeCell}
                    title={$t(`${TRANSLATION_KEY}.productType`)}
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-instances`}
                    name="instanceCount"
                    title={$t(`${TRANSLATION_KEY}.numberOfInstances`)}
                    Cell={InstanceCountCell}
                    align="right"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-delivery-lastUpdated`}
                    name="lastUpdated"
                    title={$t(`${TRANSLATION_KEY}.jobFulfilledOn`)}
                    sortable={false}
                    Cell={JobUpdatedAtCell}
                    align="right"
                />
                <GridTable.Column
                    className={`${CLASS_NAME}-cell-delivery-lastUpdatedBy`}
                    name="lastUpdatedBy.name"
                    title={$t(`${TRANSLATION_KEY}.jobFulfillmentBy`)}
                    sortable={false}
                    Cell={JobUpdatedByCell}
                />
            </GridTable>
        </GridTableWrapper>
    );
};

export default JobsTable;
