const fs = require('fs').promises
const path = require('path')
const { promisify } = require('util')
const { exec } = require('child_process')
const ConfigManager = require('../config/config-manager')
const execAsync = promisify(exec)
const { defaultLogger } = require('../utils/logger');

// 创建logger实例
const logger = defaultLogger.child('RepositoryService');



class RepositoryService {
  constructor() {
    // 初始化配置管理器
    this.configManager = new ConfigManager()
    this.config = null
    
    // 磁盘使用情况缓存
    this.diskUsageCache = {
      data: null,
      timestamp: 0,
      cacheDuration: 5 * 60 * 1000 // 5分钟缓存
    }
    
    // 缓存文件路径
    this.cacheFilePath = null
  }

  // 获取当前工作目录（基于配置）
  getCurrentBaseDir() {
    if (this.config && this.config.downloadDir) {
      // 如果是相对路径，转换为绝对路径
      return path.isAbsolute(this.config.downloadDir) 
        ? this.config.downloadDir 
        : path.resolve(process.cwd(), this.config.downloadDir)
    }
    // 默认返回项目根目录下的downloads文件夹
    return path.resolve(process.cwd(), 'downloads')
  }

  // 初始化仓库
  async initialize() {
    try {
      // 初始化配置管理器
      await this.configManager.initialize()
      
      // 加载配置
      await this.loadConfig()
      
      // 确保下载目录存在
      const currentBaseDir = this.getCurrentBaseDir()
      await fs.mkdir(currentBaseDir, { recursive: true })
      
      // 初始化缓存文件路径
      this.cacheFilePath = path.join(path.dirname(this.configManager.getConfigPath()), 'disk-usage-cache.json')
      
      // 加载持久化缓存
      await this.loadPersistentCache()
      
      return { success: true, message: '仓库初始化成功' }
    } catch (error) {
      throw new Error(`仓库初始化失败: ${error.message}`)
    }
  }

  // 加载配置
  async loadConfig() {
    try {
      this.config = await this.configManager.readConfig()
    } catch (error) {
      logger.error('加载配置失败:', error)
      // 如果加载失败，使用默认配置对象
      this.config = {
        downloadDir: "./downloads",
        fileStructure: "artist/artwork",
        namingPattern: "{artist_name}/{artwork_id}_{title}",
        maxFileSize: 0,
        allowedExtensions: [".jpg", ".png", ".gif", ".webp"],
        autoMigration: false,
        migrationRules: [],
        lastUpdated: new Date().toISOString()
      }
    }
  }

  // 保存配置
  async saveConfig() {
    try {
      await this.configManager.saveConfig(this.config)
    } catch (error) {
      throw new Error(`保存配置失败: ${error.message}`)
    }
  }

  // 获取仓库配置
  async getConfig() {
    await this.loadConfig()
    return this.config
  }

  // 更新仓库配置
  async updateConfig(newConfig) {
    this.config = { ...this.config, ...newConfig }
    await this.saveConfig()
    return { success: true, message: '配置更新成功' }
  }

  // 重置仓库配置为默认值
  async resetConfig() {
    try {
      this.config = await this.configManager.resetToDefault()
      return { success: true, message: '配置已重置为默认值' }
    } catch (error) {
      throw new Error(`重置配置失败: ${error.message}`)
    }
  }

  // 获取仓库统计信息
  async getStats(forceRefresh = false) {
    try {
      const stats = await this.scanRepository()
      return {
        totalArtworks: stats.artworks.length,
        totalArtists: stats.artists.length,
        totalSize: stats.totalSize,
        diskUsage: await this.getDiskUsage(forceRefresh),
        lastScan: new Date().toISOString()
      }
    } catch (error) {
      throw new Error(`获取统计信息失败: ${error.message}`)
    }
  }

