/**
 * @license
 * SPDX-License-Identifier: Apache-2.0
 */

import React, { useState, useEffect, useRef } from 'react';
import { 
  Activity, 
  Check, 
  Download, 
  Layers, 
  ActivitySquare, 
  MonitorPlay, 
  Save, 
  LayoutDashboard, 
  Database, 
  Image as ImageIcon, 
  Users, 
  LogOut, 
  UserPlus, 
  Key,
  ChevronRight,
  ShieldCheck,
  Search,
  Settings,
  Plus,
  Play as PlayIcon,
  RefreshCw,
  Film,
  FolderOpen,
  Server,
  AlertCircle,
  Info,
  X
} from 'lucide-react';

// --- Types ---
type User = {
  id: string;
  username: string;
  password: string;
  role: 'admin' | 'user';
  createdAt: string;
};

type Page = 'overview' | 'library' | 'workspace' | 'users';

type BackendJob = {
  id: string;
  kind: 'deformation' | 'video';
  status: 'running' | 'completed' | 'failed';
  message: string;
  result?: any;
  error?: string;
};

type LibraryItem = {
  id: string;
  patientId: string;
  date: string;
  version: string;
  status: 'processed' | 'pending';
  size: number;
  previewColor: string;
  dicomPath: string;
  fileCount?: number;
  source?: 'seed' | 'upload';
};

type LibraryInfo = {
  id: string;
  patientId: string;
  fileCount: number;
  groups: {
    title: string;
    items: { label: string; value: string }[];
  }[];
};

const API_BASE = typeof window === 'undefined'
  ? 'http://127.0.0.1:8787'
  : `${window.location.protocol}//${window.location.hostname}:8787`;

function LibraryDicomPreview({ item }: { item: LibraryItem }) {
  const [sliceIndex, setSliceIndex] = useState(Math.max(0, Math.floor((item.fileCount || 1) / 2)));
  const [requestedSliceIndex, setRequestedSliceIndex] = useState(sliceIndex);
  const [previewImage, setPreviewImage] = useState('');
  const [isLoading, setIsLoading] = useState(false);
  const [error, setError] = useState('');
  const count = Math.max(1, item.fileCount || 1);

  useEffect(() => {
    const middleIndex = Math.max(0, Math.floor((item.fileCount || 1) / 2));
    setSliceIndex(middleIndex);
    setRequestedSliceIndex(middleIndex);
  }, [item.id, item.fileCount]);

  useEffect(() => {
    const timer = window.setTimeout(() => {
      setRequestedSliceIndex(sliceIndex);
    }, 120);
    return () => window.clearTimeout(timer);
  }, [sliceIndex]);

  useEffect(() => {
    const controller = new AbortController();
    setIsLoading(true);
    setError('');
    fetch(`${API_BASE}/api/library/preview?id=${encodeURIComponent(item.id)}&index=${requestedSliceIndex}`, {
      signal: controller.signal
    })
      .then(async response => {
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || '预览生成失败');
        setPreviewImage(`${API_BASE}${data.imageUrl}`);
        (data.neighbors || []).forEach((url: string) => {
          fetch(`${API_BASE}${url}`, { signal: controller.signal }).catch(() => {});
        });
      })
      .catch(error => {
        if ((error as Error).name !== 'AbortError') setError((error as Error).message);
      })
      .finally(() => {
        if (!controller.signal.aborted) setIsLoading(false);
      });
    return () => controller.abort();
  }, [item.id, requestedSliceIndex]);

  return (
    <div className="h-52 bg-slate-950 relative flex items-center justify-center border-b border-slate-100 shadow-inner overflow-hidden">
      <div className="absolute top-3 left-4 flex gap-1.5 z-10">
        <div className="w-1.5 h-1.5 rounded-full bg-white/25"></div>
        <div className="w-1.5 h-1.5 rounded-full bg-white/25"></div>
      </div>
      <div className="absolute top-3 right-4 z-10">
        <span className={`text-[8px] font-black px-2 py-0.5 rounded border ${item.status === 'processed' ? 'bg-green-500/20 text-green-400 border-green-500/30' : 'bg-amber-500/20 text-amber-400 border-amber-500/30'}`}>
          {item.status.toUpperCase()}
        </span>
      </div>

      {previewImage && !error ? (
        <img src={previewImage} className="w-full h-full object-contain" />
      ) : (
        <div className="text-center text-white/35">
          <ImageIcon size={34} className="mx-auto mb-2" />
          <p className="text-[10px] font-bold">{error || (isLoading ? '正在生成预览...' : '等待预览')}</p>
        </div>
      )}

      <div className="absolute inset-x-0 bottom-0 p-3 bg-gradient-to-t from-black/85 via-black/45 to-transparent">
        <div className="flex items-center justify-between text-[8px] font-mono text-white/65 mb-2 uppercase tracking-[0.18em]">
          <span>Axial DICOM</span>
          <span>{sliceIndex + 1} / {count}</span>
        </div>
        <input
          type="range"
          min="0"
          max={count - 1}
          value={Math.min(sliceIndex, count - 1)}
          onChange={event => setSliceIndex(parseInt(event.target.value, 10))}
          className="w-full h-1 accent-blue-500 cursor-pointer"
        />
      </div>
    </div>
  );
}

