/**
 * @file Home.tsx - Main landing page component shown after login.
 * Displays an inbox work items table and a queue work items table with process/queue selection dropdowns and optional folder field columns.
 * Provides toolbar buttons for opening, cloning, and signing work items, along with modals for creating new work items and signing selected work items.
 */

import {
  type ChangeEvent,
  type Dispatch,
  type SetStateAction,
  useEffect,
  useState,
} from 'react';
import {
  getProcessPermissions,
  listProcesses,
  type Process,
} from '../api/process.ts';
import {
  Button,
  Col,
  FloatingLabel,
  Form,
  OverlayTrigger,
  Row,
  Tooltip,
} from 'react-bootstrap';
import { ContentCard } from '../components/ContentCard.tsx';
import { listQueues, type Queue } from '../api/queue.ts';
import {
  cloneWorkItem as apiCloneWorkItem,
  getDefaultWorkItemColumns,
  getInboxWorkItems,
  getQueueWorkItems,
  transformWorkItems,
  type WorkItem,
  type WorkItemTableData,
} from '../api/workItem.ts';
import { DataTable } from '../components/DataTable.tsx';
import { useReauth } from '../contexts/ReauthContext.tsx';
import { useMediaQuery } from 'react-responsive';
import { breakpoints } from '../utils/bootstrapBreakpoints.ts';
import {
  type FolderField,
  getProcessFolderFields,
} from '../api/folderField.ts';
import {
  RefreshButton,
  type RefreshButtonStatus,
} from '../components/RefreshButton.tsx';
import {
  clearStoredProcessId,
  clearStoredQueueId,
  getStoredProcessId,
  getStoredQueueId,
  getStoredQueueShowFolderFields,
  setStoredProcessId,
  setStoredQueueId,
  setStoredQueueShowFolderFields,
} from '../utils/localStorage.ts';
import { useAuth } from '../contexts/AuthContext.tsx';
import {
  LOCAL_STORAGE_EXPAND_INBOX_CARD,
  LOCAL_STORAGE_PAGINATION_INBOX_TABLE,
  LOCAL_STORAGE_PAGINATION_QUEUE_TABLE,
  MAX_WORK_ITEM_NAME_LENGTH,
} from '../constants.ts';
import { useNavigate } from 'react-router-dom';
import type { RowSelectionState } from '@tanstack/react-table';
import { useProcessPermissions } from '../contexts/ProcessPermissionsContext.tsx';
import { AtAllowRights } from '../types/atAllowRights.ts';
import { Icon } from '../components/Icon.tsx';
import { NewWorkItemModal } from '../components/Home/modals/NewWorkItemModal.tsx';
import { useHasVerticalScrollbar } from '../hooks/useHasVerticalScrollbar.ts';
import { SignWorkItemsModal } from '../components/Home/modals/SignWorkItemsModal.tsx';
import { useTranslation } from 'react-i18next';
import { toast } from 'react-toastify';
import { ToolbarButton } from '../components/ToolbarButton.tsx';

/**
 * Home page that allows selection of process, queue, and work item.
 */
