"use client";

import type { ReactNode } from "react";
import {
  TreeShellIframeHost,
  type TreeShellPickerItem,
} from "@/components/sidebar/tree-shell-iframe-host";
import type { FileTreeRow } from "@/lib/file-tree/types";
import { cn } from "@/lib/utils";

export type TreeRendererFamily = "react" | "rust_family";

export type TreeShellHostMode = "page" | "filetree" | "picker";

type TreeShellHostProps = {
  mode: TreeShellHostMode;
  surfaceTestId: string;
  rendererFamily?: TreeRendererFamily;
  className?: string;
  treeShellEnabled?: boolean;
  workspaceId?: string | null;
  rootNodeId?: string | null;
  activeDocumentId?: string | null;
  allowRootPick?: boolean;
  excludeIds?: string[];
  pickerItems?: TreeShellPickerItem[];
  fileTreeRows?: FileTreeRow[];
  channel?: string;
  host?: string;
  onNavigate?: (documentId: string) => void;
  onPick?: (targetId: string | null) => void;
  onPageContextMenu?: (payload: { documentId: string; x: number; y: number }) => void;
  onFileTreeContextMenu?: (payload: {
    documentId: string | null;
    assetId: string | null;
    rowId: string | null;
    rowKind: string | null;
    x: number;
    y: number;
  }) => void;
  onFileTreeSelectionChange?: (payload: {
    selectedRowIds: string[];
    anchorRowId: string | null;
    focusedRowId: string | null;
  }) => void;
  onInternalDrop?: (args: { targetRow: FileTreeRow; rowIds: string[]; copy: boolean }) => void;
  onDropFiles?: (docId: string, files: FileList | File[], targetRow?: FileTreeRow) => void;
  onAssetOpen?: (payload: { assetId: string; documentId: string | null }) => void;
  onTreeMutation?: (payload: { type: string; documentId: string | null }) => void;
  children: ReactNode;
};

export function TreeShellHost({
  mode,
  surfaceTestId,
  rendererFamily = "react",
  className,
  treeShellEnabled = true,
  workspaceId = null,
  rootNodeId = null,
  activeDocumentId = null,
  allowRootPick = false,
  excludeIds = [],
  pickerItems = [],
  fileTreeRows = [],
  channel,
  host,
  onNavigate,
  onPick,
  onPageContextMenu,
  onFileTreeContextMenu,
  onFileTreeSelectionChange,
  onInternalDrop,
  onDropFiles,
  onAssetOpen,
  onTreeMutation,
  children,
}: TreeShellHostProps) {
  const useRustHost = rendererFamily === "rust_family";
  const useIframeHost = useRustHost && treeShellEnabled && Boolean(workspaceId?.trim());
  const hostKind = rendererFamily === "rust_family" ? "rust_family" : "react";
  const implementation = useIframeHost
    ? "mnote_web_iframe_proxy"
    : rendererFamily === "rust_family"
      ? "react_fallback"
      : "react_primary";

  return (
    <div
      data-testid={surfaceTestId}
      data-shell-mode={mode}
      data-renderer-family={rendererFamily}
      data-tree-host-kind={hostKind}
      data-tree-host-implementation={implementation}
      className={cn(className)}
    >
      {useRustHost ? (
        <div
          data-testid={`${surfaceTestId}-rust-host`}
          data-tree-host-mode={mode}
          data-tree-host-kind="rust_family"
          data-tree-host-implementation={implementation}
          className="contents"
        >
          {useIframeHost && workspaceId ? (
            <TreeShellIframeHost
              mode={mode}
              surfaceTestId={surfaceTestId}
              workspaceId={workspaceId}
              rootNodeId={rootNodeId}
              activeDocumentId={activeDocumentId}
              allowRootPick={allowRootPick}
              excludeIds={excludeIds}
              pickerItems={pickerItems}
              fileTreeRows={fileTreeRows}
              channel={channel}
              host={host}
              onNavigate={onNavigate}
              onPick={onPick}
              onPageContextMenu={onPageContextMenu}
              onFileTreeContextMenu={onFileTreeContextMenu}
              onFileTreeSelectionChange={onFileTreeSelectionChange}
              onInternalDrop={onInternalDrop}
              onDropFiles={onDropFiles}
              onAssetOpen={onAssetOpen}
              onTreeMutation={onTreeMutation}
            />
          ) : (
            children
          )}
        </div>
      ) : (
        children
      )}
    </div>
  );
}