  // 扫描仓库
  async scanRepository() {
    const artworks = []
    const artists = new Set()
    let totalSize = 0

    try {
      // 确保配置已加载
      await this.loadConfig()
      
      // 使用当前配置的目录
      const currentBaseDir = this.getCurrentBaseDir()
      
      // 扫描作者目录
      const artistEntries = await fs.readdir(currentBaseDir, { withFileTypes: true })
      
      for (const artistEntry of artistEntries) {
        if (!artistEntry.isDirectory()) continue
        
        // 跳过配置文件和隐藏文件
        if (artistEntry.name.startsWith('.') || artistEntry.name === '.repository-config.json') {
          continue
        }
        
        const artistName = artistEntry.name
        const artistPath = path.join(currentBaseDir, artistName)
        
        // 扫描作者下的作品目录
        const artworkEntries = await fs.readdir(artistPath, { withFileTypes: true })
        
        for (const artworkEntry of artworkEntries) {
          if (!artworkEntry.isDirectory()) continue
          
          const fullPath = path.join(artistPath, artworkEntry.name)
          
          // 检查是否是作品目录（包含数字ID）
          const artworkMatch = artworkEntry.name.match(/^(\d+)_(.+)$/)
          if (artworkMatch) {
            const artworkId = artworkMatch[1]
            const title = artworkMatch[2]
            
            // 扫描作品文件
            const files = await this.scanArtworkFiles(fullPath)
            
            if (files.length > 0) {
              artworks.push({
                id: artworkId,
                title: title,
                artist: artistName,
                artistPath: artistPath,
                path: fullPath,
                files: files,
                size: files.reduce((sum, file) => sum + file.size, 0),
                createdAt: await this.getFileCreationTime(fullPath)
              })
              artists.add(artistName)
              totalSize += files.reduce((sum, file) => sum + file.size, 0)
            }
          }
        }
      }
      
      return {
        artworks,
        artists: Array.from(artists),
        totalSize
      }
    } catch (error) {
      throw new Error(`扫描仓库失败: ${error.message}`)
    }
  }

  // 扫描作品文件
  async scanArtworkFiles(artworkPath) {
    try {
      // 确保配置已加载
      await this.loadConfig()
      
      const files = []
      const entries = await fs.readdir(artworkPath, { withFileTypes: true })
      
      for (const entry of entries) {
        if (entry.isFile()) {
          const filePath = path.join(artworkPath, entry.name)
          const ext = path.extname(entry.name).toLowerCase()
          
          if (this.config.allowedExtensions.includes(ext)) {
            const stats = await fs.stat(filePath)
            const currentBaseDir = this.getCurrentBaseDir()
            files.push({
              name: entry.name,
              path: path.relative(currentBaseDir, filePath),
              size: stats.size,
              extension: ext,
              modifiedAt: stats.mtime
            })
          }
        }
      }
      
      return files
    } catch (error) {
      return []
    }
  }

  // 获取文件创建时间
  async getFileCreationTime(filePath) {
    try {
      const stats = await fs.stat(filePath)
      return stats.birthtime
    } catch (error) {
      return new Date()
    }
  }

