/**
 * @File FolderSection.tsx - Section within the DetailsFolderPanel responsible for document management operations.
 * Provides a toolbar of permission-gated action buttons (upload, duplicate, merge, rotate, download, print, delete), a drag-and-drop file upload dropzone, and the FolderTree for browsing/selecting documents.
 * Coordinates document deletion by switching the selected node before removing the document from state to avoid rendering stale data.
 */

import {
  useEffect,
  useMemo,
  useRef,
  useState,
  type FC,
  type RefObject,
} from 'react';
import { AtAllowRights } from '../../../../../types/atAllowRights.ts';
import { Button, OverlayTrigger, Tooltip } from 'react-bootstrap';
import { Icon } from '../../../../Icon.tsx';
import {
  FileUploadDropzone,
  type FileUploadDropzoneHandle,
} from './FileUploadDropzone.tsx';
import { FolderTree } from './FolderTree.tsx';
import { ContentCard } from '../../../../ContentCard.tsx';
import { useProcessPermissions } from '../../../../../contexts/ProcessPermissionsContext.tsx';
import { useDocument } from '../../../../../contexts/DocumentContext.tsx';
import { useWorkItem } from '../../../../../contexts/WorkItemContext.tsx';
import type { DocumentNode, FolderNode } from './FolderTree.tsx';
import type { WorkItem } from '../../../../../api/workItem.ts';
import { useProcessingUI } from '../../../../../contexts/ProcessingUIContext.tsx';
import { type Document } from '../../../../../api/document.ts';
import { sortDocumentNodesWithSplitHierarchy } from '../../../../../utils/splitDocumentNames.ts';
import {
  deleteDocument,
  type DocumentLevelActionsProps,
  duplicateDocument,
  mergeDocumentWithPrevious,
  printDocument,
  rotateDocument,
  uploadDocument,
} from '../../../../../utils/documentLevelActions.ts';
import type { PdfViewerComponent } from '@syncfusion/ej2-react-pdfviewer';
import { DeleteDocumentModal } from './DeleteDocumentModal.tsx';
import { useFolderSectionHotkeys } from '../../../../../hooks/hotkeys/useFolderSectionHotkeys.ts';
import { useTranslation } from 'react-i18next';

/**
 * Folder section within Details/Folder panel that displays document action buttons, a file upload dropzone, and the work item folder tree.
 * Buttons are controlled by process-level permissions (AtAllowRights).
 */
