import React, { useState, useCallback, useEffect, useRef, useMemo } from 'react';
import { useEditorStore } from '../../store/editorStore';
import { useCollaborationStore } from '../../store/collaborationStore';
import { ProjectFile } from '../../types/blocks';
import { FrameworkType } from '../../types';
import {
  File, Folder, FolderOpen, FileCode, FileJson, FileType,
  Trash2, Edit3, ChevronRight, ChevronDown, FilePlus, FolderPlus,
  Link, Unlink, Link2, Globe, X, Copy, PanelRight, Play
} from 'lucide-react';
import { v4 as uuidv4 } from 'uuid';
import { getColor } from '../Collaboration/CollaboratorAvatars';
import { getSocket } from '../../hooks/useWebSocket';

interface FileTreeProps {
  files: ProjectFile[];
  activeFileId: string | null;
  onFileSelect: (id: string) => void;
  framework: FrameworkType;
  expanded?: boolean;
}

const FILE_ICONS: Record<string, any> = {
  html: Globe, css: FileType, js: FileCode, ts: FileCode,
  typescript: FileCode, json: File, xaml: FileType,
  csharp: FileCode, env: FileType, jsx: FileCode, tsx: FileCode,
};

function getFileIcon(type: string) { return FILE_ICONS[type] || File; }

function flattenFiles(files: ProjectFile[]): ProjectFile[] {
  const result: ProjectFile[] = [];
  for (const f of files) { result.push(f); if (f.children) result.push(...flattenFiles(f.children)); }
  return result;
}

function findFile(files: ProjectFile[], id: string): ProjectFile | null {
  for (const f of files) {
    if (f.id === id) return f;
    if (f.children) { const found = findFile(f.children, id); if (found) return found; }
  }
  return null;
}

