/**
 * FileStructurePanel - Shows study file structure in the canvas sidebar
 *
 * Features:
 * - Tree view of study directory
 * - Highlights model files (.prt, .fem, .sim)
 * - Shows file dependencies
 * - One-click to set as model source
 * - Refresh button to reload
 */

import { useState, useEffect, useCallback } from 'react';
import {
  Folder,
  FolderOpen,
  FileBox,
  ChevronRight,
  RefreshCw,
  Box,
  Cpu,
  FileCode,
  AlertCircle,
  CheckCircle,
  Plus,
} from 'lucide-react';

interface FileNode {
  name: string;
  path: string;
  type: 'file' | 'directory';
  extension?: string;
  size?: number;
  children?: FileNode[];
  isModelFile?: boolean;
  isSelected?: boolean;
}

interface FileStructurePanelProps {
  studyId: string | null;
  onModelSelect?: (filePath: string, fileType: string) => void;
  selectedModelPath?: string;
  className?: string;
}

// File type to icon mapping
const FILE_ICONS: Record<string, { icon: typeof FileBox; color: string }> = {
  '.prt': { icon: Box, color: 'text-blue-400' },
  '.sim': { icon: Cpu, color: 'text-violet-400' },
  '.fem': { icon: FileCode, color: 'text-emerald-400' },
  '.afem': { icon: FileCode, color: 'text-emerald-400' },
  '.dat': { icon: FileBox, color: 'text-amber-400' },
  '.bdf': { icon: FileBox, color: 'text-amber-400' },
  '.op2': { icon: FileBox, color: 'text-rose-400' },
  '.f06': { icon: FileBox, color: 'text-dark-400' },
};

const MODEL_EXTENSIONS = ['.prt', '.sim', '.fem', '.afem'];