export const Home = () => {
  const { username } = useAuth();
  const navigate = useNavigate();

  // Used to trigger data refresh
  const { reauthToken, oldReauthToken, setOldReauthToken } = useReauth();
  const [inboxRefreshStatus, setInboxRefreshStatus] =
    useState<RefreshButtonStatus>('start');
  const [inboxRefreshDisabled, setInboxRefreshDisabled] = useState(false);
  const [queueRefreshStatus, setQueueRefreshStatus] =
    useState<RefreshButtonStatus>('start');

  // Retrieve list of WorkItems for the user's inbox and store in state
  // Transform for use with DataTable
  // @ts-expect-error Unused variable
  const [inboxWorkItems, setInboxWorkItems] = useState<WorkItem[]>();
  const [transformedInboxWorkItems, setTransformedInboxWorkItems] = useState<
    WorkItemTableData[]
  >([]);
  const retrieveInboxWorkItems = async () => {
    try {
      // Retrieve inbox WorkItems
      const _inboxWorkItems = await getInboxWorkItems();
      setInboxWorkItems(_inboxWorkItems);

      // Transform WorkItems
      const _transformedWorkItems = transformWorkItems(_inboxWorkItems);
      setTransformedInboxWorkItems(_transformedWorkItems);

      if (!['none', 'error'].includes(inboxRefreshStatus)) {
        setInboxRefreshStatus('success');
      }
    } catch (error) {
      toast.error((error as Error).message);

      setInboxWorkItems([]);
      setTransformedInboxWorkItems([]);

      setInboxRefreshStatus('error');
    }
  };

  // Keep track of inbox selected work item
  const [inboxSelectedWorkItem, setInboxSelectedWorkItem] =
    useState<WorkItemTableData | null>(null);
  // Keep track of whether selected inbox work item is locked
  const [inboxSelectedWorkItemLocked, setInboxSelectedWorkItemLocked] =
    useState(false);
  useEffect(() => {
    setInboxSelectedWorkItemLocked(
      ![null, username].includes(inboxSelectedWorkItem?.lockedBy as string)
    );
  }, [inboxSelectedWorkItem]);
  const [inboxRowSelectionSetter, setInboxRowSelectionSetter] =
    useState<Dispatch<SetStateAction<RowSelectionState>>>();
  useEffect(() => {
    if (inboxRowSelectionSetter && inboxRefreshStatus === 'start') {
      inboxRowSelectionSetter(() => {
        return {};
      });
    }
  }, [inboxRefreshStatus]);

  // Retrieve lists of processes and queues and store in state
  const [processes, setProcesses] = useState<Process[]>([]);
  const [queues, setQueues] = useState<Map<number, Queue[]>>(
    new Map<number, Queue[]>()
  );
  const retrieveProcessesAndQueues = async () => {
    try {
      // Retrieve all processes
      const _processes = await listProcesses();
      setProcesses(_processes);

      // Set stored selected process (if it exists)
      const storedProcessId = getStoredProcessId();
      if (storedProcessId) {
        const foundProcess = _processes.find(
          (_process) => _process.id === storedProcessId
        );
        if (foundProcess) {
          setSelectedProcessId(storedProcessId);
        } else {
          clearStoredProcessId();
        }
      }

      // Retrieve all queues
      const _queues = new Map<number, Queue[]>();
      const _queueRequests: Promise<Queue[]>[] = [];
      for (const _process of _processes) {
        _queueRequests.push(listQueues(_process.id));
      }
      const _queueResponses = await Promise.all(_queueRequests);
      for (let i = 0; i < _queueResponses.length; i++) {
        const _processId = _processes[i].id;
        _queues.set(_processId, _queueResponses[i]);
      }
      setQueues(_queues);

      // Set stored selected queue (if it exists)
      const storedQueueId = getStoredQueueId();
      if (storedQueueId) {
        const foundQueue = _queues
          .get(storedProcessId as number)
          ?.find((_queue) => _queue.queueId === storedQueueId);
        if (foundQueue) {
          setSelectedQueueId(storedQueueId);
        } else {
          clearStoredQueueId();
        }
      }

      if (!['none', 'error'].includes(queueRefreshStatus)) {
        setQueueRefreshStatus('success');
      }
    } catch (error) {
      const isTypeError = error instanceof TypeError;
      if (!isTypeError) {
        toast.error((error as Error).message);
      }

      setProcesses([]);
      setQueues(new Map<number, Queue[]>());

      setQueueRefreshStatus(isTypeError ? 'success' : 'error');
    }
  };

  // Keep track of selected process in dropdown
  const [selectedProcessId, setSelectedProcessId] = useState(0);
  // @ts-expect-error unused variable
  const [selectedProcess, setSelectedProcess] = useState<Process>();
  const updateSelectedProcess = (event: ChangeEvent<HTMLSelectElement>) => {
    const newSelectedProcessId = Number(event.target.value);

    setSelectedProcessId(newSelectedProcessId);
    setStoredProcessId(newSelectedProcessId);

    setSelectedQueueId(0);
    clearStoredQueueId();

    setQueueWorkItems([]);
    setTransformedQueueWorkItems([]);
    setProcessFolderFields([]);
  };
  useEffect(() => {
    const newSelectedProcess = processes.find(
      (process) => process.id === selectedProcessId
    );
    setSelectedProcess(newSelectedProcess);
  }, [selectedProcessId]);

  // Retrieve process-related data when selectedProcess changes
  const { setPermissions, hasPermission } = useProcessPermissions();
  const retrieveProcessData = async () => {
    try {
      // Retrieve folder fields and permissions
      const [_processFolderFields, _permissions] = await Promise.all([
        getProcessFolderFields(selectedProcessId),
        getProcessPermissions(selectedProcessId),
      ]);
      setProcessFolderFields(_processFolderFields);
      setPermissions(_permissions);
    } catch (error) {
      toast.error((error as Error).message);

      setProcessFolderFields([]);
      setPermissions([]);
    }
  };
  useEffect(() => {
    if (selectedProcessId) {
      retrieveProcessData();
    }
  }, [selectedProcessId]);

  // Keep track of selected queue in dropdown
  const [selectedQueueId, setSelectedQueueId] = useState(0);
  const [selectedQueue, setSelectedQueue] = useState<Queue>();
  const updateSelectedQueue = (event: ChangeEvent<HTMLSelectElement>) => {
    const newSelectedQueueId = Number(event.target.value);

    setSelectedQueueId(newSelectedQueueId);
    setStoredQueueId(newSelectedQueueId);

    if (queueRowSelectionSetter) {
      queueRowSelectionSetter(() => {
        return {};
      });
    }
  };
  useEffect(() => {
    const newSelectedQueue = queues
      .get(selectedProcessId)
      ?.find((queue) => queue.queueId === selectedQueueId);
    setSelectedQueue(newSelectedQueue);
  }, [queues, selectedQueueId]);

  // Retrieve list of WorkItems for the selected queue and store in state
  // Transform for use with DataTable
  // @ts-expect-error Unused variable
  const [queueWorkItems, setQueueWorkItems] = useState<WorkItem[]>();
  const [transformedQueueWorkItems, setTransformedQueueWorkItems] = useState<
    WorkItemTableData[]
  >([]);
  const [processFolderFields, setProcessFolderFields] = useState<FolderField[]>(
    []
  );
  const [showProcessFolderFields, setShowProcessFolderFields] = useState(
    getStoredQueueShowFolderFields() ?? true
  );
  const updateShowQueueWorkItemsFolderFields = (
    event: ChangeEvent<HTMLInputElement>
  ) => {
    setShowProcessFolderFields(event.target.checked);
    setStoredQueueShowFolderFields(event.target.checked);
  };
  const retrieveQueueWorkItems = async () => {
    try {
      // Retrieve WorkItems for the selected queue
      const _queueWorkItems = await getQueueWorkItems(selectedQueueId);
      setQueueWorkItems(_queueWorkItems);

      // Transform WorkItems
      const _transformedWorkItems = transformWorkItems(_queueWorkItems);
      setTransformedQueueWorkItems(_transformedWorkItems);

      if (!['none', 'error'].includes(queueRefreshStatus)) {
        setQueueRefreshStatus('success');
      }
    } catch (error) {
      toast.error((error as Error).message);

      setQueueWorkItems([]);
      setTransformedQueueWorkItems([]);

      setQueueRefreshStatus('error');
    }
  };
  useEffect(() => {
    if (selectedQueueId) {
      retrieveQueueWorkItems();
    }
  }, [selectedQueueId]);

  // Keep track of selected queue work item
  const [queueSelectedWorkItem, setQueueSelectedWorkItem] = useState<
    WorkItemTableData | WorkItemTableData[]
  >();
  // Returns the first or only selected queue work item
  // Singular vs. plural handling
  const getQueueSelectedWorkItem = () => {
    return Array.isArray(queueSelectedWorkItem)
      ? queueSelectedWorkItem[0]
      : queueSelectedWorkItem;
  };
  // Keep track of whether selected queue work item is locked
  const [queueSelectedWorkItemLocked, setQueueSelectedWorkItemLocked] =
    useState(false);
  useEffect(() => {
    if (!getQueueSelectedWorkItem()) {
      setQueueSelectedWorkItemLocked(false);
      return;
    }
    setQueueSelectedWorkItemLocked(
      ![null, username].includes(getQueueSelectedWorkItem()?.lockedBy as string)
    );
  }, [queueSelectedWorkItem]);
  const [queueRowSelectionSetter, setQueueRowSelectionSetter] =
    useState<Dispatch<SetStateAction<RowSelectionState>>>();
  useEffect(() => {
    if (queueRowSelectionSetter && queueRefreshStatus === 'start') {
      queueRowSelectionSetter(() => {
        return {};
      });
    }
  }, [queueRefreshStatus]);
  useEffect(() => {
    if (queueRowSelectionSetter) {
      queueRowSelectionSetter(() => {
        return {};
      });
    }
  }, [selectedQueue?.signable]);

  // Handles the opening of WorkItems once one has been selected
  const openWorkItem = (
    processId: number,
    queueId: number,
    workItemReferenceId: number
  ) => {
    navigate(
      '/processing/' + processId + '/' + queueId + '/' + workItemReferenceId
    );
  };

  // Determines if an inbox work item can be cloned
  const maybeCloneInboxWorkItem = (workItem: WorkItemTableData) => {
    const tKey = 'functions.clone_work_item';

    getProcessPermissions(Number(workItem.processId))
      .then((permissions) => {
        if (permissions.includes(AtAllowRights.CloneWorkitems)) {
          cloneWorkItem(workItem, true);
        } else {
          toast.error(t(tKey + '.errors.lacks_permission'));
        }
      })
      .catch((error) => {
        const message = (error as Error).message;
        toast.error(
          `${t(tKey + '.errors.failed_to_retrieve_permissions')}: ` + message
        );
      });
  };
  // Handles the cloning of work items once one has been selected
  const cloneWorkItem = (
    workItem: WorkItemTableData,
    isInboxWorkItem: boolean = false,
    tKey: string = 'functions.clone_work_item'
  ) => {
    const newWorkItemName = (workItem.description + ' - Copy').slice(
      0,
      Number(MAX_WORK_ITEM_NAME_LENGTH)
    );

    apiCloneWorkItem(
      workItem.workItemReferenceId as number,
      newWorkItemName,
      t(tKey + '.message', {
        reference_id: Number(workItem.workItemReferenceId),
      })
    )
      .then(() => {
        toast.success(t(tKey + '.success'));

        if (isInboxWorkItem) {
          setInboxRefreshStatus('start');
        } else {
          setQueueRefreshStatus('start');
        }
      })
      .catch((error) => {
        const message = (error as Error).message;
        toast.error(`${t(tKey + '.errors.failed_to_clone')}: ` + message);
      });
  };

  // "Create Work Item" modal state
  const [createWorkItemModalShown, setCreateWorkItemModalShown] =
    useState(false);
  const showCreateWorkItemModal = () => setCreateWorkItemModalShown(true);
  const hideCreateWorkItemModal = () => setCreateWorkItemModalShown(false);

  // "Sign Work Items" modal state
  const [signWorkItemsModalShown, setSignWorkItemsModalShown] = useState(false);
  const showSignWorkItemsModal = () => setSignWorkItemsModalShown(true);
  const hideSignWorkItemsModal = (refresh: boolean = false) => {
    setSignWorkItemsModalShown(false);

    if (refresh) {
      setQueueRefreshStatus('start');
    }
  };

  // Trigger refresh of inbox work items
  useEffect(() => {
    const tokenChanged = reauthToken !== oldReauthToken;

    if (inboxRefreshStatus === 'start' || tokenChanged) {
      retrieveInboxWorkItems().finally(() => {
        if (tokenChanged) {
          setOldReauthToken(reauthToken);
        }
      });
    }
  }, [reauthToken, oldReauthToken, setOldReauthToken, inboxRefreshStatus]);
  // Trigger refresh of processes, queues, and queue work items
  useEffect(() => {
    const tokenChanged = reauthToken !== oldReauthToken;

    if (queueRefreshStatus === 'start' || tokenChanged) {
      retrieveProcessesAndQueues()
        .then(() => {
          if (selectedProcessId) {
            retrieveProcessData();
          }
          if (selectedQueueId) {
            retrieveQueueWorkItems();
          }
        })
        .finally(() => {
          if (tokenChanged) {
            setOldReauthToken(reauthToken);
          }
        });
    }
  }, [reauthToken, oldReauthToken, setOldReauthToken, queueRefreshStatus]);

  const isMobileLg = useMediaQuery({ maxWidth: breakpoints.lg - 1 });
  const tooltipFixed = !useHasVerticalScrollbar();

  const { t } = useTranslation(undefined, {
    keyPrefix: 'pages.home',
  });

  const lpnuSignageEnabled =
    String(
      window.__APP_CONFIG__?.ENABLE_LPNU_WORK_ITEM_SIGNAGE
    ).toLowerCase() === 'true';

  return (
    <>
      <ContentCard
        headerContent={{
          title: t('cards.inbox.header.title'),
          subtitle: t('cards.inbox.header.subtitle'),
          rightAlignedContent: {
            content: (
              <RefreshButton
                refreshStatus={inboxRefreshStatus}
                setRefreshStatus={setInboxRefreshStatus}
                disabled={
                  inboxRefreshDisabled || inboxRefreshStatus === 'start'
                }
              />
            ),
            setIsDisabled: setInboxRefreshDisabled,
          },
        }}
        collapsible
        expansionStateKey={LOCAL_STORAGE_EXPAND_INBOX_CARD}
      >
        <>
          <DataTable
            columns={getDefaultWorkItemColumns().filter(
              (columnDef) =>
                ![
                  'workItemId',
                  'processId',
                  'queueId',
                  // @ts-expect-error accessorKey exists
                ].includes(columnDef.accessorKey)
            )}
            data={transformedInboxWorkItems}
            selection={{
              rule: 'single',
              setSelectedRow: setInboxSelectedWorkItem,
              onRowSelectionSetterReady: (setter) =>
                setInboxRowSelectionSetter(() => setter),
            }}
            toolbarButtons={{
              // @ts-expect-error element casting
              left: [
                <ToolbarButton
                  tooltip={{
                    fixed: tooltipFixed,
                    display:
                      inboxSelectedWorkItem !== undefined &&
                      inboxSelectedWorkItemLocked,
                    text: t(
                      'cards.inbox.body.table.toolbar_buttons.open.tooltip'
                    ),
                  }}
                  variant={'success'}
                  disabled={
                    !inboxSelectedWorkItem || inboxSelectedWorkItemLocked
                  }
                  onClick={
                    inboxSelectedWorkItem
                      ? () => {
                          openWorkItem(
                            inboxSelectedWorkItem?.processId as number,
                            inboxSelectedWorkItem?.queueId as number,
                            inboxSelectedWorkItem?.workItemReferenceId as number
                          );
                        }
                      : undefined
                  }
                  iconName={'Folder2Open'}
                  text={t(
                    'cards.inbox.body.table.toolbar_buttons.open.button_text'
                  )}
                />,
              ].concat(
                <ToolbarButton
                  tooltip={{
                    fixed: tooltipFixed,
                    display:
                      inboxSelectedWorkItem !== undefined &&
                      inboxSelectedWorkItemLocked,
                    text: t(
                      'cards.inbox.body.table.toolbar_buttons.clone.tooltip'
                    ),
                  }}
                  disabled={
                    !inboxSelectedWorkItem || inboxSelectedWorkItemLocked
                  }
                  onClick={
                    inboxSelectedWorkItem
                      ? () => {
                          maybeCloneInboxWorkItem(inboxSelectedWorkItem);
                        }
                      : undefined
                  }
                  iconName={'Copy'}
                  text={t(
                    'cards.inbox.body.table.toolbar_buttons.clone.button_text'
                  )}
                />
              ),
            }}
            pageSizeStateKey={LOCAL_STORAGE_PAGINATION_INBOX_TABLE}
          />
        </>
      </ContentCard>

      <ContentCard
        headerContent={{
          title: t('cards.work_item_selection.header.title'),
          subtitle: `${t('cards.work_item_selection.header.subtitle.default')}${lpnuSignageEnabled && selectedQueue?.signable ? ` ${t('cards.work_item_selection.header.subtitle.lpnu_signage')}` : ''}`,
          rightAlignedContent: {
            content: (
              <RefreshButton
                refreshStatus={queueRefreshStatus}
                setRefreshStatus={setQueueRefreshStatus}
                disabled={queueRefreshStatus === 'start'}
              />
            ),
          },
        }}
        fillPage
      >
        <Row className={'gap-2 gap-lg-0'}>
          <Col xs={12} lg={3}>
            <div className={'mb-2'}>
              <div className={'d-flex justify-content-between gap-2'}>
                <FloatingLabel
                  controlId={'process-select'}
                  label={t(
                    'cards.work_item_selection.body.selects.process.label'
                  )}
                  className={'w-100'}
                >
                  <Form.Select
                    value={selectedProcessId}
                    onChange={updateSelectedProcess}
                    disabled={!processes.length}
                  >
                    {processes.length ? (
                      <option value={0} disabled>
                        {t(
                          'cards.work_item_selection.body.selects.process.options.default'
                        )}
                      </option>
                    ) : (
                      <option value={0} disabled>
                        {t(
                          'cards.work_item_selection.body.selects.process.options.none'
                        )}
                      </option>
                    )}
                    {processes.map((process) => (
                      <option key={process.id} value={process.id}>
                        {process.name} ({process.version})
                      </option>
                    ))}
                  </Form.Select>
                </FloatingLabel>
                {hasPermission(AtAllowRights.CreateWorkitem) && (
                  <OverlayTrigger
                    placement={'top'}
                    overlay={
                      <Tooltip
                        className={tooltipFixed ? 'position-fixed' : undefined}
                      >
                        {t(
                          'cards.work_item_selection.body.buttons.new_work_item.tooltip'
                        )}
                      </Tooltip>
                    }
                  >
                    <Button
                      variant={'outline-primary'}
                      disabled={!selectedProcessId}
                      onClick={showCreateWorkItemModal}
                    >
                      <div
                        className={
                          'd-flex align-items-center justify-content-center'
                        }
                      >
                        <Icon iconName={'FolderPlus'} size={20} />
                        <span className={'ms-2'}>
                          {t(
                            'cards.work_item_selection.body.buttons.new_work_item.button_text'
                          )}
                        </span>
                      </div>
                    </Button>
                  </OverlayTrigger>
                )}
              </div>
            </div>
            <div>
              <FloatingLabel
                controlId={'queue-select'}
                label={t('cards.work_item_selection.body.selects.queue.label')}
              >
                <Form.Select
                  value={selectedQueueId}
                  onChange={updateSelectedQueue}
                  disabled={
                    !selectedProcessId || !queues.get(selectedProcessId)?.length
                  }
                >
                  {queues.get(selectedProcessId)?.length ? (
                    <option value={0} disabled>
                      {t(
                        'cards.work_item_selection.body.selects.queue.options.default'
                      )}
                    </option>
                  ) : (
                    <option value={0} disabled>
                      {t(
                        'cards.work_item_selection.body.selects.queue.options.none'
                      )}
                    </option>
                  )}
                  {queues.get(selectedProcessId)?.map((queue) => (
                    <option key={queue.queueId} value={queue.queueId}>
                      {queue.queueAlias || queue.queueName}
                    </option>
                  ))}
                </Form.Select>
              </FloatingLabel>
            </div>
            <div className={'float-lg-end mt-2'}>
              <Form.Check
                type={'switch'}
                id={'show-queue-work-items-folder-fields-switch'}
                checked={showProcessFolderFields}
                onChange={updateShowQueueWorkItemsFolderFields}
                label={t(
                  'cards.work_item_selection.body.switches.show_folder_fields.label'
                )}
              />
            </div>
          </Col>
          {isMobileLg && (
            <Col xs={12} className={'d-block'}>
              <hr />
            </Col>
          )}
          <Col xs={12} lg={9}>
            <DataTable
              columns={getDefaultWorkItemColumns()
                .filter(
                  (columnDef) =>
                    ![
                      'workItemId',
                      'processId',
                      'processName',
                      'queueId',
                      'queueName',
                    ]
                      // @ts-expect-error accessorKey exists
                      .includes(columnDef.accessorKey)
                )
                // Add column definitions for all unique folder fields in WorkItems
                .concat(
                  showProcessFolderFields
                    ? Array.from(
                        processFolderFields.map((field) => ({
                          accessorKey: field.fieldName,
                          header: field.fieldName,
                          sortDescFirst: false,
                          filterFn: 'equalsString',
                        }))
                      )
                    : []
                )}
              data={transformedQueueWorkItems}
              selection={
                lpnuSignageEnabled && selectedQueue?.signable
                  ? {
                      rule: 'multiple',
                      setSelectedRows: setQueueSelectedWorkItem,
                      onRowSelectionSetterReady: (setter) =>
                        setQueueRowSelectionSetter(() => setter),
                    }
                  : {
                      rule: 'single',
                      setSelectedRow: setQueueSelectedWorkItem,
                      onRowSelectionSetterReady: (setter) =>
                        setQueueRowSelectionSetter(() => setter),
                    }
              }
              toolbarButtons={{
                // @ts-expect-error element casting
                left: [
                  <ToolbarButton
                    tooltip={{
                      fixed: tooltipFixed,
                      display: Array.isArray(queueSelectedWorkItem)
                        ? queueSelectedWorkItem.length > 1 ||
                          queueSelectedWorkItemLocked
                        : queueSelectedWorkItem !== undefined &&
                          queueSelectedWorkItemLocked,
                      text:
                        (!Array.isArray(queueSelectedWorkItem) ||
                          queueSelectedWorkItem?.length === 1) &&
                        queueSelectedWorkItemLocked
                          ? t(
                              'cards.work_item_selection.body.table.toolbar_buttons.open.tooltip.locked'
                            )
                          : t(
                              'cards.work_item_selection.body.table.toolbar_buttons.open.tooltip.only_one'
                            ),
                    }}
                    variant={'success'}
                    disabled={
                      !getQueueSelectedWorkItem() ||
                      queueSelectedWorkItemLocked ||
                      (queueSelectedWorkItem?.length as number) > 1
                    }
                    onClick={
                      queueSelectedWorkItem
                        ? () => {
                            openWorkItem(
                              selectedProcessId,
                              selectedQueueId,
                              getQueueSelectedWorkItem()
                                ?.workItemReferenceId as number
                            );
                          }
                        : undefined
                    }
                    iconName={'Folder2Open'}
                    text={t(
                      'cards.work_item_selection.body.table.toolbar_buttons.open.button_text'
                    )}
                  />,
                ]
                  .concat(
                    hasPermission(AtAllowRights.CloneWorkitems) ? (
                      <ToolbarButton
                        tooltip={{
                          fixed: tooltipFixed,
                          display: Array.isArray(queueSelectedWorkItem)
                            ? queueSelectedWorkItem.length > 1 ||
                              queueSelectedWorkItemLocked
                            : queueSelectedWorkItem !== undefined &&
                              queueSelectedWorkItemLocked,
                          text:
                            (!Array.isArray(queueSelectedWorkItem) ||
                              queueSelectedWorkItem?.length === 1) &&
                            queueSelectedWorkItemLocked
                              ? t(
                                  'cards.work_item_selection.body.table.toolbar_buttons.clone.tooltip.locked'
                                )
                              : t(
                                  'cards.work_item_selection.body.table.toolbar_buttons.clone.tooltip.only_one'
                                ),
                        }}
                        disabled={
                          !getQueueSelectedWorkItem() ||
                          queueSelectedWorkItemLocked ||
                          (queueSelectedWorkItem?.length as number) > 1
                        }
                        onClick={
                          queueSelectedWorkItem
                            ? () => {
                                cloneWorkItem(
                                  getQueueSelectedWorkItem() as WorkItemTableData
                                );
                              }
                            : undefined
                        }
                        iconName={'Copy'}
                        text={t(
                          'cards.work_item_selection.body.table.toolbar_buttons.clone.button_text'
                        )}
                      />
                    ) : (
                      []
                    )
                  )
                  .concat(
                    lpnuSignageEnabled && selectedQueue?.signable ? (
                      <ToolbarButton
                        disabled={
                          !selectedQueue?.signable ||
                          !queueSelectedWorkItem ||
                          (queueSelectedWorkItem?.length as number) < 1
                        }
                        onClick={showSignWorkItemsModal}
                        iconName={'PatchCheck'}
                        text={t(
                          'cards.work_item_selection.body.table.toolbar_buttons.sign.button_text'
                        )}
                      />
                    ) : (
                      []
                    )
                  ),
              }}
              pageSizeStateKey={LOCAL_STORAGE_PAGINATION_QUEUE_TABLE}
              padding
              maxPadding={10}
            />
          </Col>
        </Row>
      </ContentCard>

      <NewWorkItemModal
        show={createWorkItemModalShown}
        onHide={hideCreateWorkItemModal}
        process={processes.find((process) => process.id === selectedProcessId)}
        folderFields={processFolderFields}
      />

      {lpnuSignageEnabled && selectedQueue?.signable && (
        <SignWorkItemsModal
          show={signWorkItemsModalShown}
          onHide={hideSignWorkItemsModal}
          selectedWorkItems={queueSelectedWorkItem}
        />
      )}
    </>
  );
};