  // 获取磁盘使用情况
  async getDiskUsage(forceRefresh = false) {
    try {
      const currentBaseDir = this.getCurrentBaseDir()
      
      // 检查是否在打包环境中
      const isPkg = process.pkg !== undefined
      
      // 尝试使用 fs.statfs (Node.js 内置方法) - 最快的方法
      if (!isPkg && typeof fs.statfs === 'function') {
        try {
          const stats = await fs.statfs(currentBaseDir)
          const total = stats.blocks * stats.bsize
          const free = stats.bavail * stats.bsize
          const used = total - free
          
          return {
            total,
            used,
            free,
            usagePercent: Math.round((used / total) * 100)
          }
        } catch (statfsError) {
          logger.info('fs.statfs 调用失败:', statfsError.message)
        }
      } else {
        logger.info('fs.statfs 在打包环境中不可用，尝试使用系统命令')
      }
      
      // 如果 fs.statfs 不可用，尝试使用系统命令
      if (process.platform === 'win32') {
        // Windows 系统 - 优先使用最快的命令
        const methods = [
          // 方法1: 使用 PowerShell (通常比 wmic 快)
          async () => {
            try {
              // 设置超时，避免长时间等待
              const { stdout } = await Promise.race([
                execAsync('powershell "Get-WmiObject -Class Win32_LogicalDisk | Select-Object Size,FreeSpace,Caption | ConvertTo-Json"'),
                new Promise((_, reject) => setTimeout(() => reject(new Error('PowerShell 超时')), 3000))
              ])
              
              const disks = JSON.parse(stdout)
              const diskArray = Array.isArray(disks) ? disks : [disks]
              
              for (const disk of diskArray) {
                const caption = disk.Caption
                const freeSpace = parseInt(disk.FreeSpace)
                const totalSize = parseInt(disk.Size)
                
                // 检查当前目录是否在这个磁盘上
                if (currentBaseDir.toUpperCase().startsWith(caption.toUpperCase())) {
                  const used = totalSize - freeSpace
                  return {
                    total: totalSize,
                    used,
                    free: freeSpace,
                    usagePercent: Math.round((used / totalSize) * 100)
                  }
                }
              }
            } catch (error) {
              logger.info('PowerShell 方法失败:', error.message)
              throw error
            }
          },
          
          // 方法2: 使用 wmic (备用方案)
          async () => {
            try {
              const { stdout } = await Promise.race([
                execAsync('wmic logicaldisk get size,freespace,caption /format:csv'),
                new Promise((_, reject) => setTimeout(() => reject(new Error('wmic 超时')), 3000))
              ])
              
              const lines = stdout.trim().split('\n').slice(1) // 跳过标题行
              
              for (const line of lines) {
                const parts = line.split(',')
                if (parts.length >= 3) {
                  const caption = parts[0].trim()
                  const freeSpace = parseInt(parts[1])
                  const totalSize = parseInt(parts[2])
                  
                  // 检查当前目录是否在这个磁盘上
                  if (currentBaseDir.toUpperCase().startsWith(caption.toUpperCase())) {
                    const used = totalSize - freeSpace
                    return {
                      total: totalSize,
                      used,
                      free: freeSpace,
                      usagePercent: Math.round((used / totalSize) * 100)
                    }
                  }
                }
              }
            } catch (error) {
              logger.info('wmic 方法失败:', error.message)
              throw error
            }
          }
        ]
        
        // 尝试所有方法，但限制总时间
        for (const method of methods) {
          try {
            const result = await Promise.race([
              method(),
              new Promise((_, reject) => setTimeout(() => reject(new Error('磁盘信息获取超时')), 5000))
            ])
            if (result) {
              return result
            }
          } catch (error) {
            logger.info(`磁盘使用情况获取方法失败:`, error.message)
            continue
          }
        }
      } else {
        // Unix/Linux 系统
        try {
          const { stdout } = await Promise.race([
            execAsync(`df -B1 "${currentBaseDir}" | tail -1`),
            new Promise((_, reject) => setTimeout(() => reject(new Error('df 命令超时')), 3000))
          ])
          
          const parts = stdout.trim().split(/\s+/)
          if (parts.length >= 4) {
            const total = parseInt(parts[1])
            const used = parseInt(parts[2])
            const free = parseInt(parts[3])
            
            return {
              total,
              used,
              free,
              usagePercent: Math.round((used / total) * 100)
            }
          }
        } catch (dfError) {
          logger.info('df 命令失败:', dfError.message)
        }
      }
      
      // 如果系统命令都失败，返回基于缓存的估算值
      return await this.getCachedDiskUsage(currentBaseDir, forceRefresh)
      
    } catch (error) {
      logger.error('获取磁盘使用情况失败:', error)
      return { 
        total: 0, 
        used: 0, 
        free: 0, 
        usagePercent: 0,
        note: '获取失败'
      }
    }
  }

  // 获取作者作品
  async getArtworksByArtist(artistName, offset = 0, limit = 50) {
    try {
      const stats = await this.scanRepository()
      const artistArtworks = stats.artworks.filter(artwork => 
        artwork.artist.toLowerCase() === artistName.toLowerCase()
      )
      
      return {
        artworks: artistArtworks.slice(offset, offset + limit),
        total: artistArtworks.length,
        offset,
        limit
      }
    } catch (error) {
      throw new Error(`获取作者作品失败: ${error.message}`)
    }
  }

  // 按作品ID查找
  async findArtworkById(artworkId) {
    try {
      const stats = await this.scanRepository()
      return stats.artworks.find(artwork => artwork.id === artworkId)
    } catch (error) {
      throw new Error(`查找作品失败: ${error.message}`)
    }
  }

