/**
 * @file CloseWorkItemModal.tsx - Modal displayed when the user attempts to close or leave a work item that has unsaved changes.
 * Offers three options: cancel, discard changes, or save changes.
 * Handles reauthentication interruption by capturing and restoring the close-lifecycle state (closeWorkItem, saveWorkItem, field/document change flags) so the close operation can resume after reauthentication completes.
 * Enter key triggers the save action.
 */

import { useDocument } from '../../../contexts/DocumentContext.tsx';
import { useProcessingUI } from '../../../contexts/ProcessingUIContext.tsx';
import { useEffect, useState } from 'react';
import { Key } from 'ts-key-enum';
import { Button, Modal } from 'react-bootstrap';
import { useReauthModalSuspension } from '../../../hooks/modals/useReauthModalSuspension.ts';
import { useTranslation } from 'react-i18next';

/** Snapshot of close-lifecycle state, used to restore state after reauthentication interruption. */
type InterruptedCloseState = {
  closeWorkItem: boolean;
  saveWorkItem: boolean;
  selectedNodeFieldsHaveChanged: boolean;
  selectedDocumentContentHasChanged: boolean;
};

/**
 * Close Work Item modal that may appear when attempting to close a work item with unsaved changes.
 * Supports save, discard, and cancel actions, with reauthentication interruption recovery.
 */
export const CloseWorkItemModal = () => {
  const {
    setSelectedDocumentContentHasChanged,
    selectedDocumentContentHasChanged,
  } = useDocument();
  const {
    closeWorkItemModalShown,
    hideCloseWorkItemModal,
    setSaveWorkItem,
    setCloseWorkItem,
    setSelectedNodeFieldsHaveChanged,
    workItemClosed,
    closeWorkItem,
    saveWorkItem,
    selectedNodeFieldsHaveChanged,
  } = useProcessingUI();

  // Capture close-lifecycle state before user action so it can be restored if reauthentication interrupts
  const [interruptedCloseState, setInterruptedCloseState] =
    useState<InterruptedCloseState>({
      closeWorkItem,
      saveWorkItem,
      selectedNodeFieldsHaveChanged,
      selectedDocumentContentHasChanged,
    });
  const updateInterruptedCloseState = () => {
    setInterruptedCloseState({
      closeWorkItem,
      saveWorkItem,
      selectedNodeFieldsHaveChanged,
      selectedDocumentContentHasChanged,
    });
  };

  // Discard: clear all change flags and trigger close without saving
  const discardChanges = () => {
    updateInterruptedCloseState();

    setCloseWorkItem(true);
    setSelectedNodeFieldsHaveChanged(false);
    setSelectedDocumentContentHasChanged(false);
  };
  // Save: trigger both save and close so changes are persisted before unlocking
  const saveChanges = () => {
    updateInterruptedCloseState();

    setSaveWorkItem(true);
    setCloseWorkItem(true);
  };

  const modalSuspensionState = useReauthModalSuspension(
    closeWorkItemModalShown
  );

  useEffect(() => {
    if (!closeWorkItemModalShown || modalSuspensionState === 'suspended') {
      return;
    }

    // Enter key triggers save confirmation
    const handleKeyDown = (event: KeyboardEvent) => {
      if (event.key === Key.Enter) {
        event.preventDefault();
        saveChanges();
      }
    };

    window.addEventListener('keydown', handleKeyDown);
    return () => window.removeEventListener('keydown', handleKeyDown);
  }, [closeWorkItemModalShown, modalSuspensionState]);

  // When reauthentication suspends this modal, restore the pre-action close state
  // When reauthentication completes and the work item was already closed, auto-hide this modal
  useEffect(() => {
    if (modalSuspensionState === 'suspended' && !workItemClosed) {
      setCloseWorkItem(interruptedCloseState.closeWorkItem);
      setSaveWorkItem(interruptedCloseState.saveWorkItem);
      setSelectedNodeFieldsHaveChanged(
        interruptedCloseState.selectedNodeFieldsHaveChanged
      );
      setSelectedDocumentContentHasChanged(
        interruptedCloseState.selectedDocumentContentHasChanged
      );
    } else if (modalSuspensionState !== 'hidden' && workItemClosed) {
      hideCloseWorkItemModal(true);
    }
  }, [modalSuspensionState, workItemClosed]);

  const { t } = useTranslation(undefined, {
    keyPrefix: 'components.processing.modals.close_work_item',
  });

  return (
    <Modal
      centered
      show={modalSuspensionState !== 'hidden'}
      onHide={hideCloseWorkItemModal}
      className={modalSuspensionState === 'suspended' ? 'suspended' : ''}
    >
      <Modal.Header closeButton>
        <Modal.Title>{t('header.title')}</Modal.Title>
      </Modal.Header>
      <Modal.Body>
        <p>{t('body.intro_text')}</p>
        <p className={'mb-0'}>{t('body.instructions_text')}</p>
      </Modal.Body>
      <Modal.Footer>
        <Button
          variant={'secondary'}
          onClick={() => {
            hideCloseWorkItemModal();
          }}
        >
          {t('footer.buttons.cancel.button_text')}
        </Button>
        <Button variant={'danger'} onClick={discardChanges}>
          {t('footer.buttons.discard_changes.button_text')}
        </Button>
        <Button variant={'success'} onClick={saveChanges}>
          {t('footer.buttons.save_changes.button_text')}
        </Button>
      </Modal.Footer>
    </Modal>
  );
};
