/**
 * SharepointBrowseTree – Lazy-loading tree for SharePoint browse.
 * Same look & feel as FolderTree (chevron, FaFolder/FaFolderOpen, styling).
 * Loads children on expand via onLoadChildren(path).
 */

import React, { useState, useCallback, useEffect } from 'react';
import { FaFolder, FaFolderOpen, FaChevronRight, FaGlobe } from 'react-icons/fa';
import styles from './FolderTree.module.css';

export interface BrowseEntry {
  name: string;
  path: string;
  isFolder: boolean;
  size?: number;
  mimeType?: string;
  metadata?: Record<string, unknown>;
}

export interface SharepointBrowseTreeProps {
  /** Root path (usually "/") - children loaded via onLoadChildren */
  rootPath?: string;
  /** Load children for a given path. Returns folders and files. */
  onLoadChildren: (path: string) => Promise<BrowseEntry[]>;
  /** Called when user selects a file path */
  onSelectFile: (path: string) => void;
  /** Called when user selects a folder path (e.g. for destination). If provided, folder rows are selectable. */
  onSelectFolder?: (path: string) => void;
  /** Currently selected path (for highlight) */
  selectedPath?: string | null;
  /** Optional: pre-seed root children (e.g. from initial load) */
  initialChildren?: BrowseEntry[];
}

function _fileIcon(mime?: string): string {
  if (!mime) return '\uD83D\uDCC4';
  if (mime.startsWith('image/')) return '\uD83D\uDDBC\uFE0F';
  if (mime.includes('pdf')) return '\uD83D\uDCD5';
  if (mime.includes('word') || mime.includes('docx')) return '\uD83D\uDCD8';
  if (mime.includes('sheet') || mime.includes('xlsx') || mime.includes('csv')) return '\uD83D\uDCCA';
  if (mime.includes('presentation') || mime.includes('pptx')) return '\uD83D\uDCD9';
  if (mime.includes('zip') || mime.includes('tar') || mime.includes('gz')) return '\uD83D\uDCE6';
  if (mime.startsWith('text/') || mime.includes('json') || mime.includes('xml')) return '\uD83D\uDCDD';
  return '\uD83D\uDCC4';
}

/* ── File row ──────────────────────────────────────────────────────────── */

function _FileRow({
  entry,
  selectedPath,
  onSelect,
}: {
  entry: BrowseEntry;
  selectedPath: string | null | undefined;
  onSelect: (path: string) => void;
}) {
  const isSelected = selectedPath === entry.path;

  return (
    <div
      className={`${styles.treeNode} ${styles.fileNode} ${isSelected ? styles.selected : ''}`}
      onClick={() => onSelect(entry.path)}
      title={entry.path}
    >
      <span className={styles.chevron + ' ' + styles.empty} />
      <span className={styles.fileIcon}>{_fileIcon(entry.mimeType)}</span>
      <span className={styles.folderName}>{entry.name}</span>
      {entry.size != null && (
        <span className={styles.fileSize}>
          {(entry.size / 1024).toFixed(0)}K
        </span>
      )}
    </div>
  );
}

/* ── Folder row (expandable, lazy-loads children) ───────────────────────── */

function _FolderRow({
  entry,
  selectedPath,
  expandedPaths,
  loadedChildren,
  loadingPaths,
  onToggle,
  onSelectFile,
  onSelectFolder,
}: {
  entry: BrowseEntry;
  selectedPath: string | null | undefined;
  expandedPaths: Set<string>;
  loadedChildren: Record<string, BrowseEntry[]>;
  loadingPaths: Set<string>;
  onToggle: (path: string) => void;
  onSelectFile: (path: string) => void;
  onSelectFolder?: (path: string) => void;
}) {
  const isExpanded = expandedPaths.has(entry.path);
  const isSelected = selectedPath === entry.path;
  const children = loadedChildren[entry.path] ?? [];
  const folders = children.filter((c) => c.isFolder).sort((a, b) => a.name.localeCompare(b.name));
  const files = children.filter((c) => !c.isFolder).sort((a, b) => a.name.localeCompare(b.name));
  const isLoading = isExpanded && loadingPaths.has(entry.path);

  const handleRowClick = (e: React.MouseEvent) => {
    const target = e.target as HTMLElement;
    if (target.closest(`.${styles.chevron}`)) return;
    if (onSelectFolder) {
      onSelectFolder(entry.path);
      return;
    }
    onToggle(entry.path);
  };

  const handleChevronClick = (e: React.MouseEvent) => {
    e.stopPropagation();
    onToggle(entry.path);
  };

  return (
    <div>
      <div
        className={`${styles.treeNode} ${onSelectFolder && isSelected ? styles.selected : ''}`}
        onClick={handleRowClick}
        title={entry.path}
      >
        <span
          className={`${styles.chevron} ${isExpanded ? styles.expanded : ''}`}
          onClick={handleChevronClick}
          title={isExpanded ? 'Einklappen' : 'Erweitern'}
        >
          <FaChevronRight />
        </span>
        <span className={styles.folderIcon}>
          {isExpanded ? <FaFolderOpen /> : <FaFolder />}
        </span>
        <span className={styles.folderName}>{entry.name}</span>
        {isLoading && (
          <span style={{ fontSize: 10, color: 'var(--color-text-secondary,#999)', marginLeft: 4 }}>…</span>
        )}
      </div>
      {isExpanded && (
        <div className={styles.children}>
          {isLoading ? (
            <div style={{ padding: '0.5rem 1rem', fontSize: '0.8rem', color: 'var(--color-text-secondary,#666)' }}>
              Wird geladen…
            </div>
          ) : (
            <>
              {folders.map((child) => (
                <_FolderRow
                  key={child.path}
                  entry={child}
                  selectedPath={selectedPath}
                  expandedPaths={expandedPaths}
                  loadedChildren={loadedChildren}
                  loadingPaths={loadingPaths}
                  onToggle={onToggle}
                  onSelectFile={onSelectFile}
                  onSelectFolder={onSelectFolder}
                />
              ))}
              {files.map((child) => (
                <_FileRow
                  key={child.path}
                  entry={child}
                  selectedPath={selectedPath}
                  onSelect={onSelectFile}
                />
              ))}
              {children.length === 0 && (
                <div style={{ padding: '0.4rem 1rem', fontSize: '0.8rem', color: 'var(--color-text-secondary,#999)' }}>
                  Leer
                </div>
              )}
            </>
          )}
        </div>
      )}
    </div>
  );
}