  // 检查作品是否已下载
  async isArtworkDownloaded(artworkId) {
    try {
      // 确保配置已加载
      await this.loadConfig()
      
      // 使用当前配置的目录
      const currentBaseDir = this.getCurrentBaseDir()
      
      // 扫描所有作者目录
      const artistEntries = await fs.readdir(currentBaseDir, { withFileTypes: true })
      
      for (const artistEntry of artistEntries) {
        if (!artistEntry.isDirectory()) continue
        
        // 跳过配置文件和隐藏文件
        if (artistEntry.name.startsWith('.') || artistEntry.name === '.repository-config.json') {
          continue
        }
        
        const artistPath = path.join(currentBaseDir, artistEntry.name)
        
        // 扫描作者下的作品目录
        const artworkEntries = await fs.readdir(artistPath, { withFileTypes: true })
        
        for (const artworkEntry of artworkEntries) {
          if (!artworkEntry.isDirectory()) continue
          
          // 检查是否是目标作品目录（包含数字ID）
          const artworkMatch = artworkEntry.name.match(/^(\d+)_(.+)$/)
          if (artworkMatch && artworkMatch[1] === artworkId.toString()) {
            const artworkPath = path.join(artistPath, artworkEntry.name)
            
            // 检查作品信息文件 - 这是最可靠的判断标准
            const infoPath = path.join(artworkPath, 'artwork_info.json')
            let artworkInfo;
            try {
              const infoContent = await fs.readFile(infoPath, 'utf8')
              artworkInfo = JSON.parse(infoContent)
            } catch (error) {
              // 信息文件不存在或无法读取，认为未下载
              return false
            }
            
            // 检查是否有图片文件
            const files = await this.scanArtworkFiles(artworkPath)
            if (files.length === 0) {
              // 有信息文件但没有图片文件，认为未下载
              return false
            }
            
            // 检查图片数量是否与artwork_info.json中记录的一致
            const expectedImageCount = artworkInfo.page_count || 1
            if (files.length < expectedImageCount) {
              // 图片文件数量不足，认为下载不完整
              logger.info(`作品 ${artworkId} 图片数量不匹配: 期望 ${expectedImageCount} 个，实际 ${files.length} 个`)
              return false
            }
            
            // 有信息文件、有图片文件且数量匹配，认为已下载
            // logger.info(`作品 ${artworkId} 已完整下载: ${files.length}/${expectedImageCount} 个图片文件`)
            return true
          }
        }
      }
      
      return false
    } catch (error) {
      logger.error('检查作品下载状态失败:', error)
      return false
    }
  }

  // 检查目录是否存在
  async checkDirectoryExists(dirPath) {
    try {
      // 如果是相对路径，转换为绝对路径
      const fullPath = path.isAbsolute(dirPath) ? dirPath : path.resolve(process.cwd(), dirPath)
      
      const stats = await fs.stat(fullPath)
      return stats.isDirectory()
    } catch (error) {
      return false
    }
  }

  // 搜索作品
  async searchArtworks(query, offset = 0, limit = 50) {
    try {
      const stats = await this.scanRepository()
      const filtered = stats.artworks.filter(artwork =>
        artwork.title.toLowerCase().includes(query.toLowerCase()) ||
        artwork.artist.toLowerCase().includes(query.toLowerCase()) ||
        artwork.id.includes(query)
      )
      
      return {
        artworks: filtered.slice(offset, offset + limit),
        total: filtered.length,
        offset,
        limit
      }
    } catch (error) {
      throw new Error(`搜索作品失败: ${error.message}`)
    }
  }

  // 获取所有作者列表
  async getArtists(offset = 0, limit = 50) {
    try {
      const stats = await this.scanRepository()
      const artists = stats.artists.slice(offset, offset + limit)
      
      // 获取每个作者的统计信息
      const artistsWithStats = artists.map(artistName => {
        const artistArtworks = stats.artworks.filter(artwork => artwork.artist === artistName)
        const totalSize = artistArtworks.reduce((sum, artwork) => sum + artwork.size, 0)
        
        return {
          name: artistName,
          artworkCount: artistArtworks.length,
          totalSize,
          lastUpdated: artistArtworks.length > 0 
            ? Math.max(...artistArtworks.map(a => new Date(a.createdAt).getTime()))
            : null
        }
      })
      
      return {
        artists: artistsWithStats,
        total: stats.artists.length,
        offset,
        limit
      }
    } catch (error) {
      throw new Error(`获取作者列表失败: ${error.message}`)
    }
  }