export function FileStructurePanel({
  studyId,
  onModelSelect,
  selectedModelPath,
  className = '',
}: FileStructurePanelProps) {
  const [files, setFiles] = useState<FileNode[]>([]);
  const [expandedPaths, setExpandedPaths] = useState<Set<string>>(new Set());
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState<string | null>(null);

  // Load study file structure
  const loadFileStructure = useCallback(async () => {
    if (!studyId) {
      setFiles([]);
      return;
    }

    setIsLoading(true);
    setError(null);

    try {
      const response = await fetch(`/api/files/structure/${encodeURIComponent(studyId)}`);
      
      if (!response.ok) {
        if (response.status === 404) {
          setError('Study not found');
        } else {
          throw new Error(`Failed to load: ${response.status}`);
        }
        setFiles([]);
        return;
      }

      const data = await response.json();
      
      // Process the file tree to mark model files
      const processNode = (node: FileNode): FileNode => {
        if (node.type === 'directory' && node.children) {
          return {
            ...node,
            children: node.children.map(processNode),
          };
        }
        
        const ext = '.' + node.name.split('.').pop()?.toLowerCase();
        return {
          ...node,
          extension: ext,
          isModelFile: MODEL_EXTENSIONS.includes(ext),
          isSelected: node.path === selectedModelPath,
        };
      };

      const processedFiles = (data.files || []).map(processNode);
      setFiles(processedFiles);

      // Auto-expand 1_setup and root directories
      const toExpand = new Set<string>();
      processedFiles.forEach((node: FileNode) => {
        if (node.type === 'directory') {
          toExpand.add(node.path);
          if (node.name === '1_setup' && node.children) {
            node.children.forEach((child: FileNode) => {
              if (child.type === 'directory') {
                toExpand.add(child.path);
              }
            });
          }
        }
      });
      setExpandedPaths(toExpand);
    } catch (err) {
      console.error('Failed to load file structure:', err);
      setError('Failed to load files');
    } finally {
      setIsLoading(false);
    }
  }, [studyId, selectedModelPath]);

  useEffect(() => {
    loadFileStructure();
  }, [loadFileStructure]);

  // Toggle directory expansion
  const toggleExpand = (path: string) => {
    setExpandedPaths((prev) => {
      const next = new Set(prev);
      if (next.has(path)) {
        next.delete(path);
      } else {
        next.add(path);
      }
      return next;
    });
  };

  // Handle file selection
  const handleFileClick = (node: FileNode) => {
    if (node.type === 'directory') {
      toggleExpand(node.path);
    } else if (node.isModelFile && onModelSelect) {
      onModelSelect(node.path, node.extension || '');
    }
  };

  // Render a file/folder node
  const renderNode = (node: FileNode, depth: number = 0) => {
    const isExpanded = expandedPaths.has(node.path);
    const isDirectory = node.type === 'directory';
    const fileInfo = node.extension ? FILE_ICONS[node.extension] : null;
    const Icon = isDirectory
      ? isExpanded
        ? FolderOpen
        : Folder
      : fileInfo?.icon || FileBox;
    const iconColor = isDirectory
      ? 'text-amber-400'
      : fileInfo?.color || 'text-dark-400';

    const isSelected = node.path === selectedModelPath;

    return (
      <div key={node.path}>
        <button
          onClick={() => handleFileClick(node)}
          className={`
            w-full flex items-center gap-2 px-2 py-1.5 text-left text-sm rounded-md
            transition-colors group
            ${isSelected ? 'bg-primary-500/20 text-primary-400' : 'hover:bg-dark-700/50'}
            ${node.isModelFile ? 'cursor-pointer' : isDirectory ? 'cursor-pointer' : 'cursor-default opacity-60'}
          `}
          style={{ paddingLeft: `${depth * 16 + 8}px` }}
        >
          {/* Expand/collapse chevron for directories */}
          {isDirectory ? (
            <ChevronRight
              size={14}
              className={`text-dark-500 transition-transform flex-shrink-0 ${
                isExpanded ? 'rotate-90' : ''
              }`}
            />
          ) : (
            <span className="w-3.5 flex-shrink-0" />
          )}

          {/* Icon */}
          <Icon size={16} className={`${iconColor} flex-shrink-0`} />

          {/* Name */}
          <span
            className={`flex-1 truncate ${
              isSelected ? 'text-primary-400 font-medium' : 'text-dark-200'
            }`}
          >
            {node.name}
          </span>

          {/* Model file indicator */}
          {node.isModelFile && !isSelected && (
            <span title="Set as model">
              <Plus
                size={14}
                className="text-dark-500 opacity-0 group-hover:opacity-100 transition-opacity flex-shrink-0"
              />
            </span>
          )}

          {/* Selected indicator */}
          {isSelected && (
            <CheckCircle size={14} className="text-primary-400 flex-shrink-0" />
          )}
        </button>

        {/* Children */}
        {isDirectory && isExpanded && node.children && (
          <div>
            {node.children.map((child) => renderNode(child, depth + 1))}
          </div>
        )}
      </div>
    );
  };

  // No study selected state
  if (!studyId) {
    return (
      <div className={`p-4 ${className}`}>
        <div className="text-center text-dark-400 text-sm">
          <Folder size={32} className="mx-auto mb-2 text-dark-500" />
          <p>No study selected</p>
          <p className="text-xs text-dark-500 mt-1">
            Load a study to see its files
          </p>
        </div>
      </div>
    );
  }

  return (
    <div className={`flex flex-col h-full ${className}`}>
      {/* Header */}
      <div className="flex items-center justify-between px-3 py-2 border-b border-dark-700">
        <div className="flex items-center gap-2">
          <Folder size={16} className="text-amber-400" />
          <span className="text-sm font-medium text-white">Files</span>
        </div>
        <button
          onClick={loadFileStructure}
          disabled={isLoading}
          className="p-1 rounded hover:bg-dark-700 text-dark-400 hover:text-white transition-colors"
          title="Refresh"
        >
          <RefreshCw size={14} className={isLoading ? 'animate-spin' : ''} />
        </button>
      </div>

      {/* Content */}
      <div className="flex-1 overflow-y-auto p-2">
        {isLoading && files.length === 0 ? (
          <div className="flex items-center justify-center h-20 text-dark-400 text-sm">
            <RefreshCw size={16} className="animate-spin mr-2" />
            Loading...
          </div>
        ) : error ? (
          <div className="flex items-center justify-center h-20 text-red-400 text-sm gap-2">
            <AlertCircle size={16} />
            {error}
          </div>
        ) : files.length === 0 ? (
          <div className="text-center text-dark-400 text-sm py-4">
            <p>No files found</p>
            <p className="text-xs text-dark-500 mt-1">
              Add model files to 1_setup/
            </p>
          </div>
        ) : (
          <div className="space-y-0.5">
            {files.map((node) => renderNode(node))}
          </div>
        )}
      </div>

      {/* Footer hint */}
      <div className="px-3 py-2 border-t border-dark-700 text-xs text-dark-500">
        Click a model file to select it
      </div>
    </div>
  );
}

export default FileStructurePanel;