// ===== LINKED FILES MODAL =====
function ManageLinksModal({ file, allFiles, onClose, onToggleLink }: {
  file: ProjectFile; allFiles: ProjectFile[];
  onClose: () => void; onToggleLink: (fileId: string, linkedId: string) => void;
}) {
  const flat = flattenFiles(allFiles).filter(f => f.type !== 'folder' && f.id !== file.id);
  const linkedSet = new Set(file.linkedFiles || []);
  const linked = flat.filter(f => linkedSet.has(f.id));
  const unlinked = flat.filter(f => !linkedSet.has(f.id) && (f.type === 'css' || f.type === 'js'));
  const [tab, setTab] = useState<'linked' | 'add'>('linked');

  return (
    <div className="fixed inset-0 z-50 flex items-center justify-center bg-black/60" onClick={onClose}>
      <div className="bg-surface-900 border border-surface-700 rounded-xl shadow-2xl p-5 w-full max-w-lg max-h-[80vh] flex flex-col" onClick={e => e.stopPropagation()}>
        <div className="flex items-center justify-between mb-4">
          <div>
            <h3 className="text-sm font-semibold text-surface-200">Linked Scripts &amp; Styles</h3>
            <p className="text-[11px] text-surface-400 mt-0.5">
              Manage files linked to <span className="text-primary-400">{file.name}</span>
            </p>
          </div>
          <button onClick={onClose} className="p-1 text-surface-400 hover:text-white"><X className="w-4 h-4" /></button>
        </div>

        <div className="flex gap-1 bg-surface-800 rounded-lg p-0.5 mb-3">
          <button onClick={() => setTab('linked')}
            className={`flex-1 px-3 py-1.5 rounded-md text-xs font-medium transition-all ${tab === 'linked' ? 'bg-primary-600 text-white' : 'text-surface-400'}`}>
            Linked ({linked.length})
          </button>
          <button onClick={() => setTab('add')}
            className={`flex-1 px-3 py-1.5 rounded-md text-xs font-medium transition-all ${tab === 'add' ? 'bg-primary-600 text-white' : 'text-surface-400'}`}>
            Add Files ({unlinked.length})
          </button>
        </div>

        <div className="flex-1 overflow-y-auto min-h-[200px]">
          {tab === 'linked' ? (
            linked.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-12 text-surface-500">
                <Link2 className="w-8 h-8 mb-2 opacity-30" />
                <p className="text-xs">No linked files</p>
                <p className="text-[10px] mt-1">Switch to "Add Files" to link CSS/JS</p>
              </div>
            ) : (
              <div className="space-y-1">
                {linked.map(lf => (
                  <div key={lf.id} className="flex items-center gap-2 px-3 py-2 bg-surface-800/50 rounded-lg border border-surface-700/50">
                    {lf.type === 'css'
                      ? <FileType className="w-4 h-4 text-amber-400" />
                      : <FileCode className="w-4 h-4 text-emerald-400" />}
                    <span className="flex-1 text-xs text-surface-300">{lf.name}</span>
                    <span className="text-[10px] text-surface-500 px-1.5 py-0.5 bg-surface-700 rounded">{lf.type.toUpperCase()}</span>
                    <button onClick={() => onToggleLink(file.id, lf.id)}
                      className="p-1 text-red-400 hover:text-red-300 hover:bg-surface-700 rounded" title="Unlink">
                      <Unlink className="w-3.5 h-3.5" />
                    </button>
                  </div>
                ))}
              </div>
            )
          ) : (
            unlinked.length === 0 ? (
              <div className="flex flex-col items-center justify-center py-12 text-surface-500">
                <Link2 className="w-8 h-8 mb-2 opacity-30" />
                <p className="text-xs">No files available to link</p>
                <p className="text-[10px] mt-1">Create CSS or JS files first</p>
              </div>
            ) : (
              <div className="space-y-1">
                {unlinked.map(uf => (
                  <div key={uf.id}
                    className="flex items-center gap-2 px-3 py-2 bg-surface-800/50 rounded-lg border border-surface-700/50 hover:bg-surface-800 transition-colors cursor-pointer"
                    onClick={() => onToggleLink(file.id, uf.id)}>
                    {uf.type === 'css'
                      ? <FileType className="w-4 h-4 text-amber-400" />
                      : <FileCode className="w-4 h-4 text-emerald-400" />}
                    <span className="flex-1 text-xs text-surface-300">{uf.name}</span>
                    <span className="text-[10px] text-surface-500 px-1.5 py-0.5 bg-surface-700 rounded">{uf.type.toUpperCase()}</span>
                    <Link className="w-3.5 h-3.5 text-primary-400" />
                  </div>
                ))}
              </div>
            )
          )}
        </div>
      </div>
    </div>
  );
}

// ===== LINKED FILE ROW =====
function LinkedFileRow({ file, activeFileId, onSelect, type }: { file: ProjectFile; activeFileId: string | null; onSelect: (id: string) => void; type: string }) {
  return (
    <div
      className={`flex items-center gap-1.5 py-0.5 px-2 rounded-md cursor-pointer group text-xs transition-colors ${
        activeFileId === file.id ? 'bg-primary-500/20 text-primary-300' : 'text-surface-400 hover:text-surface-200 hover:bg-surface-800/50'
      }`}
      style={{ paddingLeft: '20px' }}
      onClick={() => onSelect(file.id)}
    >
      {type === 'css'
        ? <FileType className="w-3 h-3 text-amber-400" />
        : <FileCode className="w-3 h-3 text-emerald-400" />}
      <span className="truncate text-[11px]">{file.name}</span>
      <span className="ml-auto text-[9px] px-1 py-0.5 rounded bg-surface-700/50 text-surface-500">{type === 'css' ? 'CSS' : 'JS'}</span>
    </div>
  );
}

// ===== FILE ITEM =====
interface FileItemProps {
  file: ProjectFile;
  depth: number;
  activeFileId: string | null;
  onSelect: (id: string) => void;
  onRename: (id: string, name: string) => void;
  onDelete: (id: string) => void;
  onAddChild: (parentId: string, isFolder: boolean) => void;
  allFiles: ProjectFile[];
  onOpenLinksModal: (file: ProjectFile) => void;
}