  // 自动迁移旧项目
  async migrateOldProjects(sourceDir) {
    try {
      // 确保配置已加载
      await this.loadConfig()
      
      const currentBaseDir = this.getCurrentBaseDir()
      const result = {
        success: true,
        message: '迁移完成',
        log: [],
        totalMigrated: 0
      }
      
      // 确保目标目录存在
      await fs.mkdir(currentBaseDir, { recursive: true })
      
      // 扫描源目录
      const sourceEntries = await fs.readdir(sourceDir, { withFileTypes: true })
      
      for (const entry of sourceEntries) {
        if (!entry.isDirectory()) continue
        
        const oldDirPath = path.join(sourceDir, entry.name)
        const newDirPath = path.join(currentBaseDir, entry.name)
        
        // 检查是否已存在
        try {
          await fs.access(newDirPath)
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'skipped',
            reason: '目录已存在'
          })
          continue
        } catch (error) {
          // 目录不存在，可以迁移
        }
        
        try {
          // 直接移动整个目录
          await fs.rename(oldDirPath, newDirPath)
          
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'success'
          })
          result.totalMigrated++
          
        } catch (error) {
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'error',
            reason: error.message
          })
        }
      }
      
      return result
    } catch (error) {
      throw new Error(`迁移失败: ${error.message}`)
    }
  }

  // 从旧目录迁移到新目录
  async migrateFromOldToNew(oldDir, newDir) {
    try {
      const result = {
        success: true,
        message: '迁移完成',
        log: [],
        totalMigrated: 0
      }
      
      // 检查旧目录是否存在
      try {
        await fs.access(oldDir)
      } catch (error) {
        return {
          ...result,
          message: '旧目录不存在，无需迁移'
        }
      }
      
      // 确保新目录存在
      await fs.mkdir(newDir, { recursive: true })
      
      // 扫描旧目录
      const oldEntries = await fs.readdir(oldDir, { withFileTypes: true })
      
      for (const entry of oldEntries) {
        if (!entry.isDirectory()) continue
        
        const oldEntryPath = path.join(oldDir, entry.name)
        const newEntryPath = path.join(newDir, entry.name)
        
        // 检查是否已存在
        try {
          await fs.access(newEntryPath)
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'skipped',
            reason: '目录已存在'
          })
          continue
        } catch (error) {
          // 目录不存在，可以迁移
        }
        
        try {
          // 直接移动整个目录
          await fs.rename(oldEntryPath, newEntryPath)
          
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'success'
          })
          result.totalMigrated++
          
        } catch (error) {
          result.log.push({
            id: entry.name,
            title: entry.name,
            status: 'error',
            reason: error.message
          })
        }
      }
      
      return result
    } catch (error) {
      throw new Error(`迁移失败: ${error.message}`)
    }
  }

  // 复制目录
  async copyDirectory(source, target) {
    try {
      await fs.mkdir(target, { recursive: true })
      const entries = await fs.readdir(source, { withFileTypes: true })
      
      for (const entry of entries) {
        const sourcePath = path.join(source, entry.name)
        const targetPath = path.join(target, entry.name)
        
        if (entry.isDirectory()) {
          await this.copyDirectory(sourcePath, targetPath)
        } else {
          await fs.copyFile(sourcePath, targetPath)
        }
      }
    } catch (error) {
      throw new Error(`复制目录失败: ${error.message}`)
    }
  }

  // 删除作品
  async deleteArtwork(artworkId, req) {
    try {
      // 优化：直接通过文件系统查找，避免全仓库扫描
      const artwork = await this.findArtworkByIdOptimized(artworkId)
      if (!artwork) {
        throw new Error('作品不存在')
      }
      
      // 从注册表中移除作品记录
      try {
        // 使用共享的下载服务实例，而不是创建新实例
        const downloadService = req.backend?.getDownloadService();
        if (downloadService) {
          await downloadService.downloadRegistry.removeArtwork(artwork.artist, artworkId);
          logger.debug('已从下载注册表中移除作品', { 
            artistName: artwork.artist, 
            artworkId: artworkId 
          });
        } else {
          logger.warn('无法获取下载服务实例，跳过注册表更新');
        }
      } catch (error) {
        logger.warn('从下载注册表中移除作品失败:', error.message);
      }
      
      await fs.rm(artwork.path, { recursive: true, force: true })
      
      // 优化：直接检查作者目录是否为空，避免重复扫描
      const artistDir = artwork.artistPath
      try {
        const artistEntries = await fs.readdir(artistDir, { withFileTypes: true })
        const hasArtworks = artistEntries.some(entry => 
          entry.isDirectory() && entry.name.match(/^\d+_/)
        )
        
        if (!hasArtworks) {
          await fs.rmdir(artistDir)
        }
      } catch (error) {
        // 如果读取目录失败，可能目录已经不存在，忽略错误
        logger.warn(`检查作者目录失败: ${error.message}`)
      }
      
      return { success: true, message: '作品删除成功' }
    } catch (error) {
      throw new Error(`删除作品失败: ${error.message}`)
    }
  }

  // 优化的作品查找方法：直接通过文件系统查找，避免全仓库扫描
  async findArtworkByIdOptimized(artworkId) {
    try {
      // 确保配置已加载
      await this.loadConfig()
      
      // 使用当前配置的目录
      const currentBaseDir = this.getCurrentBaseDir()
      
      // 扫描所有作者目录
      const artistEntries = await fs.readdir(currentBaseDir, { withFileTypes: true })
      
      for (const artistEntry of artistEntries) {
        if (!artistEntry.isDirectory()) continue
        
        // 跳过配置文件和隐藏文件
        if (artistEntry.name.startsWith('.') || artistEntry.name === '.repository-config.json') {
          continue
        }
        
        const artistName = artistEntry.name
        const artistPath = path.join(currentBaseDir, artistName)
        
        // 扫描作者下的作品目录
        const artworkEntries = await fs.readdir(artistPath, { withFileTypes: true })
        
        for (const artworkEntry of artworkEntries) {
          if (!artworkEntry.isDirectory()) continue
          
          // 检查是否是目标作品目录（包含数字ID）
          const artworkMatch = artworkEntry.name.match(/^(\d+)_(.+)$/)
          if (artworkMatch && artworkMatch[1] === artworkId.toString()) {
            const artworkPath = path.join(artistPath, artworkEntry.name)
            const title = artworkMatch[2]
            
            // 找到目标作品，返回基本信息（不需要扫描文件详情）
            return {
              id: artworkId,
              title: title,
              artist: artistName,
              artistPath: artistPath,
              path: artworkPath
            }
          }
        }
      }
      
      return null // 未找到作品
    } catch (error) {
      throw new Error(`查找作品失败: ${error.message}`)
    }
  }

  // 加载持久化缓存
  async loadPersistentCache() {
    try {
      if (!this.cacheFilePath) {
        return
      }
      
      const cacheData = await fs.readFile(this.cacheFilePath, 'utf8')
      const cache = JSON.parse(cacheData)
      
      // 检查缓存是否有效（24小时内）
      const now = Date.now()
      const cacheAge = now - cache.timestamp
      const maxCacheAge = 24 * 60 * 60 * 1000 // 24小时
      
      if (cacheAge < maxCacheAge) {
        this.diskUsageCache.data = cache.data
        this.diskUsageCache.timestamp = cache.timestamp
        logger.info('已加载持久化缓存，缓存年龄:', Math.round(cacheAge / 1000 / 60), '分钟')
      } else {
        logger.info('持久化缓存已过期，将重新计算')
      }
    } catch (error) {
      logger.info('加载持久化缓存失败，将使用内存缓存:', error.message)
    }
  }

  // 保存持久化缓存
  async savePersistentCache() {
    try {
      if (!this.cacheFilePath || !this.diskUsageCache.data) {
        return
      }
      
      const cacheData = {
        data: this.diskUsageCache.data,
        timestamp: this.diskUsageCache.timestamp,
        savedAt: new Date().toISOString()
      }
      
      await fs.writeFile(this.cacheFilePath, JSON.stringify(cacheData, null, 2), 'utf8')
      logger.info('持久化缓存已保存')
    } catch (error) {
      logger.error('保存持久化缓存失败:', error.message)
    }
  }

  // 清除磁盘使用情况缓存
  async clearDiskUsageCache() {
    try {
      // 清除内存缓存
      this.diskUsageCache.data = null
      this.diskUsageCache.timestamp = 0
      
      // 删除持久化缓存文件
      if (this.cacheFilePath) {
        try {
          await fs.unlink(this.cacheFilePath)
          logger.info('持久化缓存文件已删除')
        } catch (error) {
          logger.info('删除持久化缓存文件失败:', error.message)
        }
      }
      
      return { success: true, message: '缓存已清除' }
    } catch (error) {
      throw new Error(`清除缓存失败: ${error.message}`)
    }
  }

  // 获取缓存的磁盘使用情况
  async getCachedDiskUsage(currentBaseDir, forceRefresh = false) {
    const now = Date.now()
    
    // 检查内存缓存是否有效（除非强制刷新）
    if (!forceRefresh && this.diskUsageCache.data && 
        (now - this.diskUsageCache.timestamp) < this.diskUsageCache.cacheDuration) {
      logger.info('使用内存缓存的磁盘使用情况')
      return this.diskUsageCache.data
    }
    
    // 缓存过期或不存在，计算新的值
    try {
      // 快速估算：只计算前几层目录
      const estimatedSize = await this.quickDirectorySizeEstimate(currentBaseDir)
      
      // 基于估算值创建磁盘使用情况
      const estimatedTotal = Math.max(estimatedSize * 200, 100 * 1024 * 1024 * 1024) // 至少100GB
      const estimatedUsed = estimatedSize
      const estimatedFree = estimatedTotal - estimatedUsed
      
      const result = {
        total: estimatedTotal,
        used: estimatedUsed,
        free: estimatedFree,
        usagePercent: Math.round((estimatedUsed / estimatedTotal) * 100),
        note: '基于目录估算（缓存5分钟）'
      }
      
      // 更新内存缓存
      this.diskUsageCache.data = result
      this.diskUsageCache.timestamp = now
      
      // 保存到持久化缓存
      await this.savePersistentCache()
      
      return result
    } catch (error) {
      logger.info('快速估算失败，返回默认值:', error.message)
      return { 
        total: 0, 
        used: 0, 
        free: 0, 
        usagePercent: 0,
        note: '无法获取磁盘信息'
      }
    }
  }

  // 快速目录大小估算（只计算前几层）
  async quickDirectorySizeEstimate(dirPath, maxDepth = 2, currentDepth = 0) {
    try {
      if (currentDepth >= maxDepth) {
        return 0
      }
      
      let totalSize = 0
      const entries = await fs.readdir(dirPath, { withFileTypes: true })
      
      // 限制处理的文件数量，避免过长时间
      const maxFiles = 1000
      let processedFiles = 0
      
      for (const entry of entries) {
        if (processedFiles >= maxFiles) {
          break
        }
        
        const fullPath = path.join(dirPath, entry.name)
        
        if (entry.isDirectory()) {
          totalSize += await this.quickDirectorySizeEstimate(fullPath, maxDepth, currentDepth + 1)
        } else {
          try {
            const stats = await fs.stat(fullPath)
            totalSize += stats.size
            processedFiles++
          } catch (error) {
            // 忽略无法访问的文件
          }
        }
      }
      
      // 如果达到文件数量限制，进行估算
      if (processedFiles >= maxFiles) {
        const remainingEntries = entries.length - processedFiles
        const avgFileSize = totalSize / processedFiles
        totalSize += remainingEntries * avgFileSize
      }
      
      return totalSize
    } catch (error) {
      logger.error('快速目录大小估算失败:', error)
      return 0
    }
  }

  // 计算目录大小（完整版本，用于需要精确值时）
  async calculateDirectorySize(dirPath) {
    try {
      let totalSize = 0
      const entries = await fs.readdir(dirPath, { withFileTypes: true })
      
      for (const entry of entries) {
        const fullPath = path.join(dirPath, entry.name)
        
        if (entry.isDirectory()) {
          totalSize += await this.calculateDirectorySize(fullPath)
        } else {
          try {
            const stats = await fs.stat(fullPath)
            totalSize += stats.size
          } catch (error) {
            // 忽略无法访问的文件
            logger.info(`无法访问文件: ${fullPath}`)
          }
        }
      }
      
      return totalSize
    } catch (error) {
      logger.error('计算目录大小失败:', error)
      return 0
    }
  }

  // 获取文件预览URL
  async getFilePreviewUrl(filePath) {
    // 这里可以返回一个代理URL，用于前端预览
    const relativePath = path.relative(this.baseDir, filePath)
    return `/api/repository/preview?path=${encodeURIComponent(relativePath)}`
  }
}

module.exports = RepositoryService