export const FolderSection: FC = () => {
  // Required contexts for work item processing
  const {
    process,
    workItem,
    setWorkItem,
    documentTemplates,
    documents,
    setDocuments,
  } = useWorkItem();
  const {
    selectedDocumentId,
    documentActionButtonsDisabled,
    setDocumentActionButtonsDisabled,
    deleteDocumentButtonDisabled,
    setDeleteDocumentButtonDisabled,
    pdfViewerRef,
    setDocumentIsLoading,
    setSelectedDocumentContentHasChanged,
  } = useDocument();
  const { selectedNode, setSelectedNode, setSelectedNodeFieldsHaveChanged } =
    useProcessingUI();
  const { hasPermission, hasAllPermissions } = useProcessPermissions();

  // Assemble FolderNode based on work item
  const folderNode = useMemo(() => {
    return {
      folderId: workItem?.workItemReferenceId,
      folderName: workItem?.description,
    } as FolderNode;
  }, [workItem]);
  // Function updates the name of the work item
  const updateFolderName = (newName: string) => {
    setWorkItem({ ...(workItem as WorkItem), description: newName });
  };

  // Assemble DocumentNodes based on documents
  // Recalculates on change to documents (which may never happen)
  const documentNodes = useMemo(() => {
    const nodes: DocumentNode[] = [];
    documents.forEach((document) => {
      nodes.push({
        documentId: document.documentId,
        documentName: document.documentName,
      });
    });
    return sortDocumentNodesWithSplitHierarchy(nodes);
  }, [documents]);
  // Function updates the names of documents in the parent component
  const updateDocumentNames = (newDocumentNodes: DocumentNode[]) => {
    setDocuments(
      documents.map((document, index) => {
        if (
          newDocumentNodes[index].documentId === selectedDocumentId &&
          pdfViewerRef.current
        ) {
          pdfViewerRef.current.fileName = newDocumentNodes[index].documentName;
          pdfViewerRef.current.downloadFileName =
            newDocumentNodes[index].documentName;
        }
        return {
          ...document,
          documentName: newDocumentNodes[index].documentName,
        };
      })
    );
  };

  // Automatically select folder node on page load
  useEffect(() => {
    setSelectedNodeFieldsHaveChanged(false);
    setSelectedNode(folderNode);
  }, [setSelectedNode]);

  // State variables and functions for file drop zone
  const uploadDocumentDropzoneRef = useRef<FileUploadDropzoneHandle>(null);
  const [uploadDocumentProcessing, setUploadDocumentProcessing] =
    useState(false);

  // State variables and functions for "Delete Document" modal
  const [deleteDocumentModalShown, setDeleteDocumentModalShown] =
    useState(false);
  const [deleteDocumentProcessing, setDeleteDocumentProcessing] =
    useState(false);
  const showDeleteDocumentModal = () => {
    setDeleteDocumentModalShown(true);
  };
  const hideDeleteDocumentModal = () => {
    setDeleteDocumentModalShown(false);
  };

  // Two-phase document deletion: first switch to the folder node, then remove the document
  // This ensures the PDF viewer unloads the deleted document before it's removed from state
  const [documentIdToDelete, setDocumentIdToDelete] = useState<
    number | undefined
  >(undefined);
  useEffect(() => {
    if (
      selectedNode &&
      folderNode &&
      (selectedNode as FolderNode).folderId === folderNode.folderId &&
      documentIdToDelete
    ) {
      // Unload the viewer since the document is being removed
      pdfViewerRef.current?.unload();

      const deletedIndex = documentNodes.indexOf(
        documentNodes.find(
          (document) => document.documentId === documentIdToDelete
        ) as DocumentNode
      );
      const newDocuments = documents.filter(
        (document) => document.documentId !== documentIdToDelete
      );

      setDocuments(newDocuments);
      setDocumentIdToDelete(undefined);

      // Auto-select the next available document after deletion
      if (newDocuments.length) {
        const nextDocumentIndex =
          deletedIndex === 0 ? 1 : Math.max(0, deletedIndex - 1);
        setSelectedNode(documentNodes[nextDocumentIndex]);
      }
    }
  }, [selectedNode, documentIdToDelete]);

  // Document level action properties
  const documentLevelActionProps: DocumentLevelActionsProps = {
    process,
    workItem,
    documents,
    setDocuments,
    documentTemplates,
    folderNode,
    documentNodes,
    selectedNode,
    setSelectedNode,
    selectedDocumentId,
    setSelectedDocumentContentHasChanged,
    pdfViewerRef: pdfViewerRef as RefObject<PdfViewerComponent>,
    setUploadDocumentProcessing,
    setDocumentIsLoading,
    setDocumentActionButtonsDisabled,
    setDeleteDocumentButtonDisabled,
    setDocumentIdToDelete,
    setDeleteDocumentProcessing,
    hideDeleteDocumentModal,
  };
  const handleDragDropAccepted = (file: File) => {
    uploadDocument(documentLevelActionProps, file);
  };

  // Call custom hook for FolderSection hotkeys
  useFolderSectionHotkeys({
    documentActionButtonsDisabled,
    uploadDocumentDropzoneRef:
      uploadDocumentDropzoneRef as RefObject<FileUploadDropzoneHandle>,
    documentLevelActionProps,
    pdfViewerRef: pdfViewerRef as RefObject<PdfViewerComponent>,
    showDeleteDocumentModal,
  });

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

  return (
    <>
      <ContentCard
        headerContent={{
          title: t('cards.folder.header.title'),
          rightAlignedContent: {
            content: (
              <div className={'d-flex flex-wrap justify-content-end gap-2'}>
                {hasPermission(AtAllowRights.AttachDocument) && (
                  <OverlayTrigger
                    placement={'top'}
                    overlay={
                      <Tooltip className={'position-fixed'}>
                        {t(
                          'cards.folder.header.right_aligned_content.buttons.upload.tooltip'
                        )}
                      </Tooltip>
                    }
                  >
                    <Button
                      variant={'outline-primary'}
                      onClick={() => {
                        uploadDocumentDropzoneRef.current?.open();
                      }}
                    >
                      <div
                        className={
                          'd-flex justify-content-center align-items-center'
                        }
                      >
                        <Icon iconName={'Upload'} />
                      </div>
                    </Button>
                  </OverlayTrigger>
                )}
                {hasAllPermissions([
                  AtAllowRights.AttachDocument,
                  AtAllowRights.EditDocument,
                ]) && (
                  <>
                    <OverlayTrigger
                      placement={'top'}
                      overlay={
                        <Tooltip className={'position-fixed'}>
                          {t(
                            'cards.folder.header.right_aligned_content.buttons.duplicate.tooltip'
                          )}
                        </Tooltip>
                      }
                    >
                      <Button
                        variant={'outline-primary'}
                        disabled={documentActionButtonsDisabled}
                        onClick={() =>
                          duplicateDocument(documentLevelActionProps)
                        }
                      >
                        <div
                          className={
                            'd-flex justify-content-center align-items-center'
                          }
                        >
                          <Icon iconName={'Files'} />
                        </div>
                      </Button>
                    </OverlayTrigger>
                    <OverlayTrigger
                      placement={'top'}
                      overlay={
                        <Tooltip className={'position-fixed'}>
                          {t(
                            'cards.folder.header.right_aligned_content.buttons.merge.tooltip'
                          )}
                        </Tooltip>
                      }
                    >
                      <Button
                        variant={'outline-primary'}
                        onClick={() =>
                          mergeDocumentWithPrevious(documentLevelActionProps)
                        }
                        disabled={
                          documentActionButtonsDisabled ||
                          !documents.indexOf(
                            documents.find(
                              (document) =>
                                document.documentId === selectedDocumentId
                            ) as Document
                          )
                        }
                      >
                        <div
                          className={
                            'd-flex justify-content-center align-items-center'
                          }
                        >
                          <Icon iconName={'Intersect'} />
                        </div>
                      </Button>
                    </OverlayTrigger>
                  </>
                )}
                {hasPermission(AtAllowRights.EditDocument) && (
                  <OverlayTrigger
                    placement={'top'}
                    overlay={
                      <Tooltip className={'position-fixed'}>
                        {t(
                          'cards.folder.header.right_aligned_content.buttons.rotate.tooltip'
                        )}
                      </Tooltip>
                    }
                  >
                    <Button
                      variant={'outline-primary'}
                      disabled={documentActionButtonsDisabled}
                      onClick={() => rotateDocument(documentLevelActionProps)}
                    >
                      <div
                        className={
                          'd-flex justify-content-center align-items-center'
                        }
                      >
                        <Icon iconName={'ArrowClockwise'} />
                      </div>
                    </Button>
                  </OverlayTrigger>
                )}
                {hasPermission(AtAllowRights.DownloadDocument) && (
                  <>
                    <OverlayTrigger
                      placement={'top'}
                      overlay={
                        <Tooltip className={'position-fixed'}>
                          {t(
                            'cards.folder.header.right_aligned_content.buttons.download.tooltip'
                          )}
                        </Tooltip>
                      }
                    >
                      <Button
                        variant={'outline-primary'}
                        disabled={documentActionButtonsDisabled}
                        onClick={() => {
                          if (selectedDocumentId) {
                            pdfViewerRef.current?.download();
                          }
                        }}
                      >
                        <div
                          className={
                            'd-flex justify-content-center align-items-center'
                          }
                        >
                          <Icon iconName={'Download'} />
                        </div>
                      </Button>
                    </OverlayTrigger>
                    <OverlayTrigger
                      placement={'top'}
                      overlay={
                        <Tooltip className={'position-fixed'}>
                          {t(
                            'cards.folder.header.right_aligned_content.buttons.print.tooltip'
                          )}
                        </Tooltip>
                      }
                    >
                      <Button
                        variant={'outline-primary'}
                        disabled={documentActionButtonsDisabled}
                        onClick={() => printDocument(documentLevelActionProps)}
                      >
                        <div
                          className={
                            'd-flex justify-content-center align-items-center'
                          }
                        >
                          <Icon iconName={'Printer'} />
                        </div>
                      </Button>
                    </OverlayTrigger>
                  </>
                )}
                {hasPermission(AtAllowRights.DeleteDocument) && (
                  <OverlayTrigger
                    placement={'top'}
                    overlay={
                      <Tooltip className={'position-fixed'}>
                        {t(
                          'cards.folder.header.right_aligned_content.buttons.delete.tooltip'
                        )}
                      </Tooltip>
                    }
                  >
                    <Button
                      variant={'outline-danger'}
                      disabled={
                        documentActionButtonsDisabled &&
                        deleteDocumentButtonDisabled
                      }
                      onClick={() => {
                        showDeleteDocumentModal();
                      }}
                    >
                      <div
                        className={
                          'd-flex justify-content-center align-items-center'
                        }
                      >
                        <Icon iconName={'Trash'} />
                      </div>
                    </Button>
                  </OverlayTrigger>
                )}
              </div>
            ),
          },
        }}
        fillPage
      >
        {hasPermission(AtAllowRights.AttachDocument) && (
          <>
            <FileUploadDropzone
              ref={uploadDocumentDropzoneRef}
              onFileAccepted={handleDragDropAccepted}
              processing={uploadDocumentProcessing}
            />
            <hr />
          </>
        )}
        <FolderTree
          folderNode={folderNode}
          updateFolderName={updateFolderName}
          documentNodes={documentNodes}
          updateDocumentNames={updateDocumentNames}
        />
      </ContentCard>

      {/* Delete document confirmation modal */}
      <DeleteDocumentModal
        show={deleteDocumentModalShown}
        onHide={hideDeleteDocumentModal}
        onDelete={() => deleteDocument(documentLevelActionProps)}
        processing={deleteDocumentProcessing}
      />
    </>
  );
};