function FileItem({ file, depth, activeFileId, onSelect, onRename, onDelete, onAddChild, allFiles, onOpenLinksModal }: FileItemProps) {
  const [expanded, setExpanded] = useState(true);
  const [editing, setEditing] = useState(false);
  const [editName, setEditName] = useState(file.name);
  const [contextMenu, setContextMenu] = useState<{ x: number; y: number } | null>(null);
  const cmRef = useRef<HTMLDivElement>(null);
  const Icon = file.type === 'folder' ? (expanded ? FolderOpen : Folder) : getFileIcon(file.type);
  const isActive = activeFileId === file.id;
  const isFile = file.type !== 'folder';
  const linkedIds = file.linkedFiles || [];
  const collaborators = useCollaborationStore((s) => s.collaborators);
  const connected = useCollaborationStore((s) => s.connected);
  const collabOnFile = useMemo(() => collaborators.filter((c) => c.activeFileId === file.id), [collaborators, file.id]);

  // Get linked files
  const linked = linkedIds.map(id => findFile(allFiles, id)).filter(Boolean) as ProjectFile[];
  const css = linked.filter(f => f.type === 'css');
  const js = linked.filter(f => f.type === 'js');
  const hasLinks = css.length + js.length > 0;

  useEffect(() => {
    const handler = (e: MouseEvent) => {
      if (cmRef.current && !cmRef.current.contains(e.target as Node)) setContextMenu(null);
    };
    if (contextMenu) document.addEventListener('mousedown', handler);
    return () => document.removeEventListener('mousedown', handler);
  }, [contextMenu]);

  const handleRename = () => {
    if (editName.trim() && editName !== file.name) onRename(file.id, editName.trim());
    setEditing(false);
  };

  const handleContextMenu = (e: React.MouseEvent) => {
    e.preventDefault();
    e.stopPropagation();
    setContextMenu({ x: e.clientX, y: e.clientY });
  };

  const isHtmlFile = file.type === 'html';
  const isJsOrCss = file.type === 'js' || file.type === 'css';

  return (
    <div>
      <div
        className={`flex items-center gap-1 py-1 px-2 rounded-md cursor-pointer group text-sm transition-colors ${
          isActive ? 'bg-primary-500/20 text-primary-300' : 'text-surface-300 hover:bg-surface-800 hover:text-white'
        }`}
        style={{ paddingLeft: `${8 + depth * 16}px` }}
        onClick={() => { if (file.type === 'folder') setExpanded(!expanded); else onSelect(file.id); }}
        onContextMenu={handleContextMenu}
      >
        {file.type === 'folder' && (
          <span className="text-surface-400">
            {expanded ? <ChevronDown className="w-3.5 h-3.5" /> : <ChevronRight className="w-3.5 h-3.5" />}
          </span>
        )}
        <Icon className={`w-4 h-4 flex-shrink-0 ${file.type === 'folder' ? 'text-amber-400' : hasLinks ? 'text-primary-400' : 'text-surface-400'}`} />
        {editing ? (
          <input className="flex-1 bg-surface-700 text-white px-1 py-0.5 rounded text-xs outline-none"
            value={editName} onChange={(e) => setEditName(e.target.value)}
            onBlur={handleRename}
            onKeyDown={(e) => { if (e.key === 'Enter') handleRename(); if (e.key === 'Escape') setEditing(false); }}
            onClick={(e) => e.stopPropagation()} autoFocus />
        ) : (
          <span className="truncate text-xs">{file.name}</span>
        )}
        {hasLinks && isFile && (
          <span className="text-[9px] text-primary-400/60 bg-primary-500/10 px-1 rounded-full flex-shrink-0">{linkedIds.length}</span>
        )}
        {connected && collabOnFile.length > 0 && (
          <div className="flex items-center -space-x-1 ml-auto">
            {collabOnFile.slice(0, 3).map((c) => (
              <div
                key={c.userId}
                className="w-4 h-4 rounded-full flex items-center justify-center text-[7px] font-bold text-white ring-1 ring-surface-900"
                style={{ backgroundColor: getColor(c.userId) }}
                title={`${c.username} (${c.permission})`}
              >
                {c.username.charAt(0).toUpperCase()}
              </div>
            ))}
          </div>
        )}
        <div className="ml-auto flex items-center gap-0.5 opacity-0 group-hover:opacity-100">
          {file.type === 'folder' && (
            <>
              <button onClick={(e) => { e.stopPropagation(); onAddChild(file.id, false); }} className="p-0.5 hover:text-white" title="Add file"><FilePlus className="w-3 h-3" /></button>
              <button onClick={(e) => { e.stopPropagation(); onAddChild(file.id, true); }} className="p-0.5 hover:text-white" title="Add folder"><FolderPlus className="w-3 h-3" /></button>
            </>
          )}
          {isFile && (
            <button onClick={(e) => { e.stopPropagation(); onOpenLinksModal(file); }} className="p-0.5 hover:text-white" title="Manage linked files">
              <Link2 className="w-3 h-3" />
            </button>
          )}
          <button onClick={(e) => { e.stopPropagation(); setEditing(true); setEditName(file.name); }} className="p-0.5 hover:text-white"><Edit3 className="w-3 h-3" /></button>
          <button onClick={(e) => { e.stopPropagation(); onDelete(file.id); }} className="p-0.5 hover:text-red-400"><Trash2 className="w-3 h-3" /></button>
        </div>
      </div>

      {/* Linked files shown as nested indented children */}
      {hasLinks && isFile && (
        <div className="border-l border-primary-500/20 ml-4 mt-0.5 mb-0.5">
          {css.map(lf => (
            <LinkedFileRow key={lf.id} file={lf} activeFileId={activeFileId} onSelect={onSelect} type="css" />
          ))}
          {js.map(lf => (
            <LinkedFileRow key={lf.id} file={lf} activeFileId={activeFileId} onSelect={onSelect} type="js" />
          ))}
        </div>
      )}

      {/* Folder children */}
      {file.type === 'folder' && expanded && file.children && (
        <div>
          {file.children.map((child: ProjectFile) => (
            <FileItem key={child.id} file={child} depth={depth + 1} activeFileId={activeFileId}
              onSelect={onSelect} onRename={onRename} onDelete={onDelete}
              onAddChild={onAddChild} allFiles={allFiles} onOpenLinksModal={onOpenLinksModal} />
          ))}
        </div>
      )}

      {/* Context Menu */}
      {contextMenu && (
        <div ref={cmRef}
          className="fixed z-50 bg-surface-900 border border-surface-700 rounded-lg shadow-xl py-1 min-w-[200px]"
          style={{ left: contextMenu.x, top: contextMenu.y }}>
          <button onClick={() => { onSelect(file.id); setContextMenu(null); }} className="w-full flex items-center gap-2 px-3 py-1.5 text-xs text-surface-300 hover:bg-surface-700">
            <PanelRight className="w-3.5 h-3.5" /> Open
          </button>
          {isHtmlFile && (
            <>
              <div className="h-px bg-surface-700 my-1" />
              <button onClick={() => { onOpenLinksModal(file); setContextMenu(null); }} className="w-full flex items-center gap-2 px-3 py-1.5 text-xs text-surface-300 hover:bg-surface-700">
                <Link2 className="w-3.5 h-3.5" /> Manage Scripts &amp; Styles
              </button>
            </>
          )}
          {isJsOrCss && (
            <>
              <div className="h-px bg-surface-700 my-1" />
              <button onClick={() => { onOpenLinksModal(file); setContextMenu(null); }} className="w-full flex items-center gap-2 px-3 py-1.5 text-xs text-surface-300 hover:bg-surface-700">
                <Link2 className="w-3.5 h-3.5" /> Manage Linked Files
              </button>
            </>
          )}
          <div className="h-px bg-surface-700 my-1" />
          <button onClick={() => { setEditing(true); setEditName(file.name); setContextMenu(null); }} className="w-full flex items-center gap-2 px-3 py-1.5 text-xs text-surface-300 hover:bg-surface-700">
            <Edit3 className="w-3.5 h-3.5" /> Rename
          </button>
          <button onClick={() => { onDelete(file.id); setContextMenu(null); }} className="w-full flex items-center gap-2 px-3 py-1.5 text-xs text-red-400 hover:bg-surface-700">
            <Trash2 className="w-3.5 h-3.5" /> Delete
          </button>
        </div>
      )}
    </div>
  );
}

