import { ConfigStore } from './ConfigStore'
import { exec } from 'child_process'
import { promisify } from 'util'
import { existsSync, mkdirSync, readdirSync, rmSync, readFileSync, writeFileSync, unlinkSync, statSync } from 'fs'
import { join } from 'path'
import https from 'https'
import http from 'http'
import { createWriteStream, createReadStream } from 'fs'
import { sendDownloadProgress } from '../main'
import { createHash } from 'crypto'

// Import unzipper with any type to avoid type issues
const unzipper = require('unzipper')

const execAsync = promisify(exec)

// ==================== 错误处理系统 ====================

/**
 * Go 管理器错误类型枚举
 */
enum GoErrorType {
  NETWORK_ERROR = 'NETWORK_ERROR',
  DISK_SPACE_ERROR = 'DISK_SPACE_ERROR',
  PERMISSION_ERROR = 'PERMISSION_ERROR',
  VALIDATION_ERROR = 'VALIDATION_ERROR',
  FILE_SYSTEM_ERROR = 'FILE_SYSTEM_ERROR',
  ENVIRONMENT_ERROR = 'ENVIRONMENT_ERROR',
  DOWNLOAD_ERROR = 'DOWNLOAD_ERROR',
  INSTALLATION_ERROR = 'INSTALLATION_ERROR',
  UNINSTALL_ERROR = 'UNINSTALL_ERROR',
  CONFIGURATION_ERROR = 'CONFIGURATION_ERROR'
}

/**
 * Go 管理器自定义错误类
 * 提供结构化的错误信息和解决建议
 */
class GoManagerError extends Error {
  public readonly type: GoErrorType
  public readonly suggestion: string
  public readonly retryable: boolean
  public readonly details?: any

  constructor(
    type: GoErrorType,
    message: string,
    suggestion: string,
    retryable: boolean = false,
    details?: any
  ) {
    super(message)
    this.name = 'GoManagerError'
    this.type = type
    this.suggestion = suggestion
    this.retryable = retryable
    this.details = details
  }
}

/**
 * 操作结果接口
 * 统一的操作结果格式，包含成功状态、消息和详细信息
 */
interface OperationResult {
  success: boolean
  message: string
  suggestion?: string
  retryable?: boolean
  details?: any
}

/**
 * 系统资源检查结果
 */
interface SystemResourceCheck {
  hasPermission: boolean
  hasDiskSpace: boolean
  availableSpace: number
  requiredSpace: number
  permissionDetails?: string
}

/**
 * 网络连接检查结果
 */
interface NetworkCheck {
  isConnected: boolean
  canReachGolang: boolean
  responseTime?: number
  error?: string
}

interface GoVersion {
  version: string        // 版本号，如 "1.21.5"
  path: string          // 安装路径
  isActive: boolean     // 是否为当前活动版本
  goroot: string        // GOROOT 路径
  gopath?: string       // GOPATH 路径（可选）
  installDate?: Date    // 安装日期
  size?: number         // 安装大小（字节）
}

interface AvailableGoVersion {
  version: string       // 版本号
  stable: boolean       // 是否为稳定版本
  downloadUrl: string   // Windows 64位 ZIP 下载链接
  size: number         // 文件大小（字节）
  sha256: string       // SHA256 校验和
  releaseDate?: string // 发布日期
}

interface GoInfo {
  version: string       // Go 版本
  goroot: string       // GOROOT 路径
  gopath: string       // GOPATH 路径
  goversion: string    // go version 命令输出
  goos: string         // 目标操作系统
  goarch: string       // 目标架构
}

interface GoRelease {
  version: string
  stable: boolean
  files: GoFile[]
}

interface GoFile {
  filename: string
  os: string
  arch: string
  version: string
  sha256: string
  size: number
  kind: 'archive' | 'installer' | 'source'
}

interface DownloadOptions {
  url: string
  dest: string
  name: string
  expectedSha256?: string
  maxRetries?: number
  timeout?: number
}

interface DownloadProgress {
  percent: number
  downloadedBytes: number
  totalBytes: number
  speed?: number
}

interface DownloadResult {
  success: boolean
  message: string
  suggestion?: string
  retryable?: boolean
  details?: any
  filePath?: string
}

export class GoManager {
  private configStore: ConfigStore
  private versionsCache: AvailableGoVersion[] = []
  private cacheTime: number = 0
  private readonly CACHE_DURATION = 5 * 60 * 1000 // 5 分钟缓存

  constructor(configStore: ConfigStore) {
    this.configStore = configStore
  }

  // ==================== 综合错误处理系统 ====================

  /**
   * 检查系统资源（磁盘空间和权限）
   * Requirements: 8.2, 8.3
   */
  private async checkSystemResources(requiredSpaceBytes: number = 500 * 1024 * 1024): Promise<SystemResourceCheck> {
    const result: SystemResourceCheck = {
      hasPermission: false,
      hasDiskSpace: false,
      availableSpace: 0,
      requiredSpace: requiredSpaceBytes
    }

    try {
      // 检查磁盘空间
      const goBasePath = this.getGoBasePath()
      const drive = goBasePath.split(':')[0] + ':'
      
      try {
        const { stdout } = await execAsync(`powershell "Get-WmiObject -Class Win32_LogicalDisk -Filter \\"DeviceID='${drive}'\\" | Select-Object FreeSpace"`, { timeout: 10000 })
        const freeSpaceMatch = stdout.match(/(\d+)/)
        if (freeSpaceMatch) {
          result.availableSpace = parseInt(freeSpaceMatch[1], 10)
          result.hasDiskSpace = result.availableSpace >= requiredSpaceBytes
        }
      } catch (error) {
        console.warn('磁盘空间检查失败，使用默认值')
        result.availableSpace = requiredSpaceBytes // 假设有足够空间
        result.hasDiskSpace = true
      }

      // 检查写入权限
      try {
        const testDir = join(goBasePath, 'permission_test')
        if (!existsSync(goBasePath)) {
          mkdirSync(goBasePath, { recursive: true })
        }
        mkdirSync(testDir, { recursive: true })
        rmSync(testDir, { recursive: true, force: true })
        result.hasPermission = true
      } catch (error: any) {
        result.hasPermission = false
        result.permissionDetails = error.message
      }

    } catch (error: any) {
      console.error('系统资源检查失败:', error)
      result.permissionDetails = error.message
    }

    return result
  }

  /**
   * 检查网络连接
   * Requirements: 8.1
   */
  private async checkNetworkConnection(): Promise<NetworkCheck> {
    const result: NetworkCheck = {
      isConnected: false,
      canReachGolang: false
    }

    try {
      // 检查基本网络连接
      const startTime = Date.now()
      await new Promise<void>((resolve, reject) => {
        const req = https.get('https://golang.org', { timeout: 10000 }, (res) => {
          result.isConnected = true
          result.canReachGolang = res.statusCode === 200 || res.statusCode === 301 || res.statusCode === 302
          result.responseTime = Date.now() - startTime
          resolve()
        })
        
        req.on('error', (error) => {
          result.error = error.message
          reject(error)
        })
        
        req.on('timeout', () => {
          req.destroy()
          result.error = '连接超时'
          reject(new Error('连接超时'))
        })
      })
    } catch (error: any) {
      result.error = error.message
    }

    return result
  }

  /**
   * 创建结构化的错误结果
   * Requirements: 8.5
   */
  private createErrorResult(error: GoManagerError | Error, operation: string): OperationResult {
    if (error instanceof GoManagerError) {
      return {
        success: false,
        message: `${operation}失败: ${error.message}`,
        suggestion: error.suggestion,
        retryable: error.retryable,
        details: error.details
      }
    }

    // 处理普通错误，提供通用建议
    let suggestion = '请检查网络连接和系统权限，然后重试'
    let retryable = true

    // 根据错误消息提供具体建议
    const errorMessage = error.message.toLowerCase()
    if (errorMessage.includes('network') || errorMessage.includes('timeout') || errorMessage.includes('连接')) {
      suggestion = '网络连接失败，请检查网络设置并重试。如果问题持续，请尝试使用VPN或更换网络环境'
      retryable = true
    } else if (errorMessage.includes('permission') || errorMessage.includes('access') || errorMessage.includes('权限')) {
      suggestion = '权限不足，请以管理员身份运行程序，或检查目标目录的写入权限'
      retryable = false
    } else if (errorMessage.includes('space') || errorMessage.includes('disk') || errorMessage.includes('磁盘')) {
      suggestion = '磁盘空间不足，请清理磁盘空间后重试。建议至少保留500MB可用空间'
      retryable = false
    } else if (errorMessage.includes('sha256') || errorMessage.includes('checksum') || errorMessage.includes('校验')) {
      suggestion = '文件校验失败，可能是下载过程中文件损坏。请删除临时文件并重新下载'
      retryable = true
    }

    return {
      success: false,
      message: `${operation}失败: ${error.message}`,
      suggestion,
      retryable
    }
  }

