/**
 * @file DetailsSection.tsx - Section component within the DetailsFolderPanel that shows work item metadata (process, queue, reference ID) and action buttons (forward, close).
 * Handles the work item close/forward lifecycle: unlocking the work item, optionally forwarding it to a queue action, and redirecting based on the user's stored open mode.
 * Supports auto-save by waiting for unsaved changes to be persisted before completing the close operation.
 */

import { type FC, Fragment, type RefObject, useEffect, useState } from 'react';
import { Button, Dropdown } from 'react-bootstrap';
import { ContentCard } from '../../../ContentCard.tsx';
import { useWorkItem } from '../../../../contexts/WorkItemContext.tsx';
import { useDocument } from '../../../../contexts/DocumentContext.tsx';
import { useProcessingUI } from '../../../../contexts/ProcessingUIContext.tsx';
import { forwardWorkItem, unlockWorkItem } from '../../../../api/workItem.ts';
import { toast } from 'react-toastify';
import { getStoredOpenMode } from '../../../../utils/localStorage.ts';
import { Icon } from '../../../Icon.tsx';
import { useDetailsSectionHotkeys } from '../../../../hooks/hotkeys/useDetailsSectionHotkeys.ts';
import { useTranslation } from 'react-i18next';

/**
 * Details section within Details/Folder panel that displays process/queue/work item details and work item action buttons.
 * Provides a forward dropdown (populated from allowed queue action buttons) and a close button.
 */
export const DetailsSection: FC = () => {
  // Required contexts for work item processing
  const { process, queue, workItem, buttons } = useWorkItem();
  const { selectedDocumentContentHasChanged } = useDocument();
  const {
    selectedNodeFieldsHaveChanged,
    showCloseWorkItemModal,
    setCloseWorkItem,
    saveWorkItem,
    setSaveWorkItem,
    closeWorkItem,
    closeButtonRef,
    blocker,
    safeNavigate,
    setWorkItemClosed,
  } = useProcessingUI();

  // Tracks the queue action name when user selects a forward action from the dropdown
  const [forwardingAction, setForwardingAction] = useState<string>();

  /**
   * Redirects to the appropriate page based on the user's stored open mode preference.
   */
  const redirectAppropriately = () => {
    const autoOpenMode = getStoredOpenMode();

    if (autoOpenMode === 'inbox') {
      safeNavigate('/auto-open');
    } else if (autoOpenMode === 'queue') {
      safeNavigate('/auto-open/' + process?.id + '/' + queue?.queueId);
    } else {
      safeNavigate('/');
    }
  };

  // Reset saveWorkItem after changes saved
  useEffect(() => {
    if (
      saveWorkItem &&
      !selectedNodeFieldsHaveChanged &&
      !selectedDocumentContentHasChanged
    ) {
      setSaveWorkItem(false);
    }
  }, [
    saveWorkItem,
    selectedNodeFieldsHaveChanged,
    selectedDocumentContentHasChanged,
  ]);

  // Close work item lifecycle effect
  // Triggers when closeWorkItem is true and all pending changes have been resolved (saved or discarded)
  // Unlocks the work item, optionally forwards it, then redirects the user
  useEffect(() => {
    if (
      closeWorkItem &&
      !selectedNodeFieldsHaveChanged &&
      !selectedDocumentContentHasChanged
    ) {
      // useBlocker check must be reset or allowed to proceed with each check
      // Except when close button was clicked directly
      unlockWorkItem(workItem?.workItemReferenceId as number)
        .then(() => {
          if (forwardingAction) {
            forwardWorkItem(
              workItem?.workItemReferenceId as number,
              forwardingAction,
              queue?.queueId as number
            )
              .then(() => {
                if (blocker.state === 'blocked') {
                  blocker.proceed();
                } else {
                  redirectAppropriately();
                }
                toast.dismiss();
                toast.success(t('effects.close_work_item.forward.success'));
                setWorkItemClosed(true);
              })
              .catch(() => {
                if (blocker.state === 'blocked') {
                  blocker.reset();
                }
                toast.error(
                  t('effects.close_work_item.forward.errors.failed_to_forward')
                );
              });
          } else {
            if (blocker.state === 'blocked') {
              blocker.proceed();
            } else {
              safeNavigate('/');
            }
            toast.dismiss();
            setWorkItemClosed(true);
          }
        })
        .catch(() => {
          if (blocker.state === 'blocked') {
            blocker.reset();
          }
          toast.error(
            t('effects.close_work_item.unlock.errors.failed_to_unlock')
          );
        })
        .finally(() => {
          setForwardingAction(undefined);
          setCloseWorkItem(false);
        });
    }
  }, [
    closeWorkItem,
    selectedNodeFieldsHaveChanged,
    selectedDocumentContentHasChanged,
  ]);

  // Call custom hook for DetailsSection hotkeys
  useDetailsSectionHotkeys({
    closeButtonRef: closeButtonRef as RefObject<HTMLButtonElement>,
  });

  const { t } = useTranslation(undefined, {
    keyPrefix:
      'components.processing.details_folder_panel.sections.details_section',
  });

  return (
    <ContentCard
      headerContent={{
        title: t('cards.details.header.title'),
        rightAlignedContent: {
          content: (
            <div className={'d-flex flex-wrap justify-content-end gap-2'}>
              <Dropdown drop={'down-centered'}>
                <Dropdown.Toggle
                  variant={'primary'}
                  className={'d-flex align-items-center justify-content-center'}
                >
                  <Icon iconName={'FolderSymlink'} size={20} />
                  <span className={'ms-2'}>
                    {t(
                      'cards.details.header.right_aligned_content.action_dropdown.button_text'
                    )}
                  </span>
                </Dropdown.Toggle>
                <Dropdown.Menu>
                  {buttons
                    .filter((button) => button.allowedToClick)
                    .sort((a, b) => a.index - b.index)
                    .map((button, index) => (
                      <Fragment key={index}>
                        <Dropdown.Item
                          eventKey={button.index}
                          onClick={() => {
                            setForwardingAction(button.value.toLowerCase());
                            closeButtonRef.current?.click();
                          }}
                        >
                          {button.name}
                        </Dropdown.Item>
                        {index + 1 !== buttons.length && <Dropdown.Divider />}
                      </Fragment>
                    ))}
                </Dropdown.Menu>
              </Dropdown>
              <Button
                ref={closeButtonRef}
                variant={'danger'}
                onClick={() => {
                  if (
                    selectedNodeFieldsHaveChanged ||
                    selectedDocumentContentHasChanged
                  ) {
                    showCloseWorkItemModal();
                  } else {
                    setCloseWorkItem(true);
                  }
                }}
              >
                <div
                  className={'d-flex align-items-center justify-content-center'}
                >
                  <Icon iconName={'Check2Circle'} size={20} />
                  <span className={'ms-2'}>
                    {t(
                      'cards.details.header.right_aligned_content.close_button.button_text'
                    )}
                  </span>
                </div>
              </Button>
            </div>
          ),
        },
      }}
    >
      <b>{t('cards.details.body.process')}:</b>{' '}
      <abbr
        title={`${process?.name} (${process?.version}) (${process?.id.toString()})`}
      >
        {process?.name} ({process?.version})
      </abbr>
      <br />
      <b>{t('cards.details.body.queue')}:</b>{' '}
      <abbr
        title={`${queue?.queueName} ${queue?.queueAlias ? `(${queue.queueAlias}) ` : ''}(${queue?.queueId.toString()})`}
      >
        {queue?.queueAlias || queue?.queueName}
      </abbr>
      <br />
      <b>{t('cards.details.body.reference_id')}:</b>{' '}
      <abbr
        title={`${workItem?.workItemReferenceId} (${workItem?.workItemId?.toString()})`}
      >
        {workItem?.workItemReferenceId}
      </abbr>
    </ContentCard>
  );
};
