import React, { useRef } from 'react';

import { usePanelManager, usePanelResizeBindings } from '../app/PanelManagerContext';
import type { StatusMessage } from '../hooks/documents/store/useDocumentsStore';
import type { Identifier } from '../types/identifiers';

import SidebarFolderList from './components/SidebarFolderList';
import SidebarTagList, { TagEntry } from './components/SidebarTagList';
import SidebarCorrespondentList, { CorrespondentEntry } from './components/SidebarCorrespondentList';
import { FolderIdentifier, FolderTreeNode } from './components/SidebarFolderNode';
import { TenantOption } from './components/SidebarMenu';
import SidebarHeader from './components/SidebarHeader';
import SidebarSearch from './components/SidebarSearch';

type UploadHandler = (
  files: FileList | File[] | Iterable<File>,
  targetFolderId?: FolderIdentifier | null,
) => void;

interface SidebarProps {
  folderNodes: Map<FolderIdentifier, FolderTreeNode>;
  onToggle: (folderId: FolderIdentifier) => void;
  onSelect: (folderId: FolderIdentifier) => void;
  onDrop: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
  onDragOver: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
  onDragLeave: (event: React.DragEvent<HTMLDivElement>) => void;
  onDeleteFolder: (folderId: FolderIdentifier) => void;
  onRenameFolder?: (folderId: FolderIdentifier, name: string) => void;
  selectedFolder?: FolderIdentifier | null;
  onFolderDragStart?: (event: React.DragEvent<HTMLDivElement>, folderId: FolderIdentifier) => void;
  onFolderDragEnd?: (event: React.DragEvent<HTMLDivElement>) => void;
  draggedFolderId?: FolderIdentifier | null;
  onCreateFolder?: (parentId?: FolderIdentifier | null) => void;
  creatingFolder?: boolean;
  tags?: TagEntry[];
  untaggedFilterId?: Identifier | null;
  correspondents?: CorrespondentEntry[];
  onManageTags?: () => void;
  onManageCorrespondents?: () => void;
  onCreateTag?: (label: string) => Promise<void> | void;
  onCreateCorrespondent?: (name: string) => Promise<void> | void;
  onLogout?: () => void;
  status?: StatusMessage | null;
  tenantName?: string | null;
  tenants?: TenantOption[];
  activeTenantId?: Identifier | null;
  onSelectTenant?: (tenant: TenantOption | null, options?: { refreshOnly?: boolean }) => void;
  onOpenSettings?: () => void;
  onUploadFiles?: UploadHandler;
}

const Sidebar: React.FC<SidebarProps> = ({
  folderNodes,
  onToggle,
  onSelect,
  onDrop,
  onDragOver,
  onDragLeave,
  onDeleteFolder,
  onRenameFolder,
  selectedFolder = null,
  onFolderDragStart,
  onFolderDragEnd,
  draggedFolderId = null,
  onCreateFolder,
  creatingFolder = false,
  tags = [],
  untaggedFilterId = null,
  correspondents = [],
  onManageTags,
  onManageCorrespondents,
  onCreateTag,
  onCreateCorrespondent,
  onLogout,
  status = null,
  tenantName,
  tenants = [],
  activeTenantId = null,
  onSelectTenant,
  onOpenSettings,
  onUploadFiles,
}) => {
  const {
    sidebarSuppressed,
  } = usePanelManager();

  const sidebarRef = useRef<HTMLDivElement | null>(null);
  const {
    panelStyle: sidebarStyle,
    handleProps: sidebarHandleProps,
    isPanelResizing: isResizingSidebar,
  } = usePanelResizeBindings('sidebar', { panelRef: sidebarRef });

  const sidebarClassNames = ['sidebar'];
  if (isResizingSidebar) {
    sidebarClassNames.push('sidebar--resizing');
  }
  if (sidebarSuppressed) {
    sidebarClassNames.push('sidebar--suppressed');
  }

  return (
    <aside className={sidebarClassNames.join(' ')} ref={sidebarRef} style={sidebarStyle}>
      <button
        type="button"
        className={`sidebar__resize-handle${isResizingSidebar ? ' is-active' : ''}`}
        aria-label="Resize sidebar"
        {...sidebarHandleProps}
      >
        <span aria-hidden="true" />
      </button>

      <SidebarHeader
        tenantName={tenantName}
        tenants={tenants}
        activeTenantId={activeTenantId}
        onSelectTenant={onSelectTenant}
        onOpenSettings={onOpenSettings}
        onLogout={onLogout}
        onUploadFiles={onUploadFiles}
        selectedFolder={selectedFolder}
      />

      <div className="panel-body sidebar__body">
        {status && (
          <div className="sidebar__status">
            <div className={`status-banner ${status.variant}`}>{status.message}</div>
          </div>
        )}

        <SidebarSearch />

        <SidebarFolderList
          folderNodes={folderNodes}
          selectedFolder={selectedFolder}
          onToggle={onToggle}
          onSelect={onSelect}
          onDrop={onDrop}
          onDragOver={onDragOver}
          onDragLeave={onDragLeave}
          onDeleteFolder={onDeleteFolder}
          onRenameFolder={onRenameFolder}
          onFolderDragStart={onFolderDragStart}
          onFolderDragEnd={onFolderDragEnd}
          draggedFolderId={draggedFolderId}
          onCreateFolder={onCreateFolder}
          creatingFolder={creatingFolder}
        />

        <SidebarTagList
          tags={tags}
          untaggedFilterId={untaggedFilterId}
          onCreateTag={onCreateTag}
          onManageTags={onManageTags}
        />

        <SidebarCorrespondentList
          correspondents={correspondents}
          onCreateCorrespondent={onCreateCorrespondent}
          onManageCorrespondents={onManageCorrespondents}
        />
      </div>
    </aside>
  );
};

export default Sidebar;