/* ── Root component ─────────────────────────────────────────────────────── */

export function SharepointBrowseTree({
  rootPath = '/',
  onLoadChildren,
  onSelectFile,
  onSelectFolder,
  selectedPath,
  initialChildren = [],
}: SharepointBrowseTreeProps) {
  const [expandedPaths, setExpandedPaths] = useState<Set<string>>(new Set([rootPath]));
  const [loadedChildren, setLoadedChildren] = useState<Record<string, BrowseEntry[]>>(() =>
    initialChildren.length > 0 ? { [rootPath]: initialChildren } : {}
  );
  const [loadingPaths, setLoadingPaths] = useState<Set<string>>(new Set());

  const loadPath = useCallback(
    async (path: string) => {
      setLoadingPaths((p) => new Set(p).add(path));
      try {
        const items = await onLoadChildren(path);
        setLoadedChildren((prev) => ({ ...prev, [path]: items }));
      } catch {
        setLoadedChildren((prev) => ({ ...prev, [path]: [] }));
      } finally {
        setLoadingPaths((p) => {
          const next = new Set(p);
          next.delete(path);
          return next;
        });
      }
    },
    [onLoadChildren]
  );

  const handleToggle = useCallback(
    (path: string) => {
      setExpandedPaths((prev) => {
        const next = new Set(prev);
        if (next.has(path)) {
          next.delete(path);
        } else {
          next.add(path);
          loadPath(path);
        }
        return next;
      });
    },
    [loadPath]
  );

  useEffect(() => {
    if (rootPath in loadedChildren) return;
    if (initialChildren.length > 0) return;
    loadPath(rootPath);
  }, [rootPath, initialChildren.length, loadPath]);

  const rootItems = loadedChildren[rootPath] ?? [];
  const rootLoading = loadingPaths.has(rootPath);
  const rootFolders = rootItems.filter((e) => e.isFolder).sort((a, b) => a.name.localeCompare(b.name));
  const rootFiles = rootItems.filter((e) => !e.isFolder).sort((a, b) => a.name.localeCompare(b.name));
  const isRootExpanded = expandedPaths.has(rootPath);

  return (
    <div className={styles.folderTree}>
      <div
        className={`${styles.treeNode} ${selectedPath === null || selectedPath === undefined ? styles.selected : ''}`}
        style={{ fontWeight: 600 }}
      >
        <span
          className={`${styles.chevron} ${isRootExpanded ? styles.expanded : ''}`}
          onClick={() => handleToggle(rootPath)}
        >
          <FaChevronRight />
        </span>
        <span className={styles.folderIcon}><FaGlobe /></span>
        <span className={`${styles.folderName} ${styles.rootLabel}`}>SharePoint</span>
        {rootLoading && (
          <span style={{ fontSize: 10, color: 'var(--color-text-secondary,#999)', marginLeft: 4 }}>…</span>
        )}
      </div>
      {isRootExpanded && (
        <div className={styles.children}>
          {rootLoading ? (
            <div style={{ padding: '0.5rem 1rem', fontSize: '0.8rem', color: 'var(--color-text-secondary,#666)' }}>
              Sites werden geladen…
            </div>
          ) : (
            <>
              {rootFolders.map((entry) => (
                <_FolderRow
                  key={entry.path}
                  entry={entry}
                  selectedPath={selectedPath}
                  expandedPaths={expandedPaths}
                  loadedChildren={loadedChildren}
                  loadingPaths={loadingPaths}
                  onToggle={handleToggle}
                  onSelectFile={onSelectFile}
                  onSelectFolder={onSelectFolder}
                />
              ))}
              {rootFiles.map((entry) => (
                <_FileRow
                  key={entry.path}
                  entry={entry}
                  selectedPath={selectedPath}
                  onSelect={onSelectFile}
                />
              ))}
              {rootItems.length === 0 && !rootLoading && (
                <div style={{ padding: '0.5rem 1rem', fontSize: '0.8rem', color: 'var(--color-text-secondary,#999)' }}>
                  Keine Einträge
                </div>
              )}
            </>
          )}
        </div>
      )}
    </div>
  );
}