// ===== MAIN COMPONENT =====
export default function FileTreePanel({ files, activeFileId, onFileSelect, framework }: FileTreeProps) {
  const { addFile, removeFile, updateFile } = useEditorStore();
  const [linksModalFile, setLinksModalFile] = useState<ProjectFile | null>(null);

  const wsEmit = useCallback((event: string, data: any) => {
    const socket = getSocket();
    if (socket?.connected) {
      socket.emit(event, data);
    }
  }, []);

  const handleAddFile = useCallback((parentId?: string) => {
    const file: ProjectFile = {
      id: uuidv4(),
      name: `new-file.${framework === 'maui' ? 'cs' : 'js'}`,
      type: framework === 'maui' ? 'csharp' : 'js',
      content: '',
    };
    addFile(file, parentId);
    wsEmit('file_added', { file, parentId });
  }, [addFile, framework, wsEmit]);

  const handleAddFolder = useCallback((parentId?: string) => {
    const folder: ProjectFile = { id: uuidv4(), name: 'new-folder', type: 'folder', children: [] };
    addFile(folder, parentId);
    wsEmit('file_added', { file: folder, parentId });
  }, [addFile, wsEmit]);

  const handleRename = useCallback((id: string, name: string) => {
    updateFile(id, { name });
    wsEmit('file_renamed', { fileId: id, name });
  }, [updateFile, wsEmit]);

  const handleDelete = useCallback((id: string) => {
    removeFile(id);
    wsEmit('file_deleted', { fileId: id });
  }, [removeFile, wsEmit]);

  const handleToggleLink = useCallback((fileId: string, linkedId: string) => {
    const file = findFile(files, fileId);
    if (!file) return;
    const currentLinks = file.linkedFiles || [];
    const newLinks = currentLinks.includes(linkedId)
      ? currentLinks.filter(id => id !== linkedId)
      : [...currentLinks, linkedId];
    updateFile(fileId, { linkedFiles: newLinks });
    setLinksModalFile(prev => prev ? { ...prev, linkedFiles: newLinks } : null);
  }, [files, updateFile]);

  return (
    <div className="p-3">
      <div className="flex items-center justify-between mb-3">
        <h3 className="text-xs font-semibold text-surface-400 uppercase tracking-wider">Files</h3>
        <div className="flex items-center gap-1">
          <button onClick={() => handleAddFile()} className="btn-ghost p-1" title="New file"><FilePlus className="w-3.5 h-3.5" /></button>
          <button onClick={() => handleAddFolder()} className="btn-ghost p-1" title="New folder"><FolderPlus className="w-3.5 h-3.5" /></button>
        </div>
      </div>
      <div className="space-y-0.5">
        {files.map((file) => (
          <FileItem key={file.id} file={file} depth={0} activeFileId={activeFileId}
            onSelect={onFileSelect} onRename={handleRename} onDelete={removeFile}
            onAddChild={(parentId, isFolder) => { if (isFolder) handleAddFolder(parentId); else handleAddFile(parentId); }}
            allFiles={files} onOpenLinksModal={setLinksModalFile} />
        ))}
      </div>

      {linksModalFile && (
        <ManageLinksModal file={linksModalFile} allFiles={files}
          onClose={() => setLinksModalFile(null)}
          onToggleLink={handleToggleLink} />
      )}
    </div>
  );
}