  /**
   * 创建成功结果
   * Requirements: 8.4
   */
  private createSuccessResult(message: string, details?: any): OperationResult {
    return {
      success: true,
      message,
      details
    }
  }

  /**
   * 处理网络错误并提供重试选项
   * Requirements: 8.1
   */
  private async handleNetworkError(operation: () => Promise<any>, maxRetries: number = 3): Promise<any> {
    let lastError: Error | null = null
    
    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        // 在重试前检查网络连接
        if (attempt > 1) {
          console.log(`第 ${attempt} 次尝试前检查网络连接...`)
          const networkCheck = await this.checkNetworkConnection()
          if (!networkCheck.isConnected) {
            throw new GoManagerError(
              GoErrorType.NETWORK_ERROR,
              '网络连接不可用',
              '请检查网络连接后重试。确保可以访问 golang.org',
              true,
              { networkCheck }
            )
          }
        }

        return await operation()
      } catch (error: any) {
        lastError = error
        console.error(`尝试 ${attempt}/${maxRetries} 失败:`, error.message)
        
        if (attempt < maxRetries) {
          // 指数退避重试
          const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
          console.log(`等待 ${delay}ms 后重试...`)
          await new Promise(resolve => setTimeout(resolve, delay))
        }
      }
    }

    // 所有重试都失败了
    throw new GoManagerError(
      GoErrorType.NETWORK_ERROR,
      `网络操作失败（已重试 ${maxRetries} 次）: ${lastError?.message || '未知错误'}`,
      '请检查网络连接，确保可以访问 golang.org。如果问题持续，请尝试使用VPN或联系网络管理员',
      true,
      { attempts: maxRetries, lastError: lastError?.message }
    )
  }

  /**
   * 验证系统环境并抛出具体错误
   * Requirements: 8.2, 8.3
   */
  private async validateSystemEnvironment(requiredSpaceBytes: number = 500 * 1024 * 1024): Promise<void> {
    const resourceCheck = await this.checkSystemResources(requiredSpaceBytes)

    if (!resourceCheck.hasDiskSpace) {
      const availableMB = Math.round(resourceCheck.availableSpace / (1024 * 1024))
      const requiredMB = Math.round(requiredSpaceBytes / (1024 * 1024))
      
      throw new GoManagerError(
        GoErrorType.DISK_SPACE_ERROR,
        `磁盘空间不足，可用空间 ${availableMB}MB，需要 ${requiredMB}MB`,
        `请清理磁盘空间，至少需要 ${requiredMB}MB 可用空间。建议清理临时文件、回收站或卸载不需要的程序`,
        false,
        { availableSpace: resourceCheck.availableSpace, requiredSpace: requiredSpaceBytes }
      )
    }

    if (!resourceCheck.hasPermission) {
      throw new GoManagerError(
        GoErrorType.PERMISSION_ERROR,
        '权限不足，无法写入目标目录',
        '请以管理员身份运行程序，或确保当前用户对安装目录有写入权限。您也可以尝试更改安装目录到用户文件夹',
        false,
        { permissionDetails: resourceCheck.permissionDetails }
      )
    }
  }

  /**
   * 获取 Go 基础安装路径
   */
  getGoBasePath(): string {
    return join(this.configStore.getBasePath(), 'go')
  }

  /**
   * 获取指定版本的 Go 路径
   */
  getGoPath(version: string): string {
    return join(this.getGoBasePath(), `go-${version}`)
  }

  /**
   * 获取默认 GOPATH 工作空间路径
   */
  getDefaultGoPath(): string {
    return join(this.getGoBasePath(), 'workspace')
  }

  /**
   * 获取已安装的 Go 版本
   */
  async getInstalledVersions(): Promise<GoVersion[]> {
    const versions: GoVersion[] = []
    const goBasePath = this.getGoBasePath()

    if (!existsSync(goBasePath)) {
      return versions
    }

    const dirs = readdirSync(goBasePath, { withFileTypes: true })
    const activeVersion = this.configStore.get('activeGoVersion' as any) || ''

    for (const dir of dirs) {
      if (dir.isDirectory() && dir.name.startsWith('go-')) {
        const versionDir = join(goBasePath, dir.name)
        const goExe = join(versionDir, 'bin', 'go.exe')
        const gofmtExe = join(versionDir, 'bin', 'gofmt.exe')

        // 验证安装完整性
        if (existsSync(goExe) && existsSync(gofmtExe)) {
          const version = dir.name.replace('go-', '')
          const goroot = versionDir
          const gopath = this.getDefaultGoPath()

          // 获取安装日期和大小信息
          let installDate: Date | undefined
          let size: number | undefined
          
          try {
            const stats = require('fs').statSync(versionDir)
            installDate = stats.birthtime || stats.mtime
            
            // 计算目录大小（简化版本，只统计主要文件）
            const binDir = join(versionDir, 'bin')
            if (existsSync(binDir)) {
              const binFiles = readdirSync(binDir)
              size = binFiles.reduce((total, file) => {
                try {
                  const filePath = join(binDir, file)
                  const fileStats = require('fs').statSync(filePath)
                  return total + fileStats.size
                } catch {
                  return total
                }
              }, 0)
            }
          } catch {
            // 忽略统计错误
          }

          versions.push({
            version,
            path: versionDir,
            isActive: version === activeVersion,
            goroot,
            gopath,
            installDate,
            size
          })
        }
      }
    }

    // 按版本号排序（降序）
    versions.sort((a, b) => {
      const aParts = a.version.replace('go', '').split('.').map(Number)
      const bParts = b.version.replace('go', '').split('.').map(Number)
      for (let i = 0; i < 3; i++) {
        if (aParts[i] !== bParts[i]) {
          return bParts[i] - aParts[i]
        }
      }
      return 0
    })

    return versions
  }

  /**
   * 获取可用的 Go 版本列表
   * 增强的错误处理，包含网络重试机制
   * Requirements: 8.1
   */
  async getAvailableVersions(): Promise<AvailableGoVersion[]> {
    // 检查缓存
    if (this.versionsCache.length > 0 && Date.now() - this.cacheTime < this.CACHE_DURATION) {
      return this.versionsCache
    }

    try {
      // 使用网络错误处理包装器
      const versions = await this.handleNetworkError(async () => {
        return await this.fetchGoVersions()
      }, 3)

      if (versions.length > 0) {
        this.versionsCache = versions
        this.cacheTime = Date.now()
        return versions
      }
    } catch (error) {
      console.error('获取 Go 版本列表失败:', error)
      
      // 如果是网络错误，记录详细信息但不抛出异常
      if (error instanceof GoManagerError && error.type === GoErrorType.NETWORK_ERROR) {
        console.warn('使用备用版本列表，因为网络获取失败:', error.message)
      }
    }

    // 返回硬编码的版本列表作为后备
    console.log('使用备用版本列表')
    return this.getFallbackVersions()
  }

  /**
   * 从 golang.org API 获取版本列表
   */
  private async fetchGoVersions(): Promise<AvailableGoVersion[]> {
    return new Promise((resolve, reject) => {
      const url = 'https://golang.org/dl/?mode=json'

      https.get(url, {
        headers: {
          'User-Agent': 'PHPer-Dev-Manager/1.0'
        },
        timeout: 30000
      }, (res) => {
        if (res.statusCode === 301 || res.statusCode === 302) {
          const redirectUrl = res.headers.location
          if (redirectUrl) {
            https.get(redirectUrl, (redirectRes) => {
              this.handleVersionResponse(redirectRes, resolve, reject)
            }).on('error', reject)
            return
          }
        }
        this.handleVersionResponse(res, resolve, reject)
      }).on('error', reject)
        .on('timeout', () => reject(new Error('请求超时')))
    })
  }

  private handleVersionResponse(res: http.IncomingMessage, resolve: (value: AvailableGoVersion[]) => void, reject: (reason?: any) => void) {
    let data = ''
    res.on('data', chunk => data += chunk)
    res.on('end', () => {
      try {
        const releases: GoRelease[] = JSON.parse(data)
        const availableVersions: AvailableGoVersion[] = []

        for (const release of releases) {
          if (release.stable) {
            const windowsFile = release.files.find(f => 
              f.os === 'windows' && f.arch === 'amd64' && f.kind === 'archive'
            )
            
            if (windowsFile) {
              availableVersions.push({
                version: release.version,
                stable: release.stable,
                downloadUrl: `https://golang.org/dl/${windowsFile.filename}`,
                size: windowsFile.size,
                sha256: windowsFile.sha256
              })
            }
          }
        }

        // 只返回前 20 个版本
        resolve(availableVersions.slice(0, 20))
      } catch (e) {
        reject(e)
      }
    })
    res.on('error', reject)
  }

  /**
   * 安装 Go 版本
   * 包含完整的安装流程：下载、解压、验证、配置
   * 增强的错误处理和用户反馈
   * Requirements: 8.1, 8.2, 8.3, 8.4, 8.5
   */
  async install(version: string, downloadUrl: string, expectedSha256?: string): Promise<OperationResult> {
    try {
      console.log(`开始安装 Go ${version}...`)
      
      // 1. 系统环境验证（磁盘空间和权限检查）
      console.log('检查系统环境...')
      await this.validateSystemEnvironment(500 * 1024 * 1024) // 500MB 最小空间要求

      const goBasePath = this.getGoBasePath()
      const tempPath = this.configStore.getTempPath()
      const zipPath = join(tempPath, `go-${version}.zip`)
      const extractDir = join(goBasePath, `go-${version}`)

      // 确保目录存在
      if (!existsSync(goBasePath)) {
        mkdirSync(goBasePath, { recursive: true })
      }
      if (!existsSync(tempPath)) {
        mkdirSync(tempPath, { recursive: true })
      }

      // 2. 重复安装检测和防护
      if (await this.isVersionInstalled(version)) {
        return {
          success: false,
          message: `Go ${version} 已安装`,
          suggestion: '如需重新安装，请先卸载现有版本',
          retryable: false
        }
      }

      console.log(`系统环境检查通过，开始安装 Go ${version}`)

      try {
        // 3. 下载（使用增强的下载管理器，包含网络重试和 SHA256 验证）
        console.log(`正在下载 Go ${version}...`)
        await this.downloadFile(downloadUrl, zipPath, `go-${version}`, expectedSha256)

        // 4. ZIP 文件解压到目标目录
        console.log(`正在解压 Go ${version}...`)
        await this.extractGoArchive(zipPath, goBasePath, version)

        // 5. 安装后验证和完整性检查
        console.log(`正在验证 Go ${version} 安装...`)
        const validationResult = await this.performInstallationValidation(version)
        if (!validationResult.isValid) {
          // 如果验证失败，清理安装目录
          await this.cleanupFailedInstallation(extractDir)
          throw new GoManagerError(
            GoErrorType.VALIDATION_ERROR,
            `安装验证失败: ${validationResult.error}`,
            '安装文件可能损坏，请重新下载安装。如果问题持续，请检查网络连接或尝试其他版本',
            true,
            { validationError: validationResult.error }
          )
        }

        // 6. 更新配置
        await this.updateInstallationConfig(version)

        // 7. 如果是第一个版本，设为默认
        const installedVersions = await this.getInstalledVersions()
        let activationMessage = ''
        if (installedVersions.length === 1) {
          const activationResult = await this.setActive(version)
          if (activationResult.success) {
            activationMessage = '，并已设为默认版本'
          }
        }

        // 8. 返回详细的成功信息
        const installPath = this.getGoPath(version)
        return this.createSuccessResult(
          `Go ${version} 安装成功${activationMessage}`,
          {
            version,
            installPath,
            isActive: installedVersions.length === 1,
            totalVersions: installedVersions.length,
            nextSteps: installedVersions.length === 1 
              ? ['Go 已设为默认版本，可以在新的命令行窗口中使用 go 命令']
              : [`使用 "设为默认" 按钮来激活 Go ${version}`, '或继续安装其他版本']
          }
        )

      } finally {
        // 清理临时文件（无论成功还是失败）
        await this.cleanupTempFiles(zipPath)
      }

    } catch (error: any) {
      console.error(`Go ${version} 安装失败:`, error)
      return this.createErrorResult(error, `Go ${version} 安装`)
    }
  }

  /**
   * 卸载 Go 版本
   * 包含完整的文件系统清理、环境变量清理和配置状态更新
   * 增强的错误处理和用户反馈
   * Requirements: 2.2, 2.3, 2.4, 2.5, 8.3, 8.4, 8.5
   */
  async uninstall(version: string): Promise<OperationResult> {
    try {
      console.log(`开始卸载 Go ${version}...`)
      
      // 1. 权限检查
      await this.validateSystemEnvironment(0) // 卸载不需要磁盘空间，但需要权限
      
      const goBasePath = this.getGoBasePath()
      const versionDir = join(goBasePath, `go-${version}`)

      // 2. 检查版本是否存在
      if (!existsSync(versionDir)) {
        return {
          success: false,
          message: `Go ${version} 未安装`,
          suggestion: '请检查版本号是否正确，或刷新版本列表',
          retryable: false
        }
      }

      // 3. 获取当前活动版本
      const activeVersion = this.configStore.get('activeGoVersion' as any)
      const isActiveVersion = activeVersion === version

      console.log(`版本目录: ${versionDir}`)
      console.log(`是否为活动版本: ${isActiveVersion}`)

      // 4. 如果是当前活动版本，执行环境变量清理
      if (isActiveVersion) {
        console.log('清理活动版本的环境变量...')
        try {
          await this.cleanupActiveVersionEnvironment(version)
        } catch (error: any) {
          throw new GoManagerError(
            GoErrorType.ENVIRONMENT_ERROR,
            `环境变量清理失败: ${error.message}`,
            '请手动清理环境变量，或以管理员身份重试。您可以在系统设置中手动删除 GOROOT 和 GOPATH 环境变量',
            true,
            { environmentError: error.message }
          )
        }
      }

      // 5. 执行文件系统清理和目录删除
      console.log('执行文件系统清理...')
      try {
        await this.performFileSystemCleanup(versionDir, version)
      } catch (error: any) {
        throw new GoManagerError(
          GoErrorType.FILE_SYSTEM_ERROR,
          `文件系统清理失败: ${error.message}`,
          '可能有文件正在使用中。请关闭所有相关程序（如 IDE、终端）后重试，或重启计算机后再次尝试',
          true,
          { fileSystemError: error.message }
        )
      }

      // 6. 更新配置状态
      console.log('更新配置状态...')
      try {
        await this.updateUninstallConfiguration(version, isActiveVersion)
      } catch (error: any) {
        // 配置更新失败不应该阻止卸载成功
        console.warn('配置状态更新失败，但文件已删除:', error.message)
      }

      // 7. 检查剩余版本并提供建议
      const remainingVersions = await this.getInstalledVersions()
      let nextSteps: string[] = []
      
      if (remainingVersions.length === 0) {
        nextSteps.push('所有 Go 版本已卸载，环境变量已清理')
      } else if (isActiveVersion && remainingVersions.length > 0) {
        nextSteps.push(`还有 ${remainingVersions.length} 个版本可用`)
        nextSteps.push('请选择一个版本设为默认，或安装新版本')
      }

      console.log(`Go ${version} 卸载完成`)
      return this.createSuccessResult(
        `Go ${version} 已成功卸载`,
        {
          version,
          wasActive: isActiveVersion,
          remainingVersions: remainingVersions.length,
          nextSteps
        }
      )

    } catch (error: any) {
      console.error(`Go ${version} 卸载失败:`, error)
      return this.createErrorResult(error, `Go ${version} 卸载`)
    }
  }

  /**
   * 清理活动版本的环境变量
   * 移除 GOROOT、GOPATH 和 PATH 中的相关配置
   * 增强的错误处理
   * Requirements: 2.3, 8.3, 8.5
   */
  private async cleanupActiveVersionEnvironment(version: string): Promise<void> {
    try {
      const versionDir = this.getGoPath(version)
      
      console.log(`清理活动版本 ${version} 的环境变量`)
      
      // 使用专门的环境变量清理脚本
      const cleanupScript = this.generateActiveVersionCleanupScript()
      await this.executePowerShellScript(cleanupScript)
      
      console.log(`活动版本环境变量清理完成`)
      
    } catch (error: any) {
      console.error(`环境变量清理失败: ${error.message}`)
      
      // 如果是 GoManagerError，直接重新抛出
      if (error instanceof GoManagerError) {
        throw error
      }
      
      // 否则包装为 GoManagerError
      throw new GoManagerError(
        GoErrorType.ENVIRONMENT_ERROR,
        `环境变量清理失败: ${error.message}`,
        '请以管理员身份运行程序，或在系统设置中手动清理 GOROOT、GOPATH 和 PATH 环境变量',
        true,
        { version, originalError: error.message }
      )
    }
  }

  /**
   * 执行文件系统清理和目录删除
   * 完全删除版本目录及其所有内容
   * 增强的错误处理
   * Requirements: 2.2, 8.5
   */
  private async performFileSystemCleanup(versionDir: string, version: string): Promise<void> {
    try {
      console.log(`开始删除目录: ${versionDir}`)
      
      // 检查目录是否存在
      if (!existsSync(versionDir)) {
        console.log(`目录不存在，跳过删除: ${versionDir}`)
        return
      }

      // 获取目录信息用于日志记录
      const dirStats = this.getDirectoryStats(versionDir)
      console.log(`目录统计: ${dirStats.fileCount} 个文件, ${dirStats.dirCount} 个子目录`)

      // 尝试删除目录（使用强制删除）
      rmSync(versionDir, { recursive: true, force: true, maxRetries: 3, retryDelay: 1000 })
      
      // 验证删除是否成功
      if (existsSync(versionDir)) {
        throw new GoManagerError(
          GoErrorType.FILE_SYSTEM_ERROR,
          `目录删除失败，目录仍然存在: ${versionDir}`,
          '可能有文件正在使用中。请关闭所有相关程序（如 IDE、终端、Go 进程）后重试，或重启计算机后再次尝试',
          true,
          { versionDir, dirStats }
        )
      }

      console.log(`目录删除成功: ${versionDir}`)
      
    } catch (error: any) {
      console.error(`文件系统清理失败: ${error.message}`)
      
      // 如果是 GoManagerError，直接重新抛出
      if (error instanceof GoManagerError) {
        throw error
      }
      
      // 根据错误类型提供具体建议
      let suggestion = '请关闭所有相关程序后重试，或重启计算机后再次尝试'
      
      if (error.code === 'EBUSY' || error.code === 'ENOTEMPTY') {
        suggestion = '文件正在使用中，请关闭所有 Go 相关程序（IDE、终端、Go 进程）后重试'
      } else if (error.code === 'EACCES' || error.code === 'EPERM') {
        suggestion = '权限不足，请以管理员身份运行程序'
      } else if (error.code === 'ENOENT') {
        suggestion = '目录不存在或已被删除'
        return // 目录不存在就不需要删除了
      }
      
      throw new GoManagerError(
        GoErrorType.FILE_SYSTEM_ERROR,
        `文件系统清理失败: ${error.message}`,
        suggestion,
        true,
        { versionDir, errorCode: error.code, originalError: error.message }
      )
    }
  }

  /**
   * 更新卸载后的配置状态
   * 从已安装版本列表中移除，清除活动版本配置
   * 增强的错误处理
   * Requirements: 2.4, 2.5, 8.5
   */
  private async updateUninstallConfiguration(version: string, wasActiveVersion: boolean): Promise<void> {
    try {
      console.log(`更新配置状态: 移除版本 ${version}`)
      
      // 从已安装版本列表中移除
      const goVersions = this.configStore.get('goVersions' as any) || []
      const index = goVersions.indexOf(version)
      if (index > -1) {
        goVersions.splice(index, 1)
        this.configStore.set('goVersions' as any, goVersions)
        console.log(`已从版本列表中移除: ${version}`)
      } else {
        console.log(`版本不在配置列表中: ${version}`)
      }

      // 如果卸载的是活动版本，清除活动版本配置
      if (wasActiveVersion) {
        this.configStore.set('activeGoVersion' as any, '')
        console.log(`已清除活动版本配置`)
        
        // 如果还有其他版本，可以提示用户选择新的活动版本
        const remainingVersions = await this.getInstalledVersions()
        if (remainingVersions.length > 0) {
          console.log(`提示: 还有 ${remainingVersions.length} 个版本可用，可以设置新的活动版本`)
        }
      }

      console.log(`配置状态更新完成`)
      
    } catch (error: any) {
      console.error(`配置状态更新失败: ${error.message}`)
      
      throw new GoManagerError(
        GoErrorType.CONFIGURATION_ERROR,
        `配置状态更新失败: ${error.message}`,
        '配置文件可能损坏或权限不足。请检查应用程序配置目录权限，或重新启动应用程序',
        true,
        { version, wasActiveVersion, originalError: error.message }
      )
    }
  }

  /**
   * 生成活动版本清理的 PowerShell 脚本
   * 清除 GOROOT、GOPATH 和 PATH 中的所有 Go 相关配置
   */
  private generateActiveVersionCleanupScript(): string {
    return `
      # Go 活动版本环境变量清理脚本
      Write-Host "开始清理 Go 活动版本环境变量..."
      
      try {
        # 获取当前用户 PATH
        $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
        if ($userPath) {
          Write-Host "当前 PATH: $userPath"
          
          $pathArray = $userPath -split ';' | Where-Object { $_ -ne '' -and $_ -ne $null }
          
          # 移除所有 Go 相关路径（更全面的清理）
          $filteredPaths = $pathArray | Where-Object { 
            -not ($_ -like '*\\go\\go-*\\bin' -or 
                  $_ -like '*\\go-*\\bin' -or 
                  $_ -like '*\\golang\\*\\bin' -or
                  $_ -like '*\\Go\\*\\bin' -or
                  $_ -like '*\\go\\bin' -or
                  $_ -like '*\\golang\\bin')
          }
          
          $finalPath = ($filteredPaths | Where-Object { $_ -ne '' -and $_ -ne $null } | Select-Object -Unique) -join ';'
          [Environment]::SetEnvironmentVariable('PATH', $finalPath, 'User')
          Write-Host "已清理 PATH 中的所有 Go 路径"
        }
        
        # 清除 GOROOT
        $currentGoRoot = [Environment]::GetEnvironmentVariable('GOROOT', 'User')
        if ($currentGoRoot) {
          [Environment]::SetEnvironmentVariable('GOROOT', $null, 'User')
          Write-Host "已清除 GOROOT: $currentGoRoot"
        }
        
        # 清除 GOPATH
        $currentGoPath = [Environment]::GetEnvironmentVariable('GOPATH', 'User')
        if ($currentGoPath) {
          [Environment]::SetEnvironmentVariable('GOPATH', $null, 'User')
          Write-Host "已清除 GOPATH: $currentGoPath"
        }
        
        Write-Host "活动版本环境变量清理完成"
        
      } catch {
        Write-Error "活动版本环境变量清理失败: $_"
        throw $_
      }
    `
  }

  /**
   * 获取目录统计信息
   * 用于日志记录和验证
   */
  private getDirectoryStats(dirPath: string): { fileCount: number; dirCount: number; totalSize: number } {
    let fileCount = 0
    let dirCount = 0
    let totalSize = 0

    try {
      const items = readdirSync(dirPath, { withFileTypes: true })
      
      for (const item of items) {
        const itemPath = join(dirPath, item.name)
        
        if (item.isDirectory()) {
          dirCount++
          const subStats = this.getDirectoryStats(itemPath)
          fileCount += subStats.fileCount
          dirCount += subStats.dirCount
          totalSize += subStats.totalSize
        } else if (item.isFile()) {
          fileCount++
          try {
            const stats = statSync(itemPath)
            totalSize += stats.size
          } catch {
            // 忽略无法访问的文件
          }
        }
      }
    } catch (error) {
      console.warn(`获取目录统计信息失败: ${dirPath}`, error)
    }

    return { fileCount, dirCount, totalSize }
  }

  /**
   * 设置活动的 Go 版本
   * 增强的错误处理和详细反馈
   * Requirements: 8.3, 8.4, 8.5
   */
  async setActive(version: string): Promise<OperationResult> {
    try {
      console.log(`设置 Go ${version} 为活动版本...`)
      
      // 1. 权限检查
      await this.validateSystemEnvironment(0) // 不需要磁盘空间，但需要权限
      
      const goBasePath = this.getGoBasePath()
      const versionDir = join(goBasePath, `go-${version}`)

      // 2. 验证版本是否已安装
      if (!existsSync(join(versionDir, 'bin', 'go.exe'))) {
        return {
          success: false,
          message: `Go ${version} 未安装`,
          suggestion: '请先安装此版本，然后再设为默认版本',
          retryable: false
        }
      }

      // 3. 更新环境变量
      try {
        await this.updateEnvironmentVariables(version)
      } catch (error: any) {
        throw new GoManagerError(
          GoErrorType.ENVIRONMENT_ERROR,
          `环境变量更新失败: ${error.message}`,
          '请以管理员身份运行程序，或手动设置环境变量。您可以在系统设置中手动添加 GOROOT 和 PATH 配置',
          true,
          { environmentError: error.message }
        )
      }

      // 4. 更新配置
      this.configStore.set('activeGoVersion' as any, version)

      // 5. 验证设置是否生效
      try {
        const goInfo = await this.getGoInfo(version)
        if (!goInfo) {
          console.warn('无法验证 Go 版本设置，但配置已更新')
        }
      } catch (error) {
        console.warn('Go 版本验证失败，但配置已更新:', error)
      }

      console.log(`Go ${version} 已设为活动版本`)
      return this.createSuccessResult(
        `已将 Go ${version} 设为默认版本`,
        {
          version,
          goroot: this.getGoPath(version),
          gopath: this.getDefaultGoPath(),
          nextSteps: [
            '请重新打开命令行窗口以使环境变量生效',
            '使用 "go version" 命令验证版本是否正确'
          ]
        }
      )
    } catch (error: any) {
      console.error(`设置活动版本失败:`, error)
      return this.createErrorResult(error, `设置 Go ${version} 为活动版本`)
    }
  }

  /**
   * 验证 Go 安装
   */
  async validateInstallation(version: string): Promise<boolean> {
    const goPath = this.getGoPath(version)
    const goExe = join(goPath, 'bin', 'go.exe')
    const gofmtExe = join(goPath, 'bin', 'gofmt.exe')
    
    try {
      // 检查核心可执行文件
      if (!existsSync(goExe)) return false
      if (!existsSync(gofmtExe)) return false
      
      // 验证版本
      const { stdout } = await execAsync(`"${goExe}" version`)
      if (!stdout.includes(version)) return false
      
      // 验证环境和基本命令
      await execAsync(`"${goExe}" env GOROOT`)
      
      // 验证 go mod 功能
      await execAsync(`"${goExe}" help mod`)
      
      return true
    } catch {
      return false
    }
  }

  /**
   * 获取 Go 环境信息
   */
  async getGoInfo(version: string): Promise<GoInfo | null> {
    const goPath = this.getGoPath(version)
    const goExe = join(goPath, 'bin', 'go.exe')

    if (!existsSync(goExe)) {
      return null
    }

    try {
      const { stdout: goVersion } = await execAsync(`"${goExe}" version`, { timeout: 5000 })
      const { stdout: goRoot } = await execAsync(`"${goExe}" env GOROOT`, { timeout: 5000 })
      const { stdout: goOs } = await execAsync(`"${goExe}" env GOOS`, { timeout: 5000 })
      const { stdout: goArch } = await execAsync(`"${goExe}" env GOARCH`, { timeout: 5000 })
      
      return {
        version,
        goroot: goRoot.trim(),
        gopath: this.getDefaultGoPath(),
        goversion: goVersion.trim(),
        goos: goOs.trim(),
        goarch: goArch.trim()
      }
    } catch (error) {
      return null
    }
  }

  /**
   * 检测系统已安装的 Go 版本
   */
  async detectSystemGoVersion(): Promise<GoVersion | null> {
    try {
      // 尝试执行系统的 go 命令
      const { stdout: goVersion } = await execAsync('go version', { timeout: 5000 })
      const { stdout: goRoot } = await execAsync('go env GOROOT', { timeout: 5000 })
      const { stdout: goPath } = await execAsync('go env GOPATH', { timeout: 5000 })
      
      // 解析版本号
      const versionMatch = goVersion.match(/go(\d+\.\d+\.\d+)/)
      if (!versionMatch) return null
      
      const version = versionMatch[1]
      const systemGoRoot = goRoot.trim()
      const systemGoPath = goPath.trim()
      
      return {
        version: `go${version}`,
        path: systemGoRoot,
        isActive: false, // 系统版本不算作我们管理的活动版本
        goroot: systemGoRoot,
        gopath: systemGoPath,
        installDate: undefined,
        size: undefined
      }
    } catch (error) {
      // 系统没有安装 Go 或者不在 PATH 中
      return null
    }
  }

  // ==================== 私有方法 ====================

  /**
   * 检查版本是否已安装（重复安装检测）
   */
  private async isVersionInstalled(version: string): Promise<boolean> {
    const extractDir = join(this.getGoBasePath(), `go-${version}`)
    const goExe = join(extractDir, 'bin', 'go.exe')
    const gofmtExe = join(extractDir, 'bin', 'gofmt.exe')

    // 检查目录和关键文件是否存在
    if (!existsSync(extractDir) || !existsSync(goExe) || !existsSync(gofmtExe)) {
      return false
    }

    // 进一步验证安装完整性
    try {
      const { stdout } = await execAsync(`"${goExe}" version`, { timeout: 5000 })
      return stdout.includes(version)
    } catch {
      return false
    }
  }

  /**
   * 解压 Go 归档文件
   * 增强的错误处理
   * Requirements: 8.5
   */
  private async extractGoArchive(zipPath: string, destDir: string, version: string): Promise<void> {
    const extractDir = join(destDir, `go-${version}`)

    try {
      // 先解压到临时位置
      await this.extractZip(zipPath, destDir)

      // Go 的 ZIP 文件解压后会创建一个 'go' 目录，需要重命名
      const extractedGoDir = join(destDir, 'go')
      if (existsSync(extractedGoDir)) {
        // 如果目标目录已存在，先删除
        if (existsSync(extractDir)) {
          rmSync(extractDir, { recursive: true, force: true })
        }
        // 重命名为版本特定的目录
        require('fs').renameSync(extractedGoDir, extractDir)
      } else {
        throw new GoManagerError(
          GoErrorType.INSTALLATION_ERROR,
          '解压后未找到 Go 目录',
          '下载的文件可能损坏或格式不正确。请重新下载安装包',
          true,
          { zipPath, destDir, expectedDir: extractedGoDir }
        )
      }

    } catch (error: any) {
      // 如果是 GoManagerError，直接重新抛出
      if (error instanceof GoManagerError) {
        throw error
      }
      
      let suggestion = '请检查下载文件是否完整，或重新下载安装包'
      
      if (error.code === 'EACCES' || error.code === 'EPERM') {
        suggestion = '权限不足，请以管理员身份运行程序'
      } else if (error.code === 'ENOSPC') {
        suggestion = '磁盘空间不足，请清理磁盘空间后重试'
      } else if (error.message.includes('invalid') || error.message.includes('corrupt')) {
        suggestion = '文件损坏，请重新下载安装包'
      }
      
      throw new GoManagerError(
        GoErrorType.INSTALLATION_ERROR,
        `解压失败: ${error.message}`,
        suggestion,
        true,
        { zipPath, destDir, version, errorCode: error.code, originalError: error.message }
      )
    }
  }

  /**
   * 执行安装后验证和完整性检查
   */
  private async performInstallationValidation(version: string): Promise<{ isValid: boolean; error?: string }> {
    const goPath = this.getGoPath(version)
    const goExe = join(goPath, 'bin', 'go.exe')
    const gofmtExe = join(goPath, 'bin', 'gofmt.exe')

    try {
      // 1. 检查核心可执行文件是否存在
      if (!existsSync(goExe)) {
        return { isValid: false, error: 'go.exe 文件不存在' }
      }
      if (!existsSync(gofmtExe)) {
        return { isValid: false, error: 'gofmt.exe 文件不存在' }
      }

      // 2. 验证 go version 命令
      const { stdout: versionOutput } = await execAsync(`"${goExe}" version`, { timeout: 10000 })
      if (!versionOutput.includes(version)) {
        return { isValid: false, error: `版本验证失败，期望 ${version}，实际 ${versionOutput.trim()}` }
      }

      // 3. 验证 go env 命令
      await execAsync(`"${goExe}" env GOROOT`, { timeout: 10000 })

      // 4. 验证 go mod 功能
      await execAsync(`"${goExe}" help mod`, { timeout: 10000 })

      // 5. 验证 go build 命令可用
      await execAsync(`"${goExe}" help build`, { timeout: 10000 })

      // 6. 检查标准库目录
      const srcDir = join(goPath, 'src')
      if (!existsSync(srcDir)) {
        return { isValid: false, error: '标准库源码目录不存在' }
      }

      return { isValid: true }

    } catch (error: any) {
      return { isValid: false, error: `验证过程出错: ${error.message}` }
    }
  }

  /**
   * 清理失败的安装
   */
  private async cleanupFailedInstallation(installDir: string): Promise<void> {
    try {
      if (existsSync(installDir)) {
        console.log(`清理失败的安装目录: ${installDir}`)
        rmSync(installDir, { recursive: true, force: true })
      }
    } catch (error) {
      console.warn(`清理安装目录失败: ${error}`)
    }
  }

  /**
   * 更新安装配置
   */
  private async updateInstallationConfig(version: string): Promise<void> {
    const goVersions = this.configStore.get('goVersions' as any) || []
    if (!goVersions.includes(version)) {
      goVersions.push(version)
      this.configStore.set('goVersions' as any, goVersions)
    }
  }

  /**
   * 清理临时文件
   */
  private async cleanupTempFiles(zipPath: string): Promise<void> {
    try {
      // 清理下载的 ZIP 文件
      if (existsSync(zipPath)) {
        unlinkSync(zipPath)
        console.log(`已清理临时文件: ${zipPath}`)
      }

      // 清理部分下载文件
      const partialFile = `${zipPath}.partial`
      if (existsSync(partialFile)) {
        unlinkSync(partialFile)
        console.log(`已清理部分下载文件: ${partialFile}`)
      }

    } catch (error) {
      console.warn(`清理临时文件时出错: ${error}`)
      // 不抛出错误，因为这不应该影响安装结果
    }
  }

  /**
   * 增强的文件下载管理器
   * 支持 HTTPS 下载、进度跟踪、SHA256 校验、下载中断和重试
   * Requirements: 8.1, 8.5
   */
  private async downloadFile(url: string, dest: string, name: string, expectedSha256?: string): Promise<void> {
    const options: DownloadOptions = {
      url,
      dest,
      name,
      expectedSha256,
      maxRetries: 3,
      timeout: 600000 // 10 分钟超时
    }

    const result = await this.downloadWithRetry(options)
    if (!result.success) {
      // 如果下载结果包含建议，创建 GoManagerError
      if (result.suggestion) {
        throw new GoManagerError(
          GoErrorType.DOWNLOAD_ERROR,
          result.message,
          result.suggestion,
          result.retryable || false,
          result.details
        )
      } else {
        throw new Error(result.message)
      }
    }
  }

  /**
   * 带重试机制的下载
   * 增强的网络错误处理和用户反馈
   * Requirements: 8.1
   */
  private async downloadWithRetry(options: DownloadOptions): Promise<DownloadResult> {
    const { maxRetries = 3 } = options
    let lastError: Error | null = null

    for (let attempt = 1; attempt <= maxRetries; attempt++) {
      try {
        console.log(`下载尝试 ${attempt}/${maxRetries}: ${options.name}`)
        
        // 在重试前检查网络连接
        if (attempt > 1) {
          console.log(`第 ${attempt} 次尝试前检查网络连接...`)
          const networkCheck = await this.checkNetworkConnection()
          if (!networkCheck.isConnected) {
            throw new GoManagerError(
              GoErrorType.NETWORK_ERROR,
              '网络连接不可用',
              '请检查网络连接后重试。确保可以访问 golang.org',
              true,
              { networkCheck, attempt }
            )
          }
          console.log(`网络连接正常，响应时间: ${networkCheck.responseTime}ms`)
        }
        
        // 检查是否存在部分下载的文件
        const partialFile = `${options.dest}.partial`
        let resumeFrom = 0
        
        if (existsSync(partialFile)) {
          try {
            const stats = statSync(partialFile)
            resumeFrom = stats.size
            console.log(`检测到部分下载文件，从 ${resumeFrom} 字节处恢复下载`)
          } catch (e) {
            // 如果无法读取部分文件，删除它
            try {
              unlinkSync(partialFile)
            } catch {}
            resumeFrom = 0
          }
        }

        await this.performDownload(options, resumeFrom)
        
        // 下载成功后验证 SHA256（如果提供）
        if (options.expectedSha256) {
          console.log('验证文件完整性...')
          const isValid = await this.verifySha256(options.dest, options.expectedSha256)
          if (!isValid) {
            // SHA256 验证失败，删除文件并重试
            try {
              unlinkSync(options.dest)
            } catch {}
            throw new GoManagerError(
              GoErrorType.DOWNLOAD_ERROR,
              'SHA256 校验失败，文件可能损坏',
              '文件下载过程中可能出现错误，正在重新下载。如果问题持续，请检查网络连接',
              true,
              { attempt, expectedSha256: options.expectedSha256 }
            )
          }
          console.log('文件完整性验证通过')
        }

        // 清理部分下载文件
        try {
          unlinkSync(partialFile)
        } catch {}

        return {
          success: true,
          message: '下载完成',
          filePath: options.dest
        }

      } catch (error: any) {
        lastError = error
        console.error(`下载尝试 ${attempt} 失败:`, error.message)
        
        if (attempt < maxRetries) {
          // 等待一段时间后重试（指数退避）
          const delay = Math.min(1000 * Math.pow(2, attempt - 1), 10000)
          console.log(`等待 ${delay}ms 后重试...`)
          await new Promise(resolve => setTimeout(resolve, delay))
        }
      }
    }

    // 所有重试都失败了
    const errorMessage = lastError instanceof GoManagerError 
      ? lastError.message 
      : `下载失败（已重试 ${maxRetries} 次）: ${lastError?.message || '未知错误'}`
    
    const suggestion = lastError instanceof GoManagerError 
      ? lastError.suggestion
      : '请检查网络连接，确保可以访问 golang.org。如果问题持续，请尝试使用VPN或更换网络环境'

    return {
      success: false,
      message: errorMessage,
      suggestion,
      retryable: true,
      details: { attempts: maxRetries, lastError: lastError?.message }
    }
  }

  /**
   * 执行实际的下载操作
   * 增强的错误处理和网络状态检测
   * Requirements: 8.1
   */
  private async performDownload(options: DownloadOptions, resumeFrom: number = 0): Promise<void> {
    return new Promise((resolve, reject) => {
      const protocol = options.url.startsWith('https') ? https : http
      const partialFile = `${options.dest}.partial`
      const isResume = resumeFrom > 0

      const requestOptions: any = {
        headers: {
          'User-Agent': 'PHPer-Dev-Manager/1.0'
        },
        timeout: options.timeout || 600000
      }

      // 如果是断点续传，添加 Range 头
      if (isResume) {
        requestOptions.headers['Range'] = `bytes=${resumeFrom}-`
      }

      const request = protocol.get(options.url, requestOptions, (response) => {
        // 处理重定向
        if (response.statusCode === 301 || response.statusCode === 302) {
          const redirectUrl = response.headers.location
          if (redirectUrl) {
            const redirectOptions = { ...options, url: redirectUrl }
            this.performDownload(redirectOptions, resumeFrom).then(resolve).catch(reject)
            return
          }
        }

        // 检查响应状态码
        const expectedStatus = isResume ? 206 : 200 // 206 for partial content
        if (response.statusCode !== expectedStatus && response.statusCode !== 200) {
          const errorMsg = `下载失败: HTTP ${response.statusCode}`
          let suggestion = '请检查网络连接和下载链接'
          
          if (response.statusCode === 404) {
            suggestion = '下载链接不存在，请尝试其他版本或联系支持'
          } else if (response.statusCode === 403) {
            suggestion = '访问被拒绝，可能需要VPN或代理服务器'
          } else if (response.statusCode === 500 || response.statusCode === 502 || response.statusCode === 503) {
            suggestion = '服务器暂时不可用，请稍后重试'
          }
          
          reject(new GoManagerError(
            GoErrorType.NETWORK_ERROR,
            errorMsg,
            suggestion,
            true,
            { statusCode: response.statusCode, url: options.url }
          ))
          return
        }

        const totalSize = isResume 
          ? resumeFrom + parseInt(response.headers['content-length'] || '0', 10)
          : parseInt(response.headers['content-length'] || '0', 10)
        let downloadedSize = resumeFrom

        // 创建写入流（追加模式如果是断点续传）
        const file = createWriteStream(isResume ? partialFile : options.dest, 
          isResume ? { flags: 'a' } : undefined)

        let lastProgressTime = 0
        let lastDownloadedSize = downloadedSize
        let downloadSpeed = 0

        response.on('data', (chunk) => {
          downloadedSize += chunk.length
          const now = Date.now()
          
          // 每500ms更新一次进度和速度
          if (now - lastProgressTime > 500) {
            const timeDiff = (now - lastProgressTime) / 1000
            const sizeDiff = downloadedSize - lastDownloadedSize
            downloadSpeed = sizeDiff / timeDiff // bytes per second
            
            const progress = totalSize > 0 ? Math.round((downloadedSize / totalSize) * 100) : 0
            sendDownloadProgress('go', progress, downloadedSize, totalSize)
            
            lastProgressTime = now
            lastDownloadedSize = downloadedSize
          }
        })

        response.pipe(file)

        file.on('finish', () => {
          file.close()
          
          // 如果是部分下载文件，重命名为最终文件
          if (isResume) {
            try {
              if (existsSync(options.dest)) {
                unlinkSync(options.dest)
              }
              require('fs').renameSync(partialFile, options.dest)
            } catch (e) {
              reject(new GoManagerError(
                GoErrorType.FILE_SYSTEM_ERROR,
                `重命名文件失败: ${e}`,
                '可能是权限问题或磁盘空间不足，请检查目标目录权限',
                false,
                { renameError: e }
              ))
              return
            }
          }
          
          sendDownloadProgress('go', 100, totalSize, totalSize)
          resolve()
        })

        file.on('error', (err) => {
          try {
            if (!isResume) {
              unlinkSync(options.dest)
            }
          } catch {}
          reject(new GoManagerError(
            GoErrorType.FILE_SYSTEM_ERROR,
            `文件写入失败: ${err.message}`,
            '可能是磁盘空间不足或权限问题，请检查目标目录权限和可用空间',
            false,
            { fileError: err.message }
          ))
        })
      })

      request.on('error', (err) => {
        reject(new GoManagerError(
          GoErrorType.NETWORK_ERROR,
          `网络错误: ${err.message}`,
          '请检查网络连接，确保可以访问互联网。如果使用代理，请检查代理设置',
          true,
          { networkError: err.message }
        ))
      })

      request.on('timeout', () => {
        request.destroy()
        reject(new GoManagerError(
          GoErrorType.NETWORK_ERROR,
          '下载超时',
          '网络连接较慢或不稳定，请检查网络环境后重试',
          true,
          { timeout: options.timeout }
        ))
      })
    })
  }

  /**
   * 验证文件的 SHA256 校验和
   */
  private async verifySha256(filePath: string, expectedSha256: string): Promise<boolean> {
    return new Promise((resolve) => {
      try {
        const hash = createHash('sha256')
        const stream = createReadStream(filePath)

        stream.on('data', (data) => {
          hash.update(data)
        })

        stream.on('end', () => {
          const actualSha256 = hash.digest('hex').toLowerCase()
          const expected = expectedSha256.toLowerCase()
          resolve(actualSha256 === expected)
        })

        stream.on('error', () => {
          resolve(false)
        })
      } catch {
        resolve(false)
      }
    })
  }

  private async extractZip(zipPath: string, destDir: string): Promise<void> {
    return new Promise((resolve, reject) => {
      const readStream = require('fs').createReadStream(zipPath)
      readStream
        .pipe(unzipper.Extract({ path: destDir }))
        .on('close', resolve)
        .on('error', reject)
    })
  }

  /**
   * 更新环境变量以支持指定的 Go 版本
   * 设置 GOROOT、GOPATH 和 PATH，清理旧版本的路径配置
   * 增强的错误处理和权限检查
   * Requirements: 3.1, 6.1, 6.2, 6.3, 6.4, 8.3, 8.5
   */
  private async updateEnvironmentVariables(goVersion: string): Promise<void> {
    const goRoot = this.getGoPath(goVersion)
    const goBin = join(goRoot, 'bin')
    const goPath = this.getDefaultGoPath()
    
    console.log(`更新环境变量为 Go ${goVersion}`)
    console.log(`GOROOT: ${goRoot}`)
    console.log(`GOPATH: ${goPath}`)
    console.log(`Go Binary Path: ${goBin}`)
    
    try {
      // 确保 GOPATH 工作空间目录存在
      await this.ensureGoPathStructure(goPath)
      
      // 使用 PowerShell 脚本更新用户环境变量
      const psScript = this.generateEnvironmentUpdateScript(goRoot, goPath, goBin)
      
      await this.executePowerShellScript(psScript)
      console.log(`环境变量更新成功: Go ${goVersion}`)
      
    } catch (error: any) {
      console.error(`环境变量更新失败: ${error.message}`)
      
      // 根据错误类型提供具体建议
      let suggestion = '请以管理员身份运行程序，或手动设置环境变量'
      
      if (error.message.includes('ExecutionPolicy')) {
        suggestion = '请以管理员身份运行 PowerShell 并执行: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser'
      } else if (error.message.includes('Access') || error.message.includes('权限')) {
        suggestion = '权限不足，请以管理员身份运行程序，或在系统设置中手动配置环境变量'
      } else if (error.message.includes('timeout')) {
        suggestion = '操作超时，请重试。如果问题持续，请手动配置环境变量'
      }
      
      throw new GoManagerError(
        GoErrorType.ENVIRONMENT_ERROR,
        `环境变量更新失败: ${error.message}`,
        suggestion,
        true,
        { 
          goVersion, 
          goRoot, 
          goPath, 
          goBin,
          originalError: error.message 
        }
      )
    }
  }

  /**
   * 确保 GOPATH 工作空间目录结构存在
   * 创建标准的 Go 工作空间结构：src, pkg, bin
   * 增强的错误处理
   * Requirements: 8.2, 8.3
   */
  private async ensureGoPathStructure(goPath: string): Promise<void> {
    try {
      if (!existsSync(goPath)) {
        mkdirSync(goPath, { recursive: true })
        console.log(`创建 GOPATH 目录: ${goPath}`)
      }
      
      // 创建标准的 Go 工作空间结构
      const subdirs = ['src', 'pkg', 'bin']
      for (const subdir of subdirs) {
        const dirPath = join(goPath, subdir)
        if (!existsSync(dirPath)) {
          mkdirSync(dirPath, { recursive: true })
          console.log(`创建 GOPATH 子目录: ${dirPath}`)
        }
      }
    } catch (error: any) {
      let suggestion = '请检查目标目录权限，或选择其他位置作为 GOPATH'
      
      if (error.code === 'EACCES' || error.code === 'EPERM') {
        suggestion = '权限不足，请以管理员身份运行程序，或选择用户目录下的位置'
      } else if (error.code === 'ENOSPC') {
        suggestion = '磁盘空间不足，请清理磁盘空间或选择其他磁盘'
      } else if (error.code === 'ENOTDIR') {
        suggestion = '路径中存在同名文件，请删除该文件或选择其他路径'
      }
      
      throw new GoManagerError(
        GoErrorType.FILE_SYSTEM_ERROR,
        `创建 GOPATH 结构失败: ${error.message}`,
        suggestion,
        false,
        { goPath, errorCode: error.code, originalError: error.message }
      )
    }
  }

  /**
   * 生成环境变量更新的 PowerShell 脚本
   * 包含 GOROOT、GOPATH 设置和 PATH 清理更新
   */
  private generateEnvironmentUpdateScript(goRoot: string, goPath: string, goBin: string): string {
    // 转义路径中的反斜杠
    const escapedGoRoot = goRoot.replace(/\\/g, '\\\\')
    const escapedGoPath = goPath.replace(/\\/g, '\\\\')
    const escapedGoBin = goBin.replace(/\\/g, '\\\\')
    
    return `
      # Go 环境变量更新脚本
      Write-Host "开始更新 Go 环境变量..."
      
      try {
        # 设置 GOROOT
        Write-Host "设置 GOROOT: ${escapedGoRoot}"
        [Environment]::SetEnvironmentVariable('GOROOT', '${escapedGoRoot}', 'User')
        
        # 设置 GOPATH
        Write-Host "设置 GOPATH: ${escapedGoPath}"
        [Environment]::SetEnvironmentVariable('GOPATH', '${escapedGoPath}', 'User')
        
        # 更新 PATH
        Write-Host "更新 PATH 环境变量..."
        $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
        if (-not $userPath) { $userPath = '' }
        
        $pathArray = $userPath -split ';' | Where-Object { $_ -ne '' -and $_ -ne $null }
        
        # 移除所有旧的 Go 路径（更全面的清理）
        $filteredPaths = $pathArray | Where-Object { 
          -not ($_ -like '*\\go\\go-*\\bin' -or 
                $_ -like '*\\go-*\\bin' -or 
                $_ -like '*\\golang\\*\\bin' -or
                $_ -like '*\\Go\\*\\bin')
        }
        
        # 添加新的 Go 路径到开头
        $newPathArray = @('${escapedGoBin}') + $filteredPaths
        $finalPath = ($newPathArray | Where-Object { $_ -ne '' -and $_ -ne $null } | Select-Object -Unique) -join ';'
        
        Write-Host "新的 PATH: $finalPath"
        [Environment]::SetEnvironmentVariable('PATH', $finalPath, 'User')
        
        Write-Host "环境变量更新完成"
        
      } catch {
        Write-Error "环境变量更新失败: $_"
        throw $_
      }
    `
  }

  /**
   * 从环境变量中移除指定 Go 版本的路径
   * 清理 GOROOT、GOPATH 和 PATH 中的相关配置
   * 增强的错误处理
   * Requirements: 8.3, 8.5
   */
  private async removeFromPath(goPath: string): Promise<void> {
    const goBin = join(goPath, 'bin')
    
    console.log(`从环境变量中移除 Go 路径: ${goBin}`)
    
    const psScript = this.generateEnvironmentCleanupScript(goBin)
    
    try {
      await this.executePowerShellScript(psScript)
      console.log(`环境变量清理成功`)
    } catch (error: any) {
      console.error(`环境变量清理失败: ${error.message}`)
      
      // 如果是 GoManagerError，直接重新抛出
      if (error instanceof GoManagerError) {
        throw error
      }
      
      throw new GoManagerError(
        GoErrorType.ENVIRONMENT_ERROR,
        `环境变量清理失败: ${error.message}`,
        '请以管理员身份运行程序，或在系统设置中手动清理环境变量',
        true,
        { goBin, originalError: error.message }
      )
    }
  }

  /**
   * 生成环境变量清理的 PowerShell 脚本
   * 移除指定的 Go 路径并清理 GOROOT、GOPATH
   */
  private generateEnvironmentCleanupScript(goBin: string): string {
    const escapedGoBin = goBin.replace(/\\/g, '\\\\')
    
    return `
      # Go 环境变量清理脚本
      Write-Host "开始清理 Go 环境变量..."
      
      try {
        # 获取当前用户 PATH
        $userPath = [Environment]::GetEnvironmentVariable('PATH', 'User')
        if ($userPath) {
          $pathArray = $userPath -split ';' | Where-Object { $_ -ne '' -and $_ -ne $null }
          
          # 移除指定的 Go 路径
          $filteredPaths = $pathArray | Where-Object { 
            $_ -ne '${escapedGoBin}'
          }
          
          $finalPath = ($filteredPaths | Where-Object { $_ -ne '' -and $_ -ne $null } | Select-Object -Unique) -join ';'
          [Environment]::SetEnvironmentVariable('PATH', $finalPath, 'User')
          Write-Host "已从 PATH 中移除: ${escapedGoBin}"
        }
        
        # 清除 GOROOT 和 GOPATH（如果没有其他活动版本）
        [Environment]::SetEnvironmentVariable('GOROOT', $null, 'User')
        [Environment]::SetEnvironmentVariable('GOPATH', $null, 'User')
        Write-Host "已清除 GOROOT 和 GOPATH"
        
        Write-Host "环境变量清理完成"
        
      } catch {
        Write-Error "环境变量清理失败: $_"
        throw $_
      }
    `
  }

  /**
   * 执行 PowerShell 脚本
   * 创建临时脚本文件并执行，完成后清理
   * 增强的错误处理和权限检查
   * Requirements: 8.3, 8.5
   */
  private async executePowerShellScript(script: string): Promise<void> {
    const tempPs1 = join(this.configStore.getTempPath(), `go_env_${Date.now()}.ps1`)
    
    try {
      // 确保临时目录存在
      const tempDir = this.configStore.getTempPath()
      if (!existsSync(tempDir)) {
        mkdirSync(tempDir, { recursive: true })
      }
      
      // 写入脚本文件
      writeFileSync(tempPs1, script, 'utf-8')
      
      // 执行 PowerShell 脚本
      const command = `powershell -ExecutionPolicy Bypass -File "${tempPs1}"`
      const { stdout, stderr } = await execAsync(command, { timeout: 30000 })
      
      // 检查 PowerShell 脚本的输出
      if (stderr && stderr.trim()) {
        console.warn('PowerShell 脚本警告:', stderr)
        
        // 某些警告不应该被视为错误
        const ignorableWarnings = [
          'WARNING:',
          'Get-WmiObject',
          'deprecated'
        ]
        
        const isIgnorable = ignorableWarnings.some(warning => 
          stderr.toLowerCase().includes(warning.toLowerCase())
        )
        
        if (!isIgnorable && stderr.includes('Error')) {
          throw new Error(stderr)
        }
      }
      
      if (stdout && stdout.trim()) {
        console.log('PowerShell 脚本输出:', stdout)
      }
      
    } catch (error: any) {
      console.error('PowerShell 脚本执行失败:', error)
      
      let suggestion = '请以管理员身份运行程序，或手动配置环境变量'
      let errorType = GoErrorType.ENVIRONMENT_ERROR
      
      const errorMessage = error.message.toLowerCase()
      
      if (errorMessage.includes('executionpolicy')) {
        suggestion = '执行策略限制，请以管理员身份运行 PowerShell 并执行: Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser'
        errorType = GoErrorType.PERMISSION_ERROR
      } else if (errorMessage.includes('access') || errorMessage.includes('denied') || errorMessage.includes('权限')) {
        suggestion = '权限不足，请以管理员身份运行程序。您也可以在系统设置中手动配置环境变量'
        errorType = GoErrorType.PERMISSION_ERROR
      } else if (errorMessage.includes('timeout')) {
        suggestion = '操作超时，可能是系统响应较慢。请重试，或手动配置环境变量'
      } else if (errorMessage.includes('not found') || errorMessage.includes('找不到')) {
        suggestion = 'PowerShell 不可用，请确保 Windows PowerShell 已正确安装'
      }
      
      throw new GoManagerError(
        errorType,
        `PowerShell 脚本执行失败: ${error.message}`,
        suggestion,
        true,
        { 
          scriptPath: tempPs1,
          command: 'powershell -ExecutionPolicy Bypass',
          originalError: error.message 
        }
      )
    } finally {
      // 清理临时脚本文件
      try {
        if (existsSync(tempPs1)) {
          unlinkSync(tempPs1)
        }
      } catch (e) {
        console.warn('清理临时脚本文件失败:', e)
      }
    }
  }

  private getFallbackVersions(): AvailableGoVersion[] {
    return [
      { version: 'go1.22.0', stable: true, downloadUrl: 'https://golang.org/dl/go1.22.0.windows-amd64.zip', size: 0, sha256: '' },
      { version: 'go1.21.6', stable: true, downloadUrl: 'https://golang.org/dl/go1.21.6.windows-amd64.zip', size: 0, sha256: '' },
      { version: 'go1.21.5', stable: true, downloadUrl: 'https://golang.org/dl/go1.21.5.windows-amd64.zip', size: 0, sha256: '' },
      { version: 'go1.20.13', stable: true, downloadUrl: 'https://golang.org/dl/go1.20.13.windows-amd64.zip', size: 0, sha256: '' },
      { version: 'go1.20.12', stable: true, downloadUrl: 'https://golang.org/dl/go1.20.12.windows-amd64.zip', size: 0, sha256: '' },
      { version: 'go1.19.13', stable: true, downloadUrl: 'https://golang.org/dl/go1.19.13.windows-amd64.zip', size: 0, sha256: '' }
    ]
  }
}