export default function App() {
  // --- Authentication State ---
  const [isLoggedIn, setIsLoggedIn] = useState(false);
  const [currentUser, setCurrentUser] = useState<User | null>(null);
  const [loginUsername, setLoginUsername] = useState('admin');
  const [loginPassword, setLoginPassword] = useState('123456');
  const [loginError, setLoginError] = useState('');

  // --- App Flow State ---
  const [currentPage, setCurrentPage] = useState<Page>('workspace');
  const [isSidebarCollapsed, setIsSidebarCollapsed] = useState(false);

  useEffect(() => {
    // Automatically collapse sidebar when on workspace page to give more space
    if (currentPage === 'workspace') {
      setIsSidebarCollapsed(true);
    } else {
      setIsSidebarCollapsed(false);
    }
  }, [currentPage]);

  const [users, setUsers] = useState<User[]>([
    { id: '1', username: 'admin', password: '123456', role: 'admin', createdAt: '2024-01-01' },
    { id: '2', username: 'doctor1', password: 'password123', role: 'user', createdAt: '2024-05-01' }
  ]);

  const [libraryData, setLibraryData] = useState<LibraryItem[]>([]);
  const [selectedLibraryId, setSelectedLibraryId] = useState('');
  const [isUploadingDicom, setIsUploadingDicom] = useState(false);
  const [libraryInfo, setLibraryInfo] = useState<LibraryInfo | null>(null);
  const [isLibraryInfoLoading, setIsLibraryInfoLoading] = useState(false);
  const folderUploadInputRef = useRef<HTMLInputElement | null>(null);
  const zipUploadInputRef = useRef<HTMLInputElement | null>(null);
  
  // --- Simulation State (Workspace) ---
  const [cervicalRotation, setCervicalRotation] = useState(14.5);
  const [transitionWidth, setTransitionWidth] = useState(90);
  const [isSimulating, setIsSimulating] = useState(false);
  const [progress, setProgress] = useState(0);
  const [toastMessage, setToastMessage] = useState("");
  const [backendOnline, setBackendOnline] = useState(false);
  const [backendMessage, setBackendMessage] = useState('正在连接本地 Python 后端...');
  const [previewImage, setPreviewImage] = useState('');
  const [isPreviewLoading, setIsPreviewLoading] = useState(false);
  const [deformationJob, setDeformationJob] = useState<BackendJob | null>(null);
  const [videoJob, setVideoJob] = useState<BackendJob | null>(null);
  const [videoMaxAngle, setVideoMaxAngle] = useState(20);
  const [videoDuration, setVideoDuration] = useState(6);

  // --- User Management Shared State ---
  const [newUsername, setNewUsername] = useState('');
  const [newPassword, setNewPassword] = useState('');
  const [isChangingOwnPass, setIsChangingOwnPass] = useState(false);
  const [pwChangeInput, setPwChangeInput] = useState('');
  const [showAddUser, setShowAddUser] = useState(false);
  const [activeUserMenu, setActiveUserMenu] = useState<string | null>(null);

  const selectedDataset = libraryData.find(item => item.id === selectedLibraryId) || libraryData[0];
  const selectedInputDir = selectedDataset?.dicomPath || '';

  useEffect(() => {
    if (!activeUserMenu) return;

    const closeUserMenuOnOutsideClick = (event: PointerEvent) => {
      const target = event.target as HTMLElement | null;
      if (!target?.closest('[data-user-menu-root="true"]')) {
        setActiveUserMenu(null);
      }
    };

    document.addEventListener('pointerdown', closeUserMenuOnOutsideClick);
    return () => document.removeEventListener('pointerdown', closeUserMenuOnOutsideClick);
  }, [activeUserMenu]);

  const showToast = (message: string) => {
    setToastMessage(message);
    setTimeout(() => setToastMessage(""), 3000);
  };

  const apiRequest = async (path: string, options?: RequestInit) => {
    const response = await fetch(`${API_BASE}${path}`, {
      ...options,
      headers: {
        'Content-Type': 'application/json',
        ...(options?.headers || {})
      }
    });
    const data = await response.json();
    if (!response.ok) {
      throw new Error(data.error || '本地 Python 后端请求失败');
    }
    return data;
  };

  const fileUrl = (path?: string) => path ? `${API_BASE}/api/file?path=${encodeURIComponent(path)}` : '';

  const loadLibrary = async () => {
    const data = await apiRequest('/api/library');
    const items = data.items || [];
    setLibraryData(items);
    setSelectedLibraryId(current => items.some((item: LibraryItem) => item.id === current) ? current : items[0]?.id || '');
    return items;
  };

  const refreshBackendDefaults = async () => {
    try {
      const data = await apiRequest('/api/defaults');
      await loadLibrary();
      setBackendOnline(true);
      setBackendMessage('本地 Python 后端已连接');
    } catch (error) {
      setBackendOnline(false);
      setBackendMessage('未连接：请先运行 python web_backend.py');
    }
  };

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

  useEffect(() => {
    if (!deformationJob || deformationJob.status !== 'running') return;
    const timer = setInterval(async () => {
      try {
        const job = await apiRequest(`/api/job?id=${deformationJob.id}`) as BackendJob;
        setDeformationJob(job);
        setProgress(value => job.status === 'completed' ? 100 : Math.min(value + 8, 95));
        if (job.status === 'completed') {
          setIsSimulating(false);
          showToast('四状态 DICOM 与过程图已生成');
        }
        if (job.status === 'failed') {
          setIsSimulating(false);
          showToast(job.error || '形变任务失败');
        }
      } catch (error) {
        setIsSimulating(false);
        setDeformationJob(job => job ? { ...job, status: 'failed', error: (error as Error).message } : null);
      }
    }, 1500);
    return () => clearInterval(timer);
  }, [deformationJob?.id, deformationJob?.status]);

  useEffect(() => {
    if (!videoJob || videoJob.status !== 'running') return;
    const timer = setInterval(async () => {
      try {
        const job = await apiRequest(`/api/job?id=${videoJob.id}`) as BackendJob;
        setVideoJob(job);
        if (job.status === 'completed') showToast('仰头变化视频已生成');
        if (job.status === 'failed') showToast(job.error || '视频生成失败');
      } catch (error) {
        setVideoJob(job => job ? { ...job, status: 'failed', error: (error as Error).message } : null);
      }
    }, 1500);
    return () => clearInterval(timer);
  }, [videoJob?.id, videoJob?.status]);

  const handleLogin = (e: React.FormEvent) => {
    e.preventDefault();
    const user = users.find(u => u.username === loginUsername && u.password === loginPassword);
    if (user) {
      setIsLoggedIn(true);
      setCurrentUser(user);
      setLoginError('');
      showToast(`欢迎, ${user.username}`);
    } else {
      setLoginError('用户名或密码错误');
    }
  };

  const handleLogout = () => {
    setIsLoggedIn(false);
    setCurrentUser(null);
    setCurrentPage('workspace');
  };

  const addUser = () => {
    if (!newUsername || !newPassword) return;
    if (users.find(u => u.username === newUsername)) {
      showToast('用户名已存在');
      return;
    }
    const newUser: User = {
      id: Date.now().toString(),
      username: newUsername,
      password: newPassword,
      role: 'user',
      createdAt: new Date().toISOString().split('T')[0]
    };
    setUsers([...users, newUser]);
    setNewUsername('');
    setNewPassword('');
    setShowAddUser(false);
    showToast('用户创建成功');
  };

  const uploadImage = () => {
    folderUploadInputRef.current?.click();
  };

  const uploadZip = () => {
    zipUploadInputRef.current?.click();
  };

  const handleLibraryFilesSelected = async (event: React.ChangeEvent<HTMLInputElement>) => {
    const selectedFiles: File[] = [];
    const fileList = event.currentTarget.files;
    if (fileList) {
      for (let index = 0; index < fileList.length; index += 1) {
        const file = fileList.item(index);
        if (file) selectedFiles.push(file);
      }
    }
    const files = selectedFiles.filter(file => {
      const name = file.name.toLowerCase();
      return name.endsWith('.dcm') || name.endsWith('.zip');
    });
    event.currentTarget.value = '';
    if (!files.length) {
      showToast('请选择 .dcm 文件或 .zip 压缩包');
      return;
    }

    setIsUploadingDicom(true);
    try {
      const formData = new FormData();
      const firstRelativePath = (files[0] as any).webkitRelativePath || files[0].name;
      const patientId = firstRelativePath.includes('/')
        ? firstRelativePath.split('/')[0]
        : files[0].name.replace(/\.(dcm|zip)$/i, '') || `WEB_${new Date().getTime()}`;
      formData.append('patientId', patientId);
      files.forEach(file => {
        formData.append('files', file, (file as any).webkitRelativePath || file.name);
      });

      const response = await fetch(`${API_BASE}/api/library/upload`, {
        method: 'POST',
        body: formData
      });
      const data = await response.json();
      if (!response.ok) throw new Error(data.error || '上传失败');

      const items = await loadLibrary();
      setSelectedLibraryId(data.id || items[0]?.id || '');
      setCurrentPage('workspace');
      setPreviewImage('');
      setDeformationJob(null);
      showToast(`已上传 ${data.fileCount || files.length} 张 DICOM`);
    } catch (error) {
      const message = (error as Error).message === 'Failed to fetch'
        ? `无法连接 Python 后端：${API_BASE}`
        : (error as Error).message;
      showToast(message);
    } finally {
      setIsUploadingDicom(false);
    }
  };

  const deleteImage = async (id: string) => {
    try {
      const response = await fetch(`${API_BASE}/api/library?id=${encodeURIComponent(id)}`, {
        method: 'DELETE'
      });
      const data = await response.json();
      if (!response.ok) throw new Error(data.error || '删除失败');
      setLibraryData(data.items || []);
      if (selectedLibraryId === id) {
        setSelectedLibraryId(data.items?.[0]?.id || '');
        setPreviewImage('');
        setDeformationJob(null);
      }
      showToast('影像已删除');
    } catch (error) {
      showToast((error as Error).message);
    }
  };

  const showLibraryInfo = async (item: LibraryItem) => {
    setIsLibraryInfoLoading(true);
    setLibraryInfo(null);
    try {
      const data = await apiRequest(`/api/library/info?id=${encodeURIComponent(item.id)}`) as LibraryInfo;
      setLibraryInfo(data);
    } catch (error) {
      showToast((error as Error).message);
    } finally {
      setIsLibraryInfoLoading(false);
    }
  };

  const changePassword = (userId: string, newPass: string) => {
    setUsers(users.map(u => u.id === userId ? { ...u, password: newPass } : u));
    setPwChangeInput('');
    setIsChangingOwnPass(false);
    showToast('密码更新成功');
  };

  useEffect(() => {
    if (currentPage !== 'workspace' || !selectedInputDir) return;

    const controller = new AbortController();
    const timer = window.setTimeout(async () => {
      setIsPreviewLoading(true);
      try {
        const response = await fetch(`${API_BASE}/api/preview`, {
          method: 'POST',
          headers: { 'Content-Type': 'application/json' },
          body: JSON.stringify({
            inputDir: selectedInputDir,
            angleDegrees: cervicalRotation
          }),
          signal: controller.signal
        });
        const data = await response.json();
        if (!response.ok) throw new Error(data.error || '预览生成失败');
        setPreviewImage(data.image);
        setBackendOnline(true);
        setBackendMessage('预览已自动更新');
      } catch (error) {
        if ((error as Error).name !== 'AbortError') {
          setBackendOnline(false);
          setBackendMessage((error as Error).message);
        }
      } finally {
        if (!controller.signal.aborted) setIsPreviewLoading(false);
      }
    }, 300);

    return () => {
      controller.abort();
      window.clearTimeout(timer);
    };
  }, [currentPage, selectedInputDir, cervicalRotation]);

  const handleRunSimulation = async () => {
    if (isSimulating) return;
    setIsSimulating(true);
    setProgress(0);
    try {
      const job = await apiRequest('/api/deformation', {
        method: 'POST',
        body: JSON.stringify({
          inputDir: selectedInputDir,
          angleDegrees: cervicalRotation,
          transitionWidth
        })
      }) as BackendJob;
      setDeformationJob(job);
      setBackendOnline(true);
      setBackendMessage('run_deformation 任务已提交');
      showToast('形变任务已提交');
    } catch (error) {
      setIsSimulating(false);
      setBackendOnline(false);
      showToast((error as Error).message);
    }
  };

  const handleGenerateVideo = async () => {
    if (videoJob?.status === 'running') return;
    try {
      const job = await apiRequest('/api/video', {
        method: 'POST',
        body: JSON.stringify({
          inputDir: selectedInputDir,
          maxAngle: videoMaxAngle,
          durationSeconds: videoDuration
        })
      }) as BackendJob;
      setVideoJob(job);
      setBackendOnline(true);
      setBackendMessage('generate_head_extension_video.py 任务已提交');
      showToast('视频任务已提交');
    } catch (error) {
      setBackendOnline(false);
      showToast((error as Error).message);
    }
  };

  // --- Login Screen ---
  if (!isLoggedIn) {
    return (
      <div className="w-screen h-screen bg-[#f1f5f9] flex items-center justify-center">
        <div className="w-[450px] bg-white p-10 rounded-2xl shadow-xl border border-slate-200">
          <div className="flex flex-col items-center mb-8">
            <div className="w-16 h-16 bg-blue-600 rounded-xl flex items-center justify-center mb-4">
              <ActivitySquare className="text-white w-9 h-9" />
            </div>
            <h1 className="text-xl font-bold text-slate-800 text-center">颅颈特定体位CT影像智慧变形平台</h1>
            <p className="text-slate-400 text-sm mt-2">头部CT变形平台</p>
          </div>
          <form onSubmit={handleLogin} className="space-y-4">
            <div className="space-y-1">
              <label className="text-[10px] font-bold text-slate-400 uppercase ml-1">用户名</label>
              <input 
                type="text" placeholder="admin" value={loginUsername}
                onChange={e => setLoginUsername(e.target.value)}
                className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none transition-all"
              />
            </div>
            <div className="space-y-1">
              <label className="text-[10px] font-bold text-slate-400 uppercase ml-1">密码</label>
              <input 
                type="password" placeholder="123456" value={loginPassword}
                  onChange={e => setLoginPassword(e.target.value)}
                className="w-full px-4 py-3 bg-slate-50 border border-slate-200 rounded-lg focus:ring-2 focus:ring-blue-500 outline-none transition-all"
              />
            </div>
            {loginError && <p className="text-red-500 text-xs text-center font-medium">{loginError}</p>}
            <button type="submit" className="w-full py-3.5 bg-blue-600 text-white rounded-lg font-bold hover:bg-blue-700 transition-all shadow-lg shadow-blue-500/20 active:scale-95">登 录</button>
          </form>
        </div>
      </div>
    );
  }

  // --- Sidebar Component ---
  const NavItem = ({ icon: Icon, label, page }: { icon: any, label: string, page: Page }) => (
    <button 
      onClick={() => setCurrentPage(page)}
      title={isSidebarCollapsed ? label : ""}
      className={`w-full flex items-center gap-3 px-4 py-3 rounded-xl transition-all relative group ${
        currentPage === page ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-600 hover:bg-slate-100'
      } ${isSidebarCollapsed ? 'justify-center px-0' : ''}`}
    >
      <Icon size={20} className={isSidebarCollapsed ? 'shrink-0' : ''} />
      {!isSidebarCollapsed && <span className="flex-1 text-left text-sm font-medium">{label}</span>}
      {isSidebarCollapsed && (
        <div className="absolute left-16 bg-slate-800 text-white text-[10px] px-2 py-1 rounded opacity-0 group-hover:opacity-100 pointer-events-none transition-opacity whitespace-nowrap z-50">
          {label}
        </div>
      )}
    </button>
  );

  return (
    <div className="w-screen h-screen bg-[#f8fafc] text-[#1e293b] flex overflow-hidden">
      
      {/* Sidebar */}
      <aside className={`${isSidebarCollapsed ? 'w-20' : 'w-72'} bg-white border-r p-6 flex flex-col shrink-0 transition-all duration-300 ease-in-out`}>
        <div className={`flex items-center ${isSidebarCollapsed ? 'justify-center' : 'gap-3'} mb-10 transition-all`}>
          <ActivitySquare className="text-blue-600 shrink-0" size={28} />
          {!isSidebarCollapsed && <h2 className="text-base font-bold tracking-tight whitespace-nowrap overflow-hidden">头颈CT变形平台</h2>}
        </div>
        
        <nav className="flex-1 space-y-2">
          <NavItem icon={LayoutDashboard} label="总体概况" page="overview" />
          <NavItem icon={Database} label="数据影像库" page="library" />
          <NavItem icon={ImageIcon} label="影像变换工作站" page="workspace" />
          <NavItem icon={Users} label="用户管理工作区" page="users" />
        </nav>

        <div className="mt-auto pt-6 border-t font-medium">
          <div className={`flex items-center ${isSidebarCollapsed ? 'justify-center flex-col gap-2' : 'gap-3 p-3 bg-slate-50 rounded-xl mb-3'} transition-all`}>
             <div className="w-8 h-8 rounded-full bg-blue-600 border-2 border-white shadow-md flex items-center justify-center text-white text-xs shrink-0">{currentUser?.username[0].toUpperCase()}</div>
             {!isSidebarCollapsed && (
               <div className="flex-1 truncate">
                 <p className="text-xs font-bold leading-none text-slate-800">{currentUser?.username}</p>
                 <p className="text-[9px] text-slate-400 mt-1 uppercase tracking-widest">{currentUser?.role}</p>
               </div>
             )}
          </div>
          <button onClick={handleLogout} className={`w-full flex items-center gap-3 px-4 py-3 text-slate-400 hover:text-red-500 text-sm transition-all ${isSidebarCollapsed ? 'justify-center px-0' : ''}`}>
            <LogOut size={18} /> 
            {!isSidebarCollapsed && <span>退出登录</span>}
          </button>
        </div>
      </aside>

      {/* Main Content */}
      <main className="flex-1 flex flex-col overflow-hidden bg-slate-50">
        <header className="h-16 bg-white border-b px-8 flex items-center justify-between shadow-sm z-10 shrink-0">
           <div className="flex items-center gap-4">
             {isSidebarCollapsed && (
               <button 
                 onClick={() => setIsSidebarCollapsed(false)}
                 className="p-1.5 hover:bg-slate-100 rounded-lg text-slate-400 transition-colors"
               >
                 <ChevronRight size={18} />
               </button>
             )}
             <h3 className="font-bold text-slate-800">
               {currentPage === 'overview' && '控制台总览'}
               {currentPage === 'library' && '临床数据存档'}
               {currentPage === 'workspace' && '影像变换工作站'}
               {currentPage === 'users' && '系统访问权限管理'}
             </h3>
           </div>
           <div className="flex items-center gap-6">
              <div className="flex items-center gap-2 text-[10px] font-extrabold text-slate-400 uppercase tracking-tighter">
                <div className="w-2 h-2 rounded-full bg-green-500 animate-pulse"></div>
                算网协同系统 :: 稳定
              </div>
           </div>
        </header>

        <div className="flex-1 p-8 overflow-y-auto">
          
          {/* --- WORKSPACE VIEW --- */}
          {currentPage === 'workspace' && (
            <div className="min-h-full flex gap-6 animate-in fade-in zoom-in-95 duration-300">
              <div className="w-[380px] space-y-4 shrink-0">
                <div className={`flex items-center gap-3 text-xs font-bold px-4 py-3 rounded-2xl border ${backendOnline ? 'bg-green-50 text-green-700 border-green-100' : 'bg-amber-50 text-amber-700 border-amber-100'}`}>
                  {backendOnline ? <Server size={16} /> : <AlertCircle size={16} />}
                  <span>{backendMessage}</span>
                </div>

                <div className="bg-white p-5 rounded-2xl border shadow-sm space-y-4">
                  <div className="space-y-3">
                    <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest block">影像库数据源</label>
                    <div className="space-y-2">
                      <div className="flex items-center justify-between text-[10px] font-bold text-slate-500">
                        <span className="flex items-center gap-2"><Database size={12} /> 当前 DICOM 数据集</span>
                        <button onClick={() => setCurrentPage('library')} className="text-blue-600 hover:text-blue-800">切换</button>
                      </div>
                      <select
                        value={selectedDataset?.id || ''}
                        onChange={event => {
                          setSelectedLibraryId(event.target.value);
                          setPreviewImage('');
                          setDeformationJob(null);
                        }}
                        className="w-full px-3 py-2.5 bg-slate-50 border border-slate-200 rounded-xl outline-none focus:ring-2 focus:ring-blue-500 text-xs font-bold text-slate-700"
                      >
                        {libraryData.map(item => (
                          <option key={item.id} value={item.id}>{item.patientId} · {item.fileCount || 0} DICOM</option>
                        ))}
                      </select>
                    </div>
                  </div>
                </div>

                <div className="bg-white p-5 rounded-2xl border shadow-sm space-y-5">
                  <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest block">仰头数据处理及结果输出</label>

                  <div className="space-y-4 pt-2">
                    <div>
                      <div className="flex justify-between text-xs font-bold mb-2 text-slate-600"><span>仰头角度</span><span className="text-blue-600 font-mono">{cervicalRotation.toFixed(1)}°</span></div>
                      <input type="range" min="0" max="20" step="0.5" value={cervicalRotation} onChange={e => setCervicalRotation(parseFloat(e.target.value))} className="w-full h-1.5 bg-slate-100 rounded-lg appearance-none cursor-pointer accent-blue-600 opacity-80 hover:opacity-100 transition-opacity" />
                    </div>
                    <div>
                      <div className="flex justify-between text-xs font-bold mb-2 text-slate-600"><span>过渡平滑宽度</span><span className="text-blue-600 font-mono">{transitionWidth}</span></div>
                      <input type="range" min="50" max="160" step="10" value={transitionWidth} onChange={e => setTransitionWidth(parseInt(e.target.value, 10))} className="w-full h-1.5 bg-slate-100 rounded-lg appearance-none cursor-pointer accent-blue-600 opacity-80 hover:opacity-100 transition-opacity" />
                    </div>
                  </div>

                  <div>
                    <button onClick={handleRunSimulation} disabled={isSimulating || !selectedInputDir} className="w-full py-3 bg-blue-600 text-white rounded-xl text-xs font-bold hover:bg-blue-700 transition-all flex items-center justify-center gap-2 active:scale-95 disabled:opacity-50">
                      <PlayIcon className="fill-white" size={14} /> {isSimulating ? '生成中' : '四状态输出'}
                    </button>
                  </div>

                  <div className="pt-3 border-t">
                    <div className="flex justify-between text-[10px] text-slate-400 font-bold uppercase mb-2">
                      <span>{deformationJob?.message || 'head_extension_app.py / run_deformation'}</span>
                      <span>{deformationJob?.status === 'completed' ? '100%' : `${progress}%`}</span>
                    </div>
                    <div className="h-1.5 bg-slate-100 rounded-full overflow-hidden">
                      <div className={`h-full ${deformationJob?.status === 'failed' ? 'bg-red-500' : 'bg-blue-600'} transition-all`} style={{ width: `${deformationJob?.status === 'completed' ? 100 : progress}%` }} />
                    </div>
                    {deformationJob?.error && <p className="text-[10px] text-red-500 font-bold mt-2 break-all">{deformationJob.error}</p>}
                    {deformationJob?.status === 'completed' && deformationJob.result?.zip?.path && (
                      <a
                        href={fileUrl(deformationJob.result.zip.path)}
                        download={deformationJob.result.zip.name}
                        className="mt-3 w-full py-3 bg-green-600 text-white rounded-xl text-xs font-bold hover:bg-green-700 transition-all flex items-center justify-center gap-2"
                      >
                        <Download size={14} /> 下载四状态 ZIP
                      </a>
                    )}
                  </div>
                </div>

                <div className="bg-white p-5 rounded-2xl border shadow-sm space-y-4">
                  <div className="flex items-center justify-between">
                    <label className="text-[10px] font-bold text-slate-400 uppercase tracking-widest">视频生成</label>
                    <Film size={16} className="text-blue-600" />
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    <div>
                      <div className="flex justify-between text-[10px] font-bold mb-2 text-slate-500"><span>最大角度</span><span>{videoMaxAngle}°</span></div>
                      <input type="range" min="5" max="30" step="1" value={videoMaxAngle} onChange={e => setVideoMaxAngle(parseInt(e.target.value, 10))} className="w-full accent-blue-600" />
                    </div>
                    <div>
                      <div className="flex justify-between text-[10px] font-bold mb-2 text-slate-500"><span>时长</span><span>{videoDuration}s</span></div>
                      <input type="range" min="3" max="12" step="1" value={videoDuration} onChange={e => setVideoDuration(parseInt(e.target.value, 10))} className="w-full accent-blue-600" />
                    </div>
                  </div>
                  <button onClick={handleGenerateVideo} disabled={videoJob?.status === 'running' || !selectedInputDir} className="w-full py-3 bg-slate-100 text-slate-700 rounded-xl text-xs font-bold hover:bg-blue-600 hover:text-white transition-all flex items-center justify-center gap-2 disabled:opacity-50">
                    <RefreshCw size={14} className={videoJob?.status === 'running' ? 'animate-spin' : ''} /> {videoJob?.status === 'running' ? '正在生成视频' : '生成角度变化视频'}
                  </button>
                  {videoJob?.status === 'completed' && videoJob.result?.video?.path ? (
                    <div className="space-y-3">
                      <div className="bg-slate-950 rounded-xl overflow-hidden border border-slate-800">
                        <video
                          src={fileUrl(videoJob.result.video.path)}
                          controls
                          preload="metadata"
                          className="w-full aspect-video bg-black"
                        />
                      </div>
                      <a
                        href={fileUrl(videoJob.result.video.path)}
                        download={videoJob.result.video.name}
                        className="w-full py-3 bg-green-600 text-white rounded-xl text-xs font-bold hover:bg-green-700 transition-all flex items-center justify-center gap-2"
                      >
                        <Download size={14} /> 下载视频 MP4
                      </a>
                    </div>
                  ) : (
                    <p className="text-[10px] text-slate-400 font-medium break-all">{videoJob?.message || 'generate_head_extension_video.py / generate_video'}</p>
                  )}
                  {videoJob?.error && <p className="text-[10px] text-red-500 font-bold break-all">{videoJob.error}</p>}
                </div>
              </div>

              <div className="flex-1 space-y-6 pb-8">
                <div className="bg-white rounded-2xl border shadow-sm overflow-hidden">
                  <div className="px-5 py-4 border-b flex items-center justify-between">
                    <div>
                      <h4 className="font-black text-slate-800">快速 2D 预览</h4>
                      <p className="text-[10px] text-slate-400 font-bold mt-1">对应 head_extension_app.py 的 preview_deform_2d</p>
                    </div>
                    <div className="text-right">
                      <span className="text-[10px] font-mono text-slate-400">{cervicalRotation.toFixed(1)} DEG</span>
                      {isPreviewLoading && <p className="text-[9px] font-bold text-blue-500 mt-1">自动更新中...</p>}
                    </div>
                  </div>
                  <div className="h-[360px] bg-slate-950 flex items-center justify-center">
                    {previewImage ? (
                      <img src={previewImage} className="max-w-full max-h-full object-contain" />
                    ) : (
                      <div className="text-center text-slate-500">
                        <ImageIcon size={42} className="mx-auto mb-3 opacity-40" />
                        <p className="text-xs font-bold">{isPreviewLoading ? '正在自动生成预览...' : '选择影像库数据后自动生成预览'}</p>
                      </div>
                    )}
                  </div>
                </div>

                <div className="grid grid-cols-2 gap-5">
                  {[
                    { key: 'original', label: '原始序列', sub: 'ct_original' },
                    { key: 'hard_boundary', label: '硬边界', sub: 'ct_hard_boundary' },
                    { key: 'gaussian_smooth', label: '高斯平滑', sub: 'ct_gaussian_smooth' },
                    { key: 'soft_transition', label: '软过渡重建', sub: 'ct_soft_transition' }
                  ].map(t => {
                    const screenshotDir = deformationJob?.result?.previews?.screenshots;
                    const imagePath = screenshotDir ? `${screenshotDir}/${t.key}.png` : '';
                    const stateZip = deformationJob?.result?.stateZips?.[t.key];
                    return (
                      <div key={t.key} className="bg-white p-4 rounded-2xl border flex flex-col hover:border-blue-200 transition-colors shadow-sm group min-h-[285px]">
                        <div className="flex justify-between items-center mb-3">
                          <span className={`text-[10px] font-bold px-2 py-0.5 rounded transition-colors ${t.key === 'soft_transition' ? 'bg-blue-600 text-white' : 'bg-slate-100 text-slate-500 group-hover:bg-slate-200'}`}>{t.label}</span>
                          <span className="text-[8px] font-mono text-slate-300">{t.sub}</span>
                        </div>
                        <div className="flex-1 bg-slate-900 rounded-xl relative flex justify-center items-center overflow-hidden border border-slate-800">
                          {imagePath ? (
                            <img src={fileUrl(imagePath)} className="w-full h-full object-contain" />
                          ) : (
                            <div className="text-center text-white/25">
                              <Layers size={34} className="mx-auto mb-3" />
                              <p className="text-[10px] font-mono uppercase">等待 Python 输出</p>
                            </div>
                          )}
                        </div>
                        {stateZip?.path && (
                          <a
                            href={fileUrl(stateZip.path)}
                            download={stateZip.name}
                            className="mt-3 py-2.5 bg-slate-100 text-slate-600 rounded-xl text-[11px] font-black hover:bg-green-600 hover:text-white transition-all flex items-center justify-center gap-2"
                          >
                            <Download size={13} /> 下载本状态 DICOM ZIP
                          </a>
                        )}
                      </div>
                    );
                  })}
                </div>

                {deformationJob?.result?.previews?.comparison && (
                  <div className="bg-white p-4 rounded-2xl border shadow-sm">
                    <div className="flex justify-between items-center mb-3">
                      <h4 className="font-black text-sm text-slate-700">四状态过程对比图</h4>
                      <span className="text-[9px] font-mono text-slate-400 break-all">{deformationJob.result.previews.comparison}</span>
                    </div>
                    <img src={fileUrl(deformationJob.result.previews.comparison)} className="w-full rounded-xl bg-slate-950" />
                  </div>
                )}
              </div>
            </div>
          )}

          {/* --- OVERVIEW VIEW --- */}
          {currentPage === 'overview' && (
            <div className="flex flex-col gap-10 animate-in fade-in slide-in-from-bottom-4 duration-500">
               <div className="grid grid-cols-4 gap-6">
                 {[ 
                   { l: '已存储影像数', v: libraryData.length, i: Database, c: 'blue' },
                   { l: '存储容量占用', v: `${(libraryData.reduce((acc, curr) => acc + curr.size, 0) / 1024).toFixed(2)} GB`, i: ImageIcon, c: 'indigo' },
                   { l: '待处理任务', v: libraryData.filter(i => i.status === 'pending').length, i: Activity, c: 'amber' },
                   { l: '已完成计算', v: libraryData.filter(i => i.status === 'processed').length, i: Check, c: 'green' }
                 ].map((s, i) => (
                   <div key={i} className="bg-white p-7 rounded-[2.5rem] border flex items-center gap-5 shadow-sm hover:shadow-md transition-shadow">
                     <div className={`w-14 h-14 bg-${s.c}-50 rounded-2xl flex items-center justify-center text-${s.c}-600 shrink-0`}><s.i size={28} /></div>
                     <div><p className="text-[11px] text-slate-400 font-bold uppercase mb-1">{s.l}</p><p className="text-2xl font-black text-slate-800">{s.v}</p></div>
                   </div>
                 ))}
               </div>
               
               <div className="bg-white p-10 rounded-[3rem] border shadow-sm">
                  <div className="flex justify-between items-center mb-8">
                    <h4 className="font-bold text-slate-800 text-lg">近期活跃影像流</h4>
                    <button onClick={() => setCurrentPage('library')} className="text-xs font-bold text-blue-600 hover:bg-blue-50 px-4 py-2 rounded-xl transition-all">查看全部影像库</button>
                  </div>
                  <div className="grid grid-cols-2 gap-4">
                    {libraryData.slice(0, 4).map(item => (
                      <div key={item.id} className="flex items-center justify-between p-5 bg-slate-50/50 rounded-3xl border border-transparent hover:border-blue-100 transition-all group">
                        <div className="flex items-center gap-5">
                          <div className={`w-16 h-12 rounded-xl flex items-center justify-center ${item.previewColor} border border-slate-700/50 flex-col gap-1 overflow-hidden relative shadow-inner`}>
                            <div className="w-6 h-6 border-white/20 border-2 rounded-full rotate-12 opacity-50"></div>
                            <div className="absolute inset-0 bg-blue-500/10 pointer-events-none"></div>
                          </div>
                          <div>
                            <p className="text-sm font-bold text-slate-700">{item.patientId}</p>
                            <p className="text-[10px] text-slate-400 font-mono">{item.date} · {item.size}MB</p>
                          </div>
                        </div>
                        <div className="flex items-center gap-4">
                          <span className={`text-[9px] font-black px-3 py-1 rounded-full uppercase tracking-widest ${item.status === 'processed' ? 'bg-green-100 text-green-700' : 'bg-amber-100 text-amber-700'}`}>
                            {item.status === 'processed' ? 'COMPLETED' : 'QUEUEING'}
                          </span>
                        </div>
                      </div>
                    ))}
                  </div>
               </div>
            </div>
          )}

          {/* --- LIBRARY VIEW (Card Grid) --- */}
          {currentPage === 'library' && (
            <div className="space-y-10 animate-in fade-in duration-500">
              <input
                ref={folderUploadInputRef}
                type="file"
                multiple
                accept=".dcm,application/dicom"
                className="hidden"
                onChange={handleLibraryFilesSelected}
                {...({ webkitdirectory: '', directory: '' } as any)}
              />
              <input
                ref={zipUploadInputRef}
                type="file"
                accept=".zip,application/zip,application/x-zip-compressed"
                className="hidden"
                onChange={handleLibraryFilesSelected}
              />
              <div className="flex justify-between items-center">
                <div>
                  <h2 className="text-2xl font-black text-slate-800">影像资产引擎</h2>
                  <p className="text-xs font-medium text-slate-400 mt-1">网页影像库中的 DICOM 3D 序列数据集</p>
                </div>
                <div className="flex items-center gap-3">
                  <button 
                    onClick={uploadImage}
                    disabled={isUploadingDicom}
                    className="px-6 py-3.5 bg-blue-600 text-white rounded-2xl text-sm font-bold hover:bg-black transition-all flex items-center gap-3 shadow-xl shadow-blue-500/20 active:scale-95 disabled:opacity-50"
                  >
                    <Plus size={18} /> {isUploadingDicom ? '上传中...' : '上传文件夹'}
                  </button>
                  <button 
                    onClick={uploadZip}
                    disabled={isUploadingDicom}
                    className="px-6 py-3.5 bg-slate-800 text-white rounded-2xl text-sm font-bold hover:bg-blue-600 transition-all flex items-center gap-3 shadow-xl shadow-slate-500/10 active:scale-95 disabled:opacity-50"
                  >
                    <Download size={18} /> 上传压缩包
                  </button>
                </div>
              </div>

              <div className="grid grid-cols-4 gap-8">
                {libraryData.map(item => (
                  <div key={item.id} className="bg-white rounded-[2.5rem] border border-slate-200 overflow-hidden flex flex-col group hover:border-blue-400 hover:shadow-2xl hover:shadow-blue-500/10 transition-all duration-300">
                    <LibraryDicomPreview item={item} />
                    
                    <div className="p-6 flex flex-col gap-4">
                      <div className="flex justify-between items-start">
                        <div>
                          <p className="text-[10px] font-black text-slate-400 uppercase tracking-tighter mb-0.5">病例标识码</p>
                          <h5 className="font-black text-slate-800 text-base font-mono">{item.patientId}</h5>
                        </div>
                        <div className="bg-slate-50 px-2 py-1 rounded-lg text-center">
                          <p className="text-[8px] font-bold text-slate-300">SIZE</p>
                          <p className="text-[10px] font-bold text-slate-500">{item.size}MB</p>
                        </div>
                      </div>

                      <div className="flex items-center gap-3 text-[10px] text-slate-400 font-bold">
                        <span className="flex items-center gap-1"><MonitorPlay size={10} /> {item.version}</span>
                        <div className="w-1 h-1 rounded-full bg-slate-200"></div>
                        <span className="flex items-center gap-1"><Activity size={10} /> {item.date}</span>
                        <div className="w-1 h-1 rounded-full bg-slate-200"></div>
                        <span>{item.fileCount || 0} 张</span>
                      </div>

                      <div className="grid grid-cols-3 gap-3 mt-2">
                        <button 
                          onClick={() => {
                            if (item.status === 'processed') {
                              setSelectedLibraryId(item.id);
                              setPreviewImage('');
                              setDeformationJob(null);
                              setCurrentPage('workspace');
                              showToast(`已选择 ${item.patientId} 作为工作站数据源`);
                            } else {
                              showToast('该影像尚在处理队列中，无法载入');
                            }
                          }}
                          className={`py-2.5 text-[11px] font-black rounded-xl transition-all ${item.status === 'processed' ? 'bg-blue-600 text-white hover:bg-black shadow-lg shadow-blue-500/20' : 'bg-slate-100 text-slate-300 cursor-not-allowed'}`}
                        >
                          调阅
                        </button>
                        <button
                          onClick={() => showLibraryInfo(item)}
                          className="py-2.5 bg-slate-900 text-white text-[11px] font-black rounded-xl hover:bg-blue-600 transition-all flex items-center justify-center gap-1"
                        >
                          <Info size={12} /> 信息
                        </button>
                        <button 
                          onClick={() => deleteImage(item.id)}
                          className="py-2.5 bg-slate-50 text-slate-400 text-[11px] font-black rounded-xl hover:bg-red-50 hover:text-red-500 transition-all border border-slate-100"
                        >
                          删除
                        </button>
                      </div>
                    </div>
                  </div>
                ))}
                
                {/* Empty Upload Slot */}
                <div
                  className="bg-slate-50/50 rounded-[2.5rem] border-2 border-dashed border-slate-200 flex flex-col items-center justify-center p-8 text-slate-300 hover:bg-white hover:border-blue-400 hover:text-blue-600 transition-all group min-h-[380px]"
                >
                  <p className="text-xs font-black uppercase tracking-widest">新增影像数据</p>
                  <p className="text-[10px] mt-2 opacity-50">支持 DICOM 文件夹和 ZIP 压缩包</p>
                  <div className="grid grid-cols-2 gap-3 w-full mt-6">
                    <button
                      onClick={uploadImage}
                      disabled={isUploadingDicom}
                      className="py-3 bg-blue-600 text-white rounded-2xl text-[11px] font-black hover:bg-black transition-all flex items-center justify-center gap-2 disabled:opacity-50"
                    >
                      <FolderOpen size={14} /> 文件夹
                    </button>
                    <button
                      onClick={uploadZip}
                      disabled={isUploadingDicom}
                      className="py-3 bg-slate-800 text-white rounded-2xl text-[11px] font-black hover:bg-blue-600 transition-all flex items-center justify-center gap-2 disabled:opacity-50"
                    >
                      <Download size={14} /> ZIP
                    </button>
                  </div>
                </div>
              </div>
            </div>
          )}

          {/* --- USERS VIEW --- */}
          {currentPage === 'users' && (
            <div className="max-w-4xl space-y-8 animate-in fade-in duration-500">
              
              {/* My Profile */}
              <div className="bg-white p-10 rounded-[2.5rem] border shadow-sm flex items-center justify-between">
                <div className="flex items-center gap-8">
                  <div className="w-20 h-20 bg-blue-600 rounded-3xl flex items-center justify-center text-white text-3xl font-black shadow-xl shadow-blue-500/20 ring-4 ring-blue-50 transition-transform hover:rotate-6">{currentUser?.username[0].toUpperCase()}</div>
                  <div>
                    <h4 className="text-2xl font-black text-slate-800">{currentUser?.username}</h4>
                    <div className="flex gap-2 mt-2">
                       <span className="px-3 py-1 bg-blue-50 text-blue-600 text-[10px] font-black rounded-lg uppercase tracking-widest border border-blue-100">{currentUser?.role} ACCESS</span>
                    </div>
                  </div>
                </div>
                <button onClick={() => setIsChangingOwnPass(!isChangingOwnPass)} className="flex items-center gap-3 text-xs font-black text-slate-400 hover:text-blue-600 transition-all bg-slate-50 px-6 py-3 rounded-2xl"><Key size={14} /> 修改系统密码</button>
              </div>

              {isChangingOwnPass && (
                <div className="bg-white p-8 rounded-[2.5rem] border border-blue-200 shadow-xl shadow-blue-500/5 animate-in fade-in slide-in-from-top-2 duration-300">
                  <p className="text-[10px] font-black text-slate-400 mb-5 uppercase tracking-widest">密钥重置通道</p>
                  <div className="flex gap-4">
                    <input type="password" placeholder="输入新访问密码..." value={pwChangeInput} onChange={e => setPwChangeInput(e.target.value)} className="flex-1 px-5 py-3.5 bg-slate-50 border border-slate-200 rounded-2xl outline-none focus:ring-2 focus:ring-blue-500 font-mono text-sm" />
                    <button onClick={() => changePassword(currentUser!.id, pwChangeInput)} className="px-10 py-3.5 bg-blue-600 text-white rounded-2xl text-xs font-black hover:bg-black transition-all shadow-lg shadow-blue-500/10 active:scale-95">确认身份并保存</button>
                  </div>
                </div>
              )}

              {/* User List Header */}
              <div className="flex items-center justify-between px-4">
                <h3 className="text-xs font-black text-slate-400 uppercase tracking-[0.2em]">系统权限生命周期管理</h3>
                {currentUser?.role === 'admin' && (
                  <button 
                    onClick={() => setShowAddUser(!showAddUser)}
                    className="w-10 h-10 rounded-full bg-slate-800 text-white flex items-center justify-center hover:bg-blue-600 transition-all shadow-xl hover:scale-110 active:scale-90"
                  >
                    <Plus size={20} />
                  </button>
                )}
              </div>

              {/* Add User Inline Form */}
              {showAddUser && currentUser?.role === 'admin' && (
                <div className="bg-white p-10 rounded-[3rem] border-4 border-dashed border-blue-100 animate-in fade-in zoom-in-95 duration-300 flex flex-col gap-6">
                  <h3 className="font-black flex items-center gap-3 text-base text-slate-800"><UserPlus size={24} className="text-blue-600" /> 创建新的医疗访问帐户</h3>
                  <div className="grid grid-cols-2 gap-6">
                    <div className="space-y-1">
                      <label className="text-[10px] font-bold text-slate-400 uppercase ml-2">账户登录名</label>
                      <input type="text" placeholder="e.g. neuro_surgery_01" value={newUsername} onChange={e => setNewUsername(e.target.value)} className="w-full px-5 py-4 bg-slate-50 border border-slate-200 rounded-2xl outline-none focus:ring-2 focus:ring-blue-500 font-medium" />
                    </div>
                    <div className="space-y-1">
                      <label className="text-[10px] font-bold text-slate-400 uppercase ml-2">初始访问密码</label>
                      <input type="password" placeholder="••••••••" value={newPassword} onChange={e => setNewPassword(e.target.value)} className="w-full px-5 py-4 bg-slate-50 border border-slate-200 rounded-2xl outline-none focus:ring-2 focus:ring-blue-500 font-mono" />
                    </div>
                  </div>
                  <div className="flex justify-end gap-3 mt-2">
                    <button onClick={() => setShowAddUser(false)} className="px-8 py-3.5 text-slate-400 font-bold text-xs hover:text-slate-600">取消创建</button>
                    <button onClick={addUser} className="px-10 py-3.5 bg-blue-600 text-white rounded-2xl text-xs font-black hover:bg-black transition-all shadow-xl shadow-blue-500/20 active:scale-95">完成账号部署</button>
                  </div>
                </div>
              )}

              {/* Improved User List with Gear Actions */}
              <div className="grid grid-cols-1 gap-4 pb-12">
                {users.map(u => (
                  <div key={u.id} className="bg-white p-5 px-8 rounded-[2rem] border border-slate-100 flex items-center justify-between relative group hover:border-blue-200 transition-all shadow-sm">
                    <div className="flex items-center gap-6">
                      <div className={`w-14 h-14 rounded-2xl flex items-center justify-center font-black text-lg shadow-sm border ${u.role === 'admin' ? 'bg-amber-50 text-amber-600 border-amber-100' : 'bg-slate-50 text-slate-600 border-slate-100'}`}>
                          {u.username[0].toUpperCase()}
                      </div>
                      <div>
                        <div className="flex items-center gap-3">
                          <p className="text-base font-black text-slate-700">{u.username}</p>
                          {u.role === 'admin' && <ShieldCheck size={14} className="text-amber-500" />}
                        </div>
                        <p className="text-[10px] text-slate-400 font-bold tracking-tighter uppercase mt-1">{u.role} · 接入于 {u.createdAt}</p>
                      </div>
                    </div>
                    
                    <div className="flex items-center gap-4">
                      {currentUser?.role === 'admin' || u.id === currentUser?.id ? (
                        <div className="relative" data-user-menu-root="true">
                          <button 
                            onClick={() => setActiveUserMenu(activeUserMenu === u.id ? null : u.id)}
                            className={`p-3 rounded-2xl transition-all ${activeUserMenu === u.id ? 'bg-blue-600 text-white shadow-lg' : 'text-slate-300 hover:text-blue-600 hover:bg-blue-50'}`}
                          >
                            <Settings size={22} className={activeUserMenu === u.id ? 'animate-spin-slow' : ''} />
                          </button>
                          
                          {activeUserMenu === u.id && (
                            <div className="absolute right-0 mt-3 w-56 bg-white rounded-[1.5rem] shadow-[0_20px_50px_rgba(0,0,0,0.15)] border border-slate-100 p-2.5 z-20 animate-in fade-in slide-in-from-top-2 duration-300">
                               <div className="px-4 py-2 border-b border-slate-50 mb-1">
                                 <p className="text-[9px] font-black text-slate-300 uppercase tracking-widest">操作选单</p>
                               </div>
                               <button 
                                 onClick={() => {
                                   const pass = prompt(`正在为 ${u.username} 重置密码，请输入新密码:`);
                                   if(pass) changePassword(u.id, pass);
                                   setActiveUserMenu(null);
                                 }}
                                 className="w-full text-left px-4 py-3 text-xs font-bold text-slate-600 hover:bg-blue-50 hover:text-blue-600 rounded-xl flex items-center gap-3 transition-all"
                               >
                                 <Key size={14} /> 修改访问密码
                               </button>
                               {currentUser?.role === 'admin' && u.id !== currentUser.id && (
                                 <button 
                                   onClick={() => {
                                     if(confirm(`警告: 确定永久删除账号 [${u.username}] 及其关联部署吗？`)) {
                                       setUsers(users.filter(usr => usr.id !== u.id));
                                       showToast('用户权限已注销');
                                     }
                                     setActiveUserMenu(null);
                                   }}
                                   className="w-full text-left px-4 py-3 text-xs font-bold text-red-500 hover:bg-red-50 rounded-xl flex items-center gap-3 mt-1 transition-all"
                                 >
                                   <LogOut size={14} /> 注销此帐户
                                 </button>
                               )}
                            </div>
                          )}
                        </div>
                      ) : (
                        <div className="px-4 py-2 bg-slate-50 rounded-xl text-[10px] font-bold text-slate-300">无权操作</div>
                      )}
                    </div>
                  </div>
                ))}
              </div>
            </div>
          )}

        </div>
      </main>

      {(libraryInfo || isLibraryInfoLoading) && (
        <div className="fixed inset-0 bg-slate-950/45 backdrop-blur-sm z-40 flex items-center justify-center p-6">
          <div className="w-full max-w-4xl max-h-[85vh] bg-white rounded-2xl shadow-2xl border border-slate-200 overflow-hidden">
            <div className="px-7 py-5 border-b flex items-center justify-between">
              <div>
                <p className="text-[10px] font-black text-slate-400 uppercase tracking-[0.2em]">DICOM 基本信息</p>
                <h3 className="text-xl font-black text-slate-800 mt-1">
                  {libraryInfo?.patientId || '正在读取影像信息'}
                </h3>
              </div>
              <button
                onClick={() => {
                  setLibraryInfo(null);
                  setIsLibraryInfoLoading(false);
                }}
                className="w-10 h-10 rounded-xl bg-slate-50 text-slate-400 hover:bg-red-50 hover:text-red-500 flex items-center justify-center transition-all"
              >
                <X size={20} />
              </button>
            </div>

            {isLibraryInfoLoading ? (
              <div className="h-72 flex items-center justify-center text-slate-400 text-sm font-bold">
                正在读取 DICOM 头信息...
              </div>
            ) : (
              <div className="p-7 overflow-y-auto max-h-[68vh]">
                <div className="grid grid-cols-2 gap-5">
                  {libraryInfo?.groups.map(group => (
                    <div key={group.title} className="border border-slate-100 rounded-2xl p-5 bg-slate-50/50">
                      <h4 className="text-xs font-black text-slate-700 mb-4">{group.title}</h4>
                      <div className="space-y-3">
                        {group.items.map(item => (
                          <div key={`${group.title}-${item.label}`} className="flex items-start justify-between gap-4 text-xs">
                            <span className="text-slate-400 font-bold shrink-0">{item.label}</span>
                            <span className="text-slate-700 font-mono text-right break-all">{item.value || '-'}</span>
                          </div>
                        ))}
                      </div>
                    </div>
                  ))}
                </div>
              </div>
            )}
          </div>
        </div>
      )}

      {/* Toast */}
      {toastMessage && (
        <div className="fixed bottom-10 right-10 bg-slate-900 text-white px-6 py-4 rounded-2xl shadow-2xl z-50 flex items-center gap-3 animate-in fade-in slide-in-from-right-10">
          <Check className="text-green-400" size={18} />
          <span className="text-sm font-bold">{toastMessage}</span>
        </div>
      )}
    </div>
  );
}

const Play = (props: any) => (
  <svg viewBox="0 0 24 24" width={props.size} height={props.size} {...props}>
    <path d="M5 3l14 9-14 9V3z" />
  </svg>
